1 // Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROMIUMOS_WIDE_PROFILING_ADDRESS_MAPPER_H_ 6 #define CHROMIUMOS_WIDE_PROFILING_ADDRESS_MAPPER_H_ 7 8 #include <stdint.h> 9 10 #include <list> 11 12 namespace quipper { 13 14 class AddressMapper { 15 public: 16 AddressMapper() {} 17 18 // Copy constructor: copies mappings from |source| to this AddressMapper. This 19 // is useful for copying mappings from parent to child process upon fork(). It 20 // is also useful to copy kernel mappings to any process that is created. 21 AddressMapper(const AddressMapper& source); 22 23 // Maps a new address range to quipper space. 24 // |remove_existing_mappings| indicates whether to remove old mappings that 25 // collide with the new range in real address space, indicating it has been 26 // unmapped. 27 // Returns true if mapping was successful. 28 bool Map(const uint64_t real_addr, 29 const uint64_t length, 30 bool remove_existing_mappings); 31 32 // Like Map(real_addr, length, remove_existing_mappings). |id| is an 33 // identifier value to be stored along with the mapping. AddressMapper does 34 // not care whether it is unique compared to all other IDs passed in. That is 35 // up to the caller to keep track of. 36 // |offset_base| represents the offset within the original region at which the 37 // mapping begins. The original region can be much larger than the mapped 38 // region. 39 // e.g. Given a mapped region with base=0x4000 and size=0x2000 mapped with 40 // offset_base=0x10000, then the address 0x5000 maps to an offset of 0x11000 41 // (0x5000 - 0x4000 + 0x10000). 42 bool MapWithID(const uint64_t real_addr, 43 const uint64_t length, 44 const uint64_t id, 45 const uint64_t offset_base, 46 bool remove_existing_mappings); 47 48 // Looks up |real_addr| and returns the mapped address. 49 bool GetMappedAddress(const uint64_t real_addr, uint64_t* mapped_addr) const; 50 51 // Looks up |real_addr| and returns the mapping's ID and offset from the 52 // start of the mapped space. 53 bool GetMappedIDAndOffset(const uint64_t real_addr, 54 uint64_t* id, 55 uint64_t* offset) const; 56 57 // Returns true if there are no mappings. 58 bool IsEmpty() const { 59 return mappings_.empty(); 60 } 61 62 // Returns the number of address ranges that are currently mapped. 63 unsigned int GetNumMappedRanges() const { 64 return mappings_.size(); 65 } 66 67 // Returns the maximum length of quipper space containing mapped areas. 68 // There may be gaps in between blocks. 69 // If the result is 2^64 (all of quipper space), this returns 0. Call 70 // IsEmpty() to distinguish this from actual emptiness. 71 uint64_t GetMaxMappedLength() const; 72 73 // Dumps the state of the address mapper to logs. Useful for debugging. 74 void DumpToLog() const; 75 76 private: 77 struct MappedRange { 78 uint64_t real_addr; 79 uint64_t mapped_addr; 80 uint64_t size; 81 82 uint64_t id; 83 uint64_t offset_base; 84 85 // Length of unmapped space after this range. 86 uint64_t unmapped_space_after; 87 88 // Determines if this range intersects another range in real space. 89 inline bool Intersects(const MappedRange& range) const { 90 return (real_addr <= range.real_addr + range.size - 1) && 91 (real_addr + size - 1 >= range.real_addr); 92 } 93 94 // Determines if this range fully covers another range in real space. 95 inline bool Covers(const MappedRange& range) const { 96 return (real_addr <= range.real_addr) && 97 (real_addr + size - 1 >= range.real_addr + range.size - 1); 98 } 99 100 // Determines if this range fully contains another range in real space. 101 // This is different from Covers() in that the boundaries cannot overlap. 102 inline bool Contains(const MappedRange& range) const { 103 return (real_addr < range.real_addr) && 104 (real_addr + size - 1 > range.real_addr + range.size - 1); 105 } 106 107 // Determines if this range contains the given address |addr|. 108 inline bool ContainsAddress(uint64_t addr) const { 109 return (addr >= real_addr && addr <= real_addr + size - 1); 110 } 111 }; 112 113 // TODO(sque): implement with set or map to improve searching. 114 typedef std::list<MappedRange> MappingList; 115 116 // Removes an existing address mapping. 117 // Returns true if successful, false if no mapped address range was found. 118 bool Unmap(const MappedRange& range); 119 120 // Container for all the existing mappings. 121 MappingList mappings_; 122 123 bool CheckMappings() const; 124 }; 125 126 } // namespace quipper 127 128 #endif // CHROMIUMOS_WIDE_PROFILING_ADDRESS_MAPPER_H_ 129