#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 #include #include #include #include #include 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::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 map_entries; /// Maps regions back to their id std::map rev_addr_map; };