ROSE  0.9.10.103
MemoryMap.h
1 #ifndef ROSE_BinaryAnalysis_MemoryMap_H
2 #define ROSE_BinaryAnalysis_MemoryMap_H
3 
4 #include <ByteOrder.h>
5 #include <Combinatorics.h>
6 
7 #include <Sawyer/Access.h>
8 #include <Sawyer/AddressMap.h>
9 #include <Sawyer/AllocatingBuffer.h>
10 #include <Sawyer/MappedBuffer.h>
11 #include <Sawyer/NullBuffer.h>
12 #include <Sawyer/Optional.h>
13 #include <Sawyer/StaticBuffer.h>
14 
15 #include <boost/config.hpp>
16 #include <boost/utility/enable_if.hpp>
17 #include <boost/serialization/access.hpp>
18 #include <boost/serialization/base_object.hpp>
19 #include <boost/serialization/export.hpp>
20 #include <boost/type_traits/is_integral.hpp>
21 
22 namespace Rose {
23 namespace BinaryAnalysis {
24 
30 template<typename T, typename U>
31 typename boost::enable_if_c<boost::is_integral<T>::value && boost::is_integral<U>::value, T>::type
32 alignUp(T address, U alignment) {
33  ASSERT_require(alignment > 0);
34  T almt = static_cast<T>(alignment);
35  return ((address + almt - 1) / almt) * almt;
36 }
37 
43 template<typename T, typename U>
44 typename boost::enable_if_c<boost::is_integral<T>::value && boost::is_integral<U>::value, T>::type
45 alignDown(T address, U alignment) {
46  ASSERT_require(alignment > 0);
47  T almt = static_cast<T>(alignment);
48  return (address / almt) * almt;
49 }
50 
108 class MemoryMap: public Sawyer::Container::AddressMap<rose_addr_t, uint8_t>, public Sawyer::SharedObject {
109 public:
111  typedef rose_addr_t Address;
112  typedef uint8_t Value;
122 
124  struct Attach { // For consistency with other <Feature>::Boolean types
125  enum Boolean {
126  NO,
128  };
129  };
130 
131 private:
132  ByteOrder::Endianness endianness_;
133 
134 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
135 private:
136  friend class boost::serialization::access;
137 
138  template<class S>
139  void serialize(S &s, const unsigned /*version*/) {
140  s.template register_type<AllocatingBuffer>();
141  s.template register_type<MappedBuffer>();
142  s.template register_type<NullBuffer>();
143  s.template register_type<StaticBuffer>();
144  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
145  s & BOOST_SERIALIZATION_NVP(endianness_);
146  }
147 #endif
148 
149 public:
150 
151  // Whoever pollutes all namespaces with these common word preprocessor symbols is a lunatic!
152 # if defined(READABLE) || defined(WRITABLE) || defined(EXECUTABLE) || defined(IMMUTABLE) || defined(PRIVATE)
153 # ifdef _MSC_VER
154 # pragma message("Undefining common words from the global namespace: READABLE, WRITABLE, EXECUTABLE, IMMUTABLE, PRIVATE")
155 # else
156 # warning "Undefining common words from the global namespace: READABLE, WRITABLE, EXECUTABLE, IMMUTABLE, PRIVATE"
157 # endif
158 # undef READABLE
159 # undef WRITABLE
160 # undef EXECUTABLE
161 # undef IMMUTABLE
162 # undef PRIVATE
163 # endif
164 
165  // Accessibility flags
166  static const unsigned NO_ACCESS = 0;
167  static const unsigned READABLE = Sawyer::Access::READABLE;
168  static const unsigned WRITABLE = Sawyer::Access::WRITABLE;
169  static const unsigned EXECUTABLE = Sawyer::Access::EXECUTABLE;
170  static const unsigned IMMUTABLE = Sawyer::Access::IMMUTABLE;
171  static const unsigned PRIVATE = Sawyer::Access::PRIVATE;
172  static const unsigned INITIALIZED = 0x00000200; // Partitioner2: initialized memory even if writable
173 
174  // Aggregate accessibility flags
175  static const unsigned READ_WRITE = READABLE | WRITABLE;
176  static const unsigned READ_EXECUTE = READABLE | EXECUTABLE;
177  static const unsigned READ_WRITE_EXECUTE = READABLE | WRITABLE | EXECUTABLE;
178 
179  // These bits are reserved for use in ROSE
180  static const unsigned RESERVED_ACCESS_BITS = 0x0000ffff;
181 
182 
183 public:
185  class Exception: public std::runtime_error {
186  public:
187  Exception(const std::string &mesg, const MemoryMap::Ptr map): std::runtime_error(mesg), map(map) {}
188  virtual ~Exception() throw() {}
189  virtual std::string leader(std::string dflt="memory map problem") const;
190  virtual std::string details(bool) const;
191  virtual void print(std::ostream&, bool verbose=true) const;
192  friend std::ostream& operator<<(std::ostream&, const Exception&);
193  public:
195  };
196 
201  struct Inconsistent : public Exception {
202  Inconsistent(const std::string &mesg, const MemoryMap::Ptr &map,
203  const AddressInterval &new_range, const Segment &new_segment,
204  const AddressInterval &old_range, const Segment &old_segment)
205  : Exception(mesg, map),
206  new_range(new_range), old_range(old_range),
207  new_segment(new_segment), old_segment(old_segment) {}
208  virtual ~Inconsistent() throw() {}
209  virtual void print(std::ostream&, bool verbose=true) const;
210  friend std::ostream& operator<<(std::ostream&, const Inconsistent&);
211  AddressInterval new_range, old_range;
212  Segment new_segment, old_segment;
213  };
214 
216  struct NotMapped : public Exception {
217  NotMapped(const std::string &mesg, const MemoryMap::Ptr &map, rose_addr_t va)
218  : Exception(mesg, map), va(va) {}
219  virtual ~NotMapped() throw() {}
220  virtual void print(std::ostream&, bool verbose=true) const;
221  friend std::ostream& operator<<(std::ostream&, const NotMapped&);
222  rose_addr_t va;
223  };
224 
226  struct NoFreeSpace : public Exception {
227  NoFreeSpace(const std::string &mesg, const MemoryMap::Ptr &map, size_t size)
228  : Exception(mesg, map), size(size) {}
229  virtual ~NoFreeSpace() throw() {}
230  virtual void print(std::ostream&, bool verbose=true) const;
231  friend std::ostream& operator<<(std::ostream&, const NoFreeSpace&);
232  size_t size;
233  };
234 
236  struct SyntaxError: public Exception {
237  SyntaxError(const std::string &mesg, const MemoryMap::Ptr &map, const std::string &filename,
238  unsigned linenum, int colnum=-1)
239  : Exception(mesg, map), filename(filename), linenum(linenum), colnum(colnum) {}
240  virtual ~SyntaxError() throw() {}
241  virtual void print(std::ostream&, bool verbose=true) const;
242  friend std::ostream& operator<<(std::ostream&, const SyntaxError&);
243  std::string filename;
244  unsigned linenum;
245  int colnum;
246  };
247 
248 protected:
250  MemoryMap(): endianness_(ByteOrder::ORDER_UNSPECIFIED) {}
251 
252 public:
254  static Ptr instance() {
255  return Ptr(new MemoryMap);
256  }
257 
261  Ptr shallowCopy() {
262  return Ptr(new MemoryMap(*this));
263  }
264 
272  ByteOrder::Endianness byteOrder() const { return endianness_; }
273  void byteOrder(ByteOrder::Endianness order) { endianness_ = order; }
276  // Note that the order of the enum members is for backward compatibility with an older version of insertFile whose third
277  // argument was "bool writable = false" (MAP_RDONLY, but now intended to be MAP_PRIVATE) and when it was true was the same
278  // as MAP_READWRITE.
279  //
288  };
289 
294  size_t insertFile(const std::string &fileName, rose_addr_t va, InsertFileMapMode mode = MAP_PRIVATE,
295  std::string segmentName = "");
296 
372  AddressInterval insertFile(const std::string &locatorString);
373 
375  static std::string insertFileDocumentation();
376 
403  AddressInterval insertData(const std::string &locatorString);
404 
406  static std::string insertDataDocumentation();
407 
408 
409 #ifdef BOOST_WINDOWS
410  void insertProcess(int pid, Attach::Boolean attach);
411 #else
412 
413  void insertProcess(pid_t pid, Attach::Boolean attach);
414 #endif
415 
419  void insertProcess(const std::string &locatorString);
420 
422  static std::string insertProcessDocumentation();
423 
425  void eraseZeros(size_t minsize);
426 
437  bool shrinkUnshare();
438 
440  size_t readQuick(void *buf, rose_addr_t startVa, size_t desired) const {
441  return at(startVa).limit(desired).require(READABLE).read((uint8_t*)buf).size();
442  }
443 
456  std::string readString(rose_addr_t startVa, size_t desired, int(*validChar)(int)=NULL, int(*invalidChar)(int)=NULL,
457  unsigned requiredPerms=READABLE, unsigned prohibitedPerms=0, char terminator='\0') const;
458 
464  template<typename U>
465  Sawyer::Optional<U> readUnsigned(rose_addr_t startVa) const {
466  U val = 0;
467  if (at(startVa).limit(sizeof val).read((uint8_t*)&val).size() != sizeof val)
468  return Sawyer::Nothing();
469  ByteOrder::convert((void*)&val, sizeof val, endianness_, ByteOrder::host_order());
470  return val;
471  }
472 
474  SgUnsignedCharList readVector(rose_addr_t startVa, size_t desired, unsigned requiredPerms=READABLE) const;
475 
477  size_t writeQuick(const void *buf, rose_addr_t startVa, size_t desired) {
478  return at(startVa).limit(desired).require(WRITABLE).write((const uint8_t*)buf).size();
479  }
480 
488  Sawyer::Optional<rose_addr_t> findAny(const Extent &limits, const std::vector<uint8_t> &bytesToFind,
489  unsigned requiredPerms=READABLE, unsigned prohibitedPerms=0) const;
490  Sawyer::Optional<rose_addr_t> findAny(const AddressInterval &limits, const std::vector<uint8_t> &bytesToFind,
491  unsigned requiredPerms=READABLE, unsigned prohibitedPerms=0) const;
499  Sawyer::Optional<rose_addr_t> findSequence(const AddressInterval &interval, const std::vector<uint8_t> &sequence) const;
500 
504  void dump(FILE*, const char *prefix="") const;
505  void dump(std::ostream&, std::string prefix="") const;
506  void print(std::ostream &o, std::string prefix="") const { dump(o, prefix); }
524 
526  static std::string segmentTitle(const Segment&);
527 
528  friend std::ostream& operator<<(std::ostream&, const MemoryMap&);
529 };
530 
531 } // namespace
532 } // namespace
533 
534 // Register the types needed for serialization since some of them are derived from polymorphic class templates.
535 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
537 BOOST_CLASS_EXPORT_KEY(Rose::BinaryAnalysis::MemoryMap::MappedBuffer);
538 BOOST_CLASS_EXPORT_KEY(Rose::BinaryAnalysis::MemoryMap::NullBuffer);
539 BOOST_CLASS_EXPORT_KEY(Rose::BinaryAnalysis::MemoryMap::StaticBuffer);
540 #endif
541 
542 
543 #endif
Exception thrown by find_free() when there's not enough free space left.
Definition: MemoryMap.h:226
int colnum
Optional column number (0-origin; negative if unknown).
Definition: MemoryMap.h:245
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:236
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:506
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.
size_t insertFile(const std::string &fileName, rose_addr_t va, InsertFileMapMode mode=MAP_PRIVATE, std::string segmentName="")
Insert file contents into memory map.
A contiguous range of values.
Definition: rangemap.h:50
InsertFileMapMode
Mapping mode for insertFile.
Definition: MemoryMap.h:281
MemoryMap()
Constructs an empty memory map.
Definition: MemoryMap.h:250
Holds a value or nothing.
Definition: Optional.h:49
MemoryMap::Ptr map
Map that caused the exception if available, null otherwise.
Definition: MemoryMap.h:194
Attach with ptrace, get memory, then detach.
Definition: MemoryMap.h:127
AddressSegment< rose_addr_t, uint8_t > Segment
Type of segments stored by this map.
Definition: AddressMap.h:978
AddressInterval insertData(const std::string &locatorString)
Insert data into a memory map.
Main namespace for the ROSE library.
Memory mapped file.
Definition: MappedBuffer.h:43
File is mapped with read-only permission.
Definition: MemoryMap.h:286
Allocates memory as needed.
std::string filename
Name of index file where error occurred.
Definition: MemoryMap.h:243
Combinatorics::Hasher & hash(Combinatorics::Hasher &) const
Compute a hash of the entire memory contents.
static Ptr instance()
Construct an empty memory map.
Definition: MemoryMap.h:254
void byteOrder(ByteOrder::Endianness order)
Property: byte order.
Definition: MemoryMap.h:273
Sawyer::Container::Interval< Address > read(Value *buf, const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Reads data into the supplied buffer.
Definition: AddressMap.h:1657
File is mapped with read and write permission.
Definition: MemoryMap.h:284
size_t readQuick(void *buf, rose_addr_t startVa, size_t desired) const
Read data into buffer.
Definition: MemoryMap.h:440
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:216
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:108
boost::enable_if_c< boost::is_integral< T >::value &&boost::is_integral< U >::value, T >::type alignDown(T address, U alignment)
Align address upward to boundary.
Definition: MemoryMap.h:45
boost::enable_if_c< boost::is_integral< T >::value &&boost::is_integral< U >::value, T >::type alignUp(T address, U alignment)
Align address downward to boundary.
Definition: MemoryMap.h:32
unsigned linenum
Line number (1 origin) where error occurred.
Definition: MemoryMap.h:244
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:201
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:124
bool shrinkUnshare()
Shrink buffers and remove sharing.
Represents no value.
Definition: Optional.h:32
ByteOrder::Endianness byteOrder() const
Property: byte order.
Definition: MemoryMap.h:272
static std::string insertDataDocumentation()
Documentation string for insertData.
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.
AddressMapConstraints< const AddressMap > limit(size_t x) const
Constraint: limit matched size.
Definition: AddressMap.h:1123
size_t writeQuick(const void *buf, rose_addr_t startVa, size_t desired)
Write data from buffer.
Definition: MemoryMap.h:477
Sawyer::Optional< U > readUnsigned(rose_addr_t startVa) const
Read an unsigned value.
Definition: MemoryMap.h:465
Exception for MemoryMap operations.
Definition: MemoryMap.h:185
Assume ptrace is attached and process is stopped.
Definition: MemoryMap.h:126
Ptr shallowCopy()
Create a new copy of the memory map.
Definition: MemoryMap.h:261