00001 #ifndef ROSE_MEMORY_MAP_H
00002 #define ROSE_MEMORY_MAP_H
00003
00004
00005 #define ALIGN_UP(ADDR,ALMNT) ((((ADDR)+(ALMNT)-1)/(ALMNT))*(ALMNT))
00006
00007
00008 #define ALIGN_DN(ADDR,ALMNT) (((ADDR)/(ALMNT))*(ALMNT))
00009
00014 class MemoryMap {
00015 public:
00017 enum Protection {
00018
00019 MM_PROT_BITS = 0x00000007,
00020 MM_PROT_READ = 0x00000001,
00021 MM_PROT_WRITE = 0x00000002,
00022 MM_PROT_EXEC = 0x00000004,
00024
00025 MM_PROT_NONE = 0x00000000,
00026 MM_PROT_ANY = 0x00000007,
00027 MM_PROT_RW = (MM_PROT_READ|MM_PROT_WRITE),
00028 MM_PROT_RX = (MM_PROT_READ|MM_PROT_EXEC),
00029 MM_PROT_RWX = (MM_PROT_ANY),
00030
00031
00032
00033
00034 MM_PROT_FLAGS = 0xfffffff0,
00035 MM_PROT_PRIVATE = 0x00000010,
00036 };
00037
00045 typedef std::map<std::string, std::set<std::string> > NamePairings;
00046
00061 class MapElement {
00062 public:
00063 MapElement()
00064 : va(0), size(0), base(NULL), offset(0), read_only(false), mapperms(MM_PROT_READ), anonymous(NULL) {}
00065
00066 MapElement(const MapElement &other) {
00067 init(other);
00068 }
00069
00070 MapElement &operator=(const MapElement &other) {
00071 nullify();
00072 init(other);
00073 return *this;
00074 }
00075
00076 ~MapElement() {
00077 nullify();
00078 }
00079
00082 MapElement(rose_addr_t va, size_t size, void *base, rose_addr_t offset, unsigned perms=MM_PROT_READ)
00083 : va(va), size(size), base(base), offset(offset), read_only(false), mapperms(perms), anonymous(NULL) {}
00084
00087 MapElement(rose_addr_t va, size_t size, const void *base, rose_addr_t offset, unsigned perms=MM_PROT_READ)
00088 : va(va), size(size), base(const_cast<void*>(base)), offset(offset), read_only(true), mapperms(perms), anonymous(NULL)
00089 {}
00090
00094 MapElement(rose_addr_t va, size_t size, unsigned perms=MM_PROT_READ)
00095 : va(va), size(size), base(NULL), offset(0), read_only(false), mapperms(perms), anonymous(new Anonymous)
00096 {}
00097
00099 rose_addr_t get_va() const {
00100 return va;
00101 }
00102
00104 size_t get_size() const {
00105 return size;
00106 }
00107
00109 bool is_anonymous() const {
00110 return anonymous!=NULL;
00111 }
00112
00117 bool is_read_only() const {
00118 return read_only;
00119 }
00120
00124 unsigned get_mapperms() const {
00125 return mapperms;
00126 }
00127
00131 void set_mapperms(unsigned new_perms) {
00132 mapperms = new_perms;
00133 }
00134
00137 void *get_base(bool allocate_anonymous=true) const;
00138
00141 rose_addr_t get_offset() const {
00142 return offset;
00143 }
00144
00148 rose_addr_t get_va_offset(rose_addr_t va, size_t nbytes=1) const;
00149
00154 bool consistent(const MapElement &other) const;
00155
00158 bool merge(const MapElement &other);
00159
00163 MapElement& set_name(const std::string &name);
00164
00166 const std::string &get_name() const {
00167 return name;
00168 }
00169
00173 std::string get_name_pairings(NamePairings*) const;
00174
00177 MapElement& set_name(const NamePairings&, const std::string &s1="", const std::string &s2="");
00178
00179 #ifdef _MSC_VER
00180
00181
00182
00183
00184
00185
00186
00187
00188 #endif
00189
00190 private:
00191 friend class MemoryMap;
00192
00194 void init(const MapElement &other) {
00195 va = other.va;
00196 size = other.size;
00197 base = other.base;
00198 offset = other.offset;
00199 read_only = other.read_only;
00200 mapperms = other.mapperms;
00201 name = other.name;
00202
00203 anonymous = other.anonymous;
00204 if (anonymous)
00205 anonymous->refcount++;
00206 }
00207
00209 void nullify() {
00210 if (anonymous) {
00211 if (0==--(anonymous->refcount)) {
00212 delete[] anonymous->base;
00213 delete anonymous;
00214 }
00215 }
00216
00217 anonymous = NULL;
00218 va = 0;
00219 size = 0;
00220 base = NULL;
00221 offset = 0;
00222 read_only = 0;
00223 mapperms = MM_PROT_NONE;
00224 name = "";
00225 }
00226
00228 void merge_names(const MapElement &other);
00229
00234 void set_va(rose_addr_t new_va) {
00235 va = new_va;
00236 }
00237
00240 void set_offset(rose_addr_t new_offset) {
00241 offset = new_offset;
00242 }
00243
00247 void set_size(size_t sz) {
00248 ROSE_ASSERT(sz>0);
00249 size = sz;
00250 }
00251
00252 rose_addr_t va;
00253 size_t size;
00254 mutable void *base;
00255 rose_addr_t offset;
00256 bool read_only;
00257 unsigned mapperms;
00258 std::string name;
00262 class Anonymous {
00263 private:
00264 Anonymous(const Anonymous &other) { abort(); }
00265 Anonymous &operator=(const Anonymous &other) { abort(); return *this; }
00266 public:
00267 Anonymous(): refcount(1), base(NULL) {}
00268 size_t refcount;
00269 uint8_t *base;
00270 } *anonymous;
00271 };
00272
00274 struct Exception {
00275 Exception(const MemoryMap *map)
00276 : map(map) {}
00277 virtual ~Exception() {}
00278 friend std::ostream& operator<<(std::ostream&, const Exception&);
00279 virtual void print(std::ostream&) const;
00280 const MemoryMap *map;
00281 };
00282
00286 struct Inconsistent : public Exception {
00287 Inconsistent(const MemoryMap *map, const MapElement &a, const MapElement &b)
00288 : Exception(map), a(a), b(b) {}
00289 virtual ~Inconsistent() {}
00290 friend std::ostream& operator<<(std::ostream&, const Inconsistent&);
00291 virtual void print(std::ostream&) const;
00292 MapElement a, b;
00293 };
00294
00296 struct NotMapped : public Exception {
00297 NotMapped(const MemoryMap *map, rose_addr_t va)
00298 : Exception(map), va(va) {}
00299 virtual ~NotMapped() {}
00300 friend std::ostream& operator<<(std::ostream&, const NotMapped&);
00301 virtual void print(std::ostream&) const;
00302 rose_addr_t va;
00303 };
00304
00306 struct NoFreeSpace : public Exception {
00307 NoFreeSpace(const MemoryMap *map, size_t size)
00308 : Exception(map), size(size) {}
00309 virtual ~NoFreeSpace() {}
00310 friend std::ostream& operator<<(std::ostream&, const NoFreeSpace&);
00311 virtual void print(std::ostream&) const;
00312 size_t size;
00313 };
00314
00316 struct Syntax: public Exception {
00317 Syntax(const MemoryMap *map, const std::string &mesg, const std::string &filename, unsigned linenum, int colnum=-1)
00318 : Exception(map), mesg(mesg), filename(filename), linenum(linenum), colnum(colnum) {}
00319 virtual ~Syntax() {}
00320 friend std::ostream& operator<<(std::ostream&, const Syntax&);
00321 virtual void print(std::ostream&) const;
00322 std::string mesg;
00323 std::string filename;
00324 unsigned linenum;
00325 int colnum;
00326 };
00327
00328 MemoryMap() {}
00329
00332 void clear();
00333
00335 void insert(MapElement elmt);
00336
00340 void erase(MapElement elmt);
00341
00344 const MapElement* find(rose_addr_t va) const;
00345
00349 rose_addr_t find_free(rose_addr_t start_va, size_t size, rose_addr_t mem_alignment=1) const;
00350
00354 rose_addr_t find_last_free(rose_addr_t max=(rose_addr_t)(-1)) const;
00355
00357 const std::vector<MapElement> &get_elements() const;
00358
00360 void prune(bool(*predicate)(const MapElement&));
00361
00364 void prune(unsigned required, unsigned prohibited=MM_PROT_NONE);
00365
00372 size_t read(void *dst_buf, rose_addr_t start_va, size_t desired, unsigned req_perms=MM_PROT_READ) const;
00373
00377 SgUnsignedCharList read(rose_addr_t start_va, size_t desired, unsigned req_perms=MM_PROT_READ) const;
00378
00383 size_t read1(void *dst_buf, rose_addr_t va, size_t desired, unsigned req_perms=MM_PROT_READ,
00384 const MemoryMap::MapElement **mep=NULL) const;
00385
00390 size_t write(const void *src_buf, rose_addr_t start_va, size_t size, unsigned req_perms=MM_PROT_WRITE) const;
00391
00394 size_t write1(const void *src_buf, rose_addr_t va, size_t size, unsigned req_perms=MM_PROT_WRITE,
00395 const MemoryMap::MapElement **mep=NULL) const;
00396
00398 ExtentMap va_extents() const;
00399
00402 void mprotect(const MapElement &elmt, bool relax=false);
00403
00406 void dump(FILE*, const char *prefix="") const;
00407
00411 void dump(const std::string &basename) const;
00412
00438 bool load(const std::string &basename);
00439
00440 private:
00441 mutable std::vector<MapElement> elements;
00442 };
00443
00445 inline bool operator<(const MemoryMap::MapElement &a, const MemoryMap::MapElement &b) {
00446 return a.get_va() < b.get_va();
00447 }
00448
00449 #endif
00450
00451