#include <MemoryMap.h>
Each map element describes a mapping from contiguous virtual addresses to contiguous file/memory bytes. A map element can point to a buffer supplied by the caller or a buffer allocated and managed by the MemoryMap itself. MemoryMap-managed buffers are used for anonymous maps where the backing store is initialized to all zero bytes rather than to values supplied by the caller.
If the user supplies a const pointer base address to the MapElement constructor then any call to MemoryMap::write() will fail when attempting to write to that map element. The is_read_only() method returns true if the user supplied a const base address to the constructor.
The map element also tracks what permissions would be used if the memory were actually mapped for real. These permissions are bit flags MM_PROT_EXEC, MM_PROT_READ, MM_PROT_WRITE, and MM_PROT_NONE from the Protection enum. The presence or absence of the MM_PROT_WRITE bit here has no relation to the is_read_only() value -- it is legal for ROSE to write new values to a memory location that is mapped without MM_PROT_WRITE, but not to a memory location where is_read_only() is true.
Public Member Functions | |
| MapElement () | |
| MapElement (const MapElement &other) | |
| MapElement & | operator= (const MapElement &other) |
| ~MapElement () | |
| MapElement (rose_addr_t va, size_t size, void *base, rose_addr_t offset, unsigned perms=MM_PROT_READ) | |
| Creates a mapping relative to a memory buffer. | |
| MapElement (rose_addr_t va, size_t size, const void *base, rose_addr_t offset, unsigned perms=MM_PROT_READ) | |
| Create a mapping relative to a read-only memory buffer. | |
| MapElement (rose_addr_t va, size_t size, unsigned perms=MM_PROT_READ) | |
| Creates an anonymous mapping where all addresses of the mapping initially contain zero bytes. | |
| rose_addr_t | get_va () const |
| Returns the starting virtual address for this map element. | |
| size_t | get_size () const |
| Returns the size in bytes represented by the entire map element. | |
| bool | is_anonymous () const |
| Returns true if the map element is anonymous. | |
| bool | is_read_only () const |
| Returns true if the map points to read-only memory. | |
| unsigned | get_mapperms () const |
| Returns mapping permissions. | |
| void | set_mapperms (unsigned new_perms) |
| Modifies the mapping permissions. | |
| void * | get_base () const |
| Returns the buffer to which the offset applies. | |
| rose_addr_t | get_offset () const |
| Returns the starting offset for this map element. | |
| rose_addr_t | get_va_offset (rose_addr_t va) const |
| Returns the starting offset of the specified virtual address or throws a MemoryMap::NotMapped exception if the virtual address is not represented by this map element. | |
| bool | consistent (const MapElement &other) const |
Returns true if this element is consistent with the other element. | |
| bool | merge (const MapElement &other) |
Attempts to merge the other element with this one. | |
| MapElement & | set_name (const std::string &name) |
| Give the map entry a name. | |
| const std::string & | get_name () const |
| Return the name assigned to this map element. | |
Private Member Functions | |
| void | init (const MapElement &other) |
| Initialize this element using data from another element. | |
| void | nullify () |
| Make this a null mapping, releasing any anonymous memory that might be referenced. | |
| void | merge_anonymous (const MapElement &other, size_t oldsize) |
Helper function for merge() when this and other element are both anonymous. | |
| void | merge_names (const MapElement &other) |
| Adjust the debugging name when merging two map elements. | |
| void | set_va (rose_addr_t new_va) |
| Changes the virtual address of a mapped region. | |
| void | set_offset (rose_addr_t new_offset) |
| Changes the starting offset with respect to the 'base'. | |
| void | set_size (size_t sz) |
| Changes the size of a mapped region. | |
Private Attributes | |
| rose_addr_t | va |
| Virtual address for start of region. | |
| size_t | size |
| Number of bytes in region. | |
| void * | base |
| The buffer to which 'offset' applies. | |
| rose_addr_t | offset |
| Offset with respect to 'base'. | |
| bool | read_only |
| If set then write() is not allowed. | |
| unsigned | mapperms |
| Mapping permissions (MM_PROT_{READ,WRITE,EXEC} from Protection enum). | |
| std::string | name |
| Name used for debugging purposes. | |
| size_t * | anonymous |
| If non-null then the element describes an anonymous mapping, one that is initially all zero. | |
Friends | |
| class | MemoryMap |
| MemoryMap::MapElement::MapElement | ( | ) | [inline] |
| MemoryMap::MapElement::MapElement | ( | const MapElement & | other | ) | [inline] |
| MemoryMap::MapElement::~MapElement | ( | ) | [inline] |
| MemoryMap::MapElement::MapElement | ( | rose_addr_t | va, | |
| size_t | size, | |||
| void * | base, | |||
| rose_addr_t | offset, | |||
| unsigned | perms = MM_PROT_READ | |||
| ) | [inline] |
Creates a mapping relative to a memory buffer.
The MemoryMap will coalesce adjacent elements having the same base when possible, but never elements having different bases.
| MemoryMap::MapElement::MapElement | ( | rose_addr_t | va, | |
| size_t | size, | |||
| const void * | base, | |||
| rose_addr_t | offset, | |||
| unsigned | perms = MM_PROT_READ | |||
| ) | [inline] |
Create a mapping relative to a read-only memory buffer.
The MemoryMap will coalesce adjacent elements having the same base when possible, but never elements having different bases.
| MemoryMap::MapElement::MapElement | ( | rose_addr_t | va, | |
| size_t | size, | |||
| unsigned | perms = MM_PROT_READ | |||
| ) | [inline] |
Creates an anonymous mapping where all addresses of the mapping initially contain zero bytes.
Note that memory is not allocated (and the base address is not assigned) until a write attempt is made. The implementation is free to coalesce compatible adjacent anonymous regions as it sees fit, reallocating memory as necessary.
| MapElement& MemoryMap::MapElement::operator= | ( | const MapElement & | other | ) | [inline] |
| rose_addr_t MemoryMap::MapElement::get_va | ( | ) | const [inline] |
Returns the starting virtual address for this map element.
| size_t MemoryMap::MapElement::get_size | ( | ) | const [inline] |
Returns the size in bytes represented by the entire map element.
| bool MemoryMap::MapElement::is_anonymous | ( | ) | const [inline] |
Returns true if the map element is anonymous.
| bool MemoryMap::MapElement::is_read_only | ( | ) | const [inline] |
Returns true if the map points to read-only memory.
This attribute is orthogonal to the mapping permissions returned by get_mapperms(). For instance, the underlying storage in ROSE can be a const buffer (is_read_only() returns true) even though the map element indicates that the storage would be mapped by the loader with write permission.
| unsigned MemoryMap::MapElement::get_mapperms | ( | ) | const [inline] |
Returns mapping permissions.
The mapping permissions are orthogonal to is_read_only(). For instance, an element can indicate that memory would be mapped read-only by the loader even when the underlying storage in ROSE is writable.
| void MemoryMap::MapElement::set_mapperms | ( | unsigned | new_perms | ) | [inline] |
Modifies the mapping permissions.
The mapping permissions are orthogonal to is_read_only(). For instance, an element can indicate that memory would be mapped read-only by the loader even when the underlying storage in ROSE is writable.
| void* MemoryMap::MapElement::get_base | ( | ) | const [inline] |
Returns the buffer to which the offset applies.
The base for anonymous elements is probably not of interest to a caller since the implementation is free to allocate anonymous memory as it sees fit (in fact, it might not even use a large contiguous buffer).
| rose_addr_t MemoryMap::MapElement::get_offset | ( | ) | const [inline] |
Returns the starting offset for this map element.
The offset is measured with respect to the value returned by get_base(). The offset is probably not of interest when the element describes an anonymous mapping.
| rose_addr_t MemoryMap::MapElement::get_va_offset | ( | rose_addr_t | va | ) | const |
Returns the starting offset of the specified virtual address or throws a MemoryMap::NotMapped exception if the virtual address is not represented by this map element.
| bool MemoryMap::MapElement::consistent | ( | const MapElement & | other | ) | const |
Returns true if this element is consistent with the other element.
Consistent map elements can be merged when they are adjacent or overlapping with one another. Elements are not consistent if they have different base addresses or different permissions. If the base addresses are the same, elements are not consistent if the difference in starting virtual addresses is not equal to the difference in offsets.
| bool MemoryMap::MapElement::merge | ( | const MapElement & | other | ) |
Attempts to merge the other element with this one.
Returns true if the elements can be merged; false if they cannot. If the two elements overlap but are inconsistent then a MemoryMap::Inconsistent exception is thrown.
| MemoryMap::MapElement & MemoryMap::MapElement::set_name | ( | const std::string & | name | ) |
Give the map entry a name.
This can be used for debugging, but don't rely too heavily on it because a MemoryMap may sometimes combine two adjacent elements that have different names. Returns a reference to this object so that it is convenient to use this method in the argument expression for MemoryMap::insert().
| const std::string& MemoryMap::MapElement::get_name | ( | ) | const [inline] |
Return the name assigned to this map element.
Names are used primarily for debugging purposes.
| void MemoryMap::MapElement::init | ( | const MapElement & | other | ) | [inline, private] |
Initialize this element using data from another element.
| void MemoryMap::MapElement::nullify | ( | ) | [inline, private] |
Make this a null mapping, releasing any anonymous memory that might be referenced.
| void MemoryMap::MapElement::merge_anonymous | ( | const MapElement & | other, | |
| size_t | oldsize | |||
| ) | [private] |
Helper function for merge() when this and other element are both anonymous.
This method will allocate storage for this anonymous element if necessary and initialize it with the contents of the other element. The oldsize argument is the size of this element before we merged it with the other.
| void MemoryMap::MapElement::merge_names | ( | const MapElement & | other | ) | [private] |
Adjust the debugging name when merging two map elements.
| void MemoryMap::MapElement::set_va | ( | rose_addr_t | new_va | ) | [inline, private] |
Changes the virtual address of a mapped region.
This is private because changing the starting address can cause the mapping to become inconsistent. In general, it is safe to split a map element into smaller pieces and this method can be used to adjust the starting addresses of those pieces. The set_offset() method should also be called when adjusting the starting address.
| void MemoryMap::MapElement::set_offset | ( | rose_addr_t | new_offset | ) | [inline, private] |
Changes the starting offset with respect to the 'base'.
The starting offset sometimes needs to be adjusted when splitting a map element into multiple parts.
| void MemoryMap::MapElement::set_size | ( | size_t | sz | ) | [inline, private] |
Changes the size of a mapped region.
This is private because changing the size can cause the mapping to become inconsistent. In general, it is safe to split a map element into smaller pieces and this method can be used to adjust the size of those pieces.
friend class MemoryMap [friend] |
rose_addr_t MemoryMap::MapElement::va [private] |
Virtual address for start of region.
size_t MemoryMap::MapElement::size [private] |
Number of bytes in region.
void* MemoryMap::MapElement::base [mutable, private] |
The buffer to which 'offset' applies.
rose_addr_t MemoryMap::MapElement::offset [private] |
Offset with respect to 'base'.
bool MemoryMap::MapElement::read_only [private] |
If set then write() is not allowed.
unsigned MemoryMap::MapElement::mapperms [private] |
Mapping permissions (MM_PROT_{READ,WRITE,EXEC} from Protection enum).
std::string MemoryMap::MapElement::name [private] |
Name used for debugging purposes.
size_t* MemoryMap::MapElement::anonymous [private] |
If non-null then the element describes an anonymous mapping, one that is initially all zero.
The 'base' data member in this case will initially be NULL and will be allocated when a MemoryMap::write() modifies the anonymous region. When 'base' is allocated, then anonymous will point to a one and will be incremented each time the element is copied and decremented when the element is overwritten or destroyed. Each allocated 'base' will have it's own allocated reference counter.
1.4.7