dwarfinterpret/include/dwarfinterpret/MemoryMap.hpp

97 lines
2.9 KiB
C++

#pragma once
/** MemoryMap: load, parse and make available the process' memory map
*
* This class allows the easy loading, parsing and reading of the process'
* memory map, that is, the correspondance between the various compile units
* and shared libraries' sections, and their mapping location in memory.
*
* This class is absolutely not portable and reads /proc/[pid]/maps. For more
* information, please read `man 5 proc`.
*/
#include <exception>
#include <stdexcept>
#include <map>
#include <vector>
#include <string>
#include <cstdint>
class MemoryMap {
public:
/// Thrown when the constructor fails to read the map's data
class ReadMapFailed: public std::exception {};
struct MemoryRegion {
/** A contiguous memory region. */
MemoryRegion() = default;
MemoryRegion(uintptr_t begin, uintptr_t end)
: begin(begin), end(end) {}
uintptr_t begin; ///< First address (incl.) in the region
uintptr_t end; ///< Past-the-end address for the region
bool operator==(const MemoryRegion& oth) const {
return begin == oth.begin && end == oth.end;
}
bool operator<(const MemoryRegion& oth) const {
if(begin < oth.begin)
return true;
return (begin == oth.begin && end < oth.end);
}
/// Checks whether `addr` is in this region
bool contains(uintptr_t addr) const {
return begin <= addr && addr < end;
}
};
struct MapEntry {
std::string pathname;
MemoryRegion mem_region;
uintptr_t offset;
/// Debug feature: dumps the MapEntry on the given stream
void dump(std::ostream& os) const;
};
/// An iterator to the map entries. The underlying type might change.
typedef std::vector<MapEntry>::const_iterator iter_t;
public:
/** Loads and constructs the map.
*
* \throws ReadMapFailed upon failure */
MemoryMap();
/** Get the MapEntry for a given id
*
* \throws std::out_of_range if there is no such entry */
const MapEntry& get_entry(size_t id) const;
/// Synonymous for get_entry
const MapEntry& operator[](size_t id) const;
/** Get the MapEntry id of the region containing addr
*
* \throws std::out_of_range if no such region is mapped */
size_t id_of_address(uintptr_t addr) const;
/// Get a constant iterator to the first map entry
iter_t begin() const;
/// Get a constant iterator to a past-the-end iterator
iter_t end() const;
/// Get the number of entries in the map
size_t size() const;
private:
std::vector<MapEntry> map_entries;
/// Maps regions back to their id
std::map<MemoryRegion, size_t> rev_addr_map;
};