97 lines
2.9 KiB
C++
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;
|
|
};
|