MemoryMap.h

Go to the documentation of this file.
00001 #ifndef ROSE_MEMORY_MAP_H
00002 #define ROSE_MEMORY_MAP_H
00003 
00004 /* Increase ADDR if necessary to make it a multiple of ALMNT */
00005 #define ALIGN_UP(ADDR,ALMNT)       ((((ADDR)+(ALMNT)-1)/(ALMNT))*(ALMNT))
00006 
00007 /* Decrease ADDR if necessary to make it a multiple of ALMNT */
00008 #define ALIGN_DN(ADDR,ALMNT)       (((ADDR)/(ALMNT))*(ALMNT))
00009 
00014 class MemoryMap {
00015 public:
00017     enum Protection {
00018         /* Protection bits */
00019         MM_PROT_BITS    = 0x00000007,     /*NO_STRINGIFY*/
00020         MM_PROT_READ    = 0x00000001,    
00021         MM_PROT_WRITE   = 0x00000002,    
00022         MM_PROT_EXEC    = 0x00000004,    
00024         /* Protection convenience stuff */
00025         MM_PROT_NONE    = 0x00000000,    
00026         MM_PROT_ANY     = 0x00000007,    
00027         MM_PROT_RW      = (MM_PROT_READ|MM_PROT_WRITE),                   /*NO_STRINGIFY*/
00028         MM_PROT_RX      = (MM_PROT_READ|MM_PROT_EXEC),                  /*NO_STRINGIFY*/
00029         MM_PROT_RWX     = (MM_PROT_ANY),                                                        /*NO_STRINGIFY*/
00030 
00031         /* Other flags. These generally aren't interpreted by MemoryMap, but can be used to pass info.  When merging memory
00032          * regions, MemoryMap::MapElement::consistent() will not treat two regions as being consistent if they have different
00033          * bits set. */
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         /* CH (4/15/2010): Make < operator be its member function instead of non-member function outside to avoid template
00181          * parameter deduction failure in MSVC */
00182 // tps : commented out because of operatror < is ambigious.
00183 // there is a function at the end of the file that is ambigious
00184 //inline bool operator<(const MemoryMap::MapElement &a, const MemoryMap::MapElement &b) {
00185 //        bool operator<(const MapElement &a) const {
00186  //           return this->get_va() < a.get_va();
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; } // return is to silence Klockwork
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 

Generated on Tue Jan 31 05:31:37 2012 for ROSE by  doxygen 1.4.7