ROSE  0.9.9.109
MemoryMap.h
1 #ifndef ROSE_BinaryAnalysis_MemoryMap_H
2 #define ROSE_BinaryAnalysis_MemoryMap_H
3 
4 #include "ByteOrder.h"
5 
6 #include <Sawyer/Access.h>
7 #include <Sawyer/AddressMap.h>
8 #include <Sawyer/AllocatingBuffer.h>
9 #include <Sawyer/MappedBuffer.h>
10 #include <Sawyer/NullBuffer.h>
11 #include <Sawyer/Optional.h>
12 #include <Sawyer/StaticBuffer.h>
13 
14 #include <boost/config.hpp>
15 #include <boost/serialization/access.hpp>
16 #include <boost/serialization/base_object.hpp>
17 #include <boost/serialization/export.hpp>
18 
19 namespace Rose {
20 namespace BinaryAnalysis {
21 
25 template<typename T>
26 T alignUp(T address, T alignment) {
27  return ((address + alignment - 1) / alignment) * alignment;
28 }
29 
34 template<typename T>
35 T alignDown(T address, T alignment) {
36  return (address / alignment) * alignment;
37 }
38 
96 class MemoryMap: public Sawyer::Container::AddressMap<rose_addr_t, uint8_t>, public Sawyer::SharedObject {
97 public:
99  typedef rose_addr_t Address;
100  typedef uint8_t Value;
110 
112  struct Attach { // For consistency with other <Feature>::Boolean types
113  enum Boolean {
114  NO,
116  };
117  };
118 
119 private:
120  ByteOrder::Endianness endianness_;
121 
122 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
123 private:
124  friend class boost::serialization::access;
125 
126  template<class S>
127  void serialize(S &s, const unsigned version) {
128  s.template register_type<AllocatingBuffer>();
129  s.template register_type<MappedBuffer>();
130  s.template register_type<NullBuffer>();
131  s.template register_type<StaticBuffer>();
132  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
133  s & BOOST_SERIALIZATION_NVP(endianness_);
134  }
135 #endif
136 
137 public:
138 
139  // Whoever pollutes all namespaces with these common word preprocessor symbols is a lunatic!
140 # if defined(READABLE) || defined(WRITABLE) || defined(EXECUTABLE) || defined(IMMUTABLE) || defined(PRIVATE)
141 # ifdef _MSC_VER
142 # pragma message("Undefining common words from the global namespace: READABLE, WRITABLE, EXECUTABLE, IMMUTABLE, PRIVATE")
143 # else
144 # warning "Undefining common words from the global namespace: READABLE, WRITABLE, EXECUTABLE, IMMUTABLE, PRIVATE"
145 # endif
146 # undef READABLE
147 # undef WRITABLE
148 # undef EXECUTABLE
149 # undef IMMUTABLE
150 # undef PRIVATE
151 # endif
152 
153  // Accessibility flags
154  static const unsigned NO_ACCESS = 0;
155  static const unsigned READABLE = Sawyer::Access::READABLE;
156  static const unsigned WRITABLE = Sawyer::Access::WRITABLE;
157  static const unsigned EXECUTABLE = Sawyer::Access::EXECUTABLE;
158  static const unsigned IMMUTABLE = Sawyer::Access::IMMUTABLE;
159  static const unsigned PRIVATE = 0x00000100;
160  static const unsigned INITIALIZED = 0x00000200; // Partitioner2: initialized memory even if writable
161 
162  // Aggregate accessibility flags
163  static const unsigned READ_WRITE = READABLE | WRITABLE;
164  static const unsigned READ_EXECUTE = READABLE | EXECUTABLE;
165  static const unsigned READ_WRITE_EXECUTE = READABLE | WRITABLE | EXECUTABLE;
166 
167  // These bits are reserved for use in ROSE
168  static const unsigned RESERVED_ACCESS_BITS = 0x0000ffff;
169 
170 
171 public:
173  class Exception: public std::runtime_error {
174  public:
175  Exception(const std::string &mesg, const MemoryMap::Ptr map): std::runtime_error(mesg), map(map) {}
176  virtual ~Exception() throw() {}
177  virtual std::string leader(std::string dflt="memory map problem") const;
178  virtual std::string details(bool) const;
179  virtual void print(std::ostream&, bool verbose=true) const;
180  friend std::ostream& operator<<(std::ostream&, const Exception&);
181  public:
183  };
184 
189  struct Inconsistent : public Exception {
190  Inconsistent(const std::string &mesg, const MemoryMap::Ptr &map,
191  const AddressInterval &new_range, const Segment &new_segment,
192  const AddressInterval &old_range, const Segment &old_segment)
193  : Exception(mesg, map),
194  new_range(new_range), old_range(old_range),
195  new_segment(new_segment), old_segment(old_segment) {}
196  virtual ~Inconsistent() throw() {}
197  virtual void print(std::ostream&, bool verbose=true) const;
198  friend std::ostream& operator<<(std::ostream&, const Inconsistent&);
199  AddressInterval new_range, old_range;
200  Segment new_segment, old_segment;
201  };
202 
204  struct NotMapped : public Exception {
205  NotMapped(const std::string &mesg, const MemoryMap::Ptr &map, rose_addr_t va)
206  : Exception(mesg, map), va(va) {}
207  virtual ~NotMapped() throw() {}
208  virtual void print(std::ostream&, bool verbose=true) const;
209  friend std::ostream& operator<<(std::ostream&, const NotMapped&);
210  rose_addr_t va;
211  };
212 
214  struct NoFreeSpace : public Exception {
215  NoFreeSpace(const std::string &mesg, const MemoryMap::Ptr &map, size_t size)
216  : Exception(mesg, map), size(size) {}
217  virtual ~NoFreeSpace() throw() {}
218  virtual void print(std::ostream&, bool verbose=true) const;
219  friend std::ostream& operator<<(std::ostream&, const NoFreeSpace&);
220  size_t size;
221  };
222 
224  struct SyntaxError: public Exception {
225  SyntaxError(const std::string &mesg, const MemoryMap::Ptr &map, const std::string &filename,
226  unsigned linenum, int colnum=-1)
227  : Exception(mesg, map), filename(filename), linenum(linenum), colnum(colnum) {}
228  virtual ~SyntaxError() throw() {}
229  virtual void print(std::ostream&, bool verbose=true) const;
230  friend std::ostream& operator<<(std::ostream&, const SyntaxError&);
231  std::string filename;
232  unsigned linenum;
233  int colnum;
234  };
235 
236 protected:
238  MemoryMap(): endianness_(ByteOrder::ORDER_UNSPECIFIED) {}
239 
240 public:
242  static Ptr instance() {
243  return Ptr(new MemoryMap);
244  }
245 
249  Ptr shallowCopy() {
250  return Ptr(new MemoryMap(*this));
251  }
252 
260  ByteOrder::Endianness byteOrder() const { return endianness_; }
261  void byteOrder(ByteOrder::Endianness order) { endianness_ = order; }
268  size_t insertFile(const std::string &fileName, rose_addr_t va, bool writable=false, std::string segmentName="");
269 
345  AddressInterval insertFile(const std::string &locatorString);
346 
348  static std::string insertFileDocumentation();
349 
350 #ifdef BOOST_WINDOWS
351  void insertProcess(int pid, Attach::Boolean attach);
352 #else
353 
354  void insertProcess(pid_t pid, Attach::Boolean attach);
355 #endif
356 
360  void insertProcess(const std::string &locatorString);
361 
363  static std::string insertProcessDocumentation();
364 
366  void eraseZeros(size_t minsize);
367 
378  bool shrinkUnshare();
379 
381  size_t readQuick(void *buf, rose_addr_t startVa, size_t desired) const {
382  return at(startVa).limit(desired).require(READABLE).read((uint8_t*)buf).size();
383  }
384 
397  std::string readString(rose_addr_t startVa, size_t desired, int(*validChar)(int)=NULL, int(*invalidChar)(int)=NULL,
398  unsigned requiredPerms=READABLE, unsigned prohibitedPerms=0, char terminator='\0') const;
399 
401  SgUnsignedCharList readVector(rose_addr_t startVa, size_t desired, unsigned requiredPerms=READABLE) const;
402 
404  size_t writeQuick(const void *buf, rose_addr_t startVa, size_t desired) {
405  return at(startVa).limit(desired).require(WRITABLE).write((const uint8_t*)buf).size();
406  }
407 
415  Sawyer::Optional<rose_addr_t> findAny(const Extent &limits, const std::vector<uint8_t> &bytesToFind,
416  unsigned requiredPerms=READABLE, unsigned prohibitedPerms=0) const;
417  Sawyer::Optional<rose_addr_t> findAny(const AddressInterval &limits, const std::vector<uint8_t> &bytesToFind,
418  unsigned requiredPerms=READABLE, unsigned prohibitedPerms=0) const;
426  Sawyer::Optional<rose_addr_t> findSequence(const AddressInterval &interval, const std::vector<uint8_t> &sequence) const;
427 
431  void dump(FILE*, const char *prefix="") const;
432  void dump(std::ostream&, std::string prefix="") const;
433  void print(std::ostream &o, std::string prefix="") const { dump(o, prefix); }
437  static std::string segmentTitle(const Segment&);
438 
439  friend std::ostream& operator<<(std::ostream&, const MemoryMap&);
440 };
441 
442 } // namespace
443 } // namespace
444 
445 // Register the types needed for serialization since some of them are derived from polymorphic class templates.
446 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
448 BOOST_CLASS_EXPORT_KEY(Rose::BinaryAnalysis::MemoryMap::MappedBuffer);
449 BOOST_CLASS_EXPORT_KEY(Rose::BinaryAnalysis::MemoryMap::NullBuffer);
450 BOOST_CLASS_EXPORT_KEY(Rose::BinaryAnalysis::MemoryMap::StaticBuffer);
451 #endif
452 
453 
454 #endif
Exception thrown by find_free() when there's not enough free space left.
Definition: MemoryMap.h:214
int colnum
Optional column number (0-origin; negative if unknown).
Definition: MemoryMap.h:233
T alignDown(T address, T alignment)
Align address upward to boundary.
Definition: MemoryMap.h:35
Points to static data.
Definition: StaticBuffer.h:30
Exception thrown by load() when there's a syntax error in the index file.
Definition: MemoryMap.h:224
virtual std::string leader(std::string dflt="memory map problem") const
Leading part of the error message.
void print(std::ostream &o, std::string prefix="") const
Prints the contents of the map for debugging.
Definition: MemoryMap.h:433
virtual std::string details(bool) const
Details emitted on following lines, indented two spaces.
AddressMapConstraints< const AddressMap > at(Address x) const
Constraint: anchor point.
Definition: AddressMap.h:1082
static std::string insertFileDocumentation()
Documentation string for insertFile.
A contiguous range of values.
Definition: rangemap.h:50
MemoryMap()
Constructs an empty memory map.
Definition: MemoryMap.h:238
MemoryMap::Ptr map
Map that caused the exception if available, null otherwise.
Definition: MemoryMap.h:182
Attach with ptrace, get memory, then detach.
Definition: MemoryMap.h:115
AddressSegment< rose_addr_t, uint8_t > Segment
Type of segments stored by this map.
Definition: AddressMap.h:978
Main namespace for the ROSE library.
Memory mapped file.
Definition: MappedBuffer.h:43
Allocates memory as needed.
std::string filename
Name of index file where error occurred.
Definition: MemoryMap.h:231
static Ptr instance()
Construct an empty memory map.
Definition: MemoryMap.h:242
void byteOrder(ByteOrder::Endianness order)
Property: byte order.
Definition: MemoryMap.h:261
size_t readQuick(void *buf, rose_addr_t startVa, size_t desired) const
Read data into buffer.
Definition: MemoryMap.h:381
void insertProcess(pid_t pid, Attach::Boolean attach)
Insert the memory of some other process into this memory map.
Exception for when we try to access a virtual address that isn't mapped.
Definition: MemoryMap.h:204
A mapping from address space to values.
Definition: AddressMap.h:971
Buffer that has no data.
Definition: NullBuffer.h:26
Base class for all buffers.
Definition: Buffer.h:25
An efficient mapping from an address space to stored data.
Definition: MemoryMap.h:96
unsigned linenum
Line number (1 origin) where error occurred.
Definition: MemoryMap.h:232
Constraints are used to select addresses from a memory map.
Definition: AddressMap.h:76
Sawyer::Optional< rose_addr_t > findSequence(const AddressInterval &interval, const std::vector< uint8_t > &sequence) const
Search for a byte sequence.
std::string readString(rose_addr_t startVa, size_t desired, int(*validChar)(int)=NULL, int(*invalidChar)(int)=NULL, unsigned requiredPerms=READABLE, unsigned prohibitedPerms=0, char terminator='\0') const
Reads a NUL-terminated string from the memory map.
Base class for reference counted objects.
Definition: SharedObject.h:22
Exception for an inconsistent mapping.
Definition: MemoryMap.h:189
void dump(FILE *, const char *prefix="") const
Prints the contents of the map for debugging.
void eraseZeros(size_t minsize)
Erases regions of zero bytes that are executable and readable and at least minsize in size...
SgUnsignedCharList readVector(rose_addr_t startVa, size_t desired, unsigned requiredPerms=READABLE) const
Read quickly into a vector.
Attach with ptrace first when reading a process?
Definition: MemoryMap.h:112
bool shrinkUnshare()
Shrink buffers and remove sharing.
ByteOrder::Endianness byteOrder() const
Property: byte order.
Definition: MemoryMap.h:260
Sawyer::Optional< rose_addr_t > findAny(const Extent &limits, const std::vector< uint8_t > &bytesToFind, unsigned requiredPerms=READABLE, unsigned prohibitedPerms=0) const
Search for any byte.
static std::string segmentTitle(const Segment &)
Title of a segment when printing the map.
static std::string insertProcessDocumentation()
Documentation string for insertProcess.
size_t writeQuick(const void *buf, rose_addr_t startVa, size_t desired)
Write data from buffer.
Definition: MemoryMap.h:404
T alignUp(T address, T alignment)
Align address downward to boundary.
Definition: MemoryMap.h:26
size_t insertFile(const std::string &fileName, rose_addr_t va, bool writable=false, std::string segmentName="")
Insert file contents into memory map.
Exception for MemoryMap operations.
Definition: MemoryMap.h:173
Assume ptrace is attached and process is stopped.
Definition: MemoryMap.h:114
Ptr shallowCopy()
Create a new copy of the memory map.
Definition: MemoryMap.h:249