ROSE 0.11.145.147
MemoryMap.h
1#ifndef ROSE_BinaryAnalysis_MemoryMap_H
2#define ROSE_BinaryAnalysis_MemoryMap_H
3#include <featureTests.h>
4#ifdef ROSE_ENABLE_BINARY_ANALYSIS
5
6#include <Rose/BinaryAnalysis/AddressIntervalSet.h>
7#include <Rose/BinaryAnalysis/BasicTypes.h>
8#include <Rose/BinaryAnalysis/ByteOrder.h>
9#include <Rose/Exception.h>
10
11#include <Combinatorics.h>
12#include <rose_extent.h>
13#include <sageContainer.h>
14
15#include <Sawyer/Access.h>
16#include <Sawyer/AddressMap.h>
17#include <Sawyer/AllocatingBuffer.h>
18#include <Sawyer/MappedBuffer.h>
19#include <Sawyer/NullBuffer.h>
20#include <Sawyer/Optional.h>
21#include <Sawyer/StaticBuffer.h>
22
23#include <boost/config.hpp>
24#include <boost/utility/enable_if.hpp>
25#include <boost/serialization/access.hpp>
26#include <boost/serialization/base_object.hpp>
27#include <boost/serialization/export.hpp>
28#include <boost/type_traits/is_integral.hpp>
29
30namespace Rose {
31namespace BinaryAnalysis {
32
38template<typename T, typename U>
39typename boost::enable_if_c<boost::is_integral<T>::value && boost::is_integral<U>::value, T>::type
40alignUp(T address, U alignment) {
41 ASSERT_require(alignment > 0);
42 T almt = static_cast<T>(alignment);
43 return ((address + almt - 1) / almt) * almt;
44}
45
51template<typename T, typename U>
52typename boost::enable_if_c<boost::is_integral<T>::value && boost::is_integral<U>::value, T>::type
53alignDown(T address, U alignment) {
54 ASSERT_require(alignment > 0);
55 T almt = static_cast<T>(alignment);
56 return (address / almt) * almt;
57}
58
115class MemoryMap: public Sawyer::Container::AddressMap<rose_addr_t, uint8_t>, public Sawyer::SharedObject {
116public:
119
120 typedef rose_addr_t Address;
121 typedef uint8_t Value;
131
133 struct Attach { // For consistency with other <Feature>::Boolean types
134 enum Boolean {
136 YES
137 };
138 };
139
141 enum class Clobber {NO, YES};
142
143private:
144 ByteOrder::Endianness endianness_;
145 std::string name_;
146
147#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
148private:
149 friend class boost::serialization::access;
150
151 template<class S>
152 void serialize(S &s, const unsigned /*version*/) {
153 s.template register_type<AllocatingBuffer>();
154 s.template register_type<MappedBuffer>();
155 s.template register_type<NullBuffer>();
156 s.template register_type<StaticBuffer>();
157 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
158 s & BOOST_SERIALIZATION_NVP(endianness_);
159 }
160#endif
161
162public:
163
164 // Whoever pollutes all namespaces with these common word preprocessor symbols is a lunatic!
165# if defined(READABLE) || defined(WRITABLE) || defined(EXECUTABLE) || defined(IMMUTABLE) || defined(PRIVATE)
166# ifdef _MSC_VER
167# pragma message("Undefining common words from the global namespace: READABLE, WRITABLE, EXECUTABLE, IMMUTABLE, PRIVATE")
168# else
169# warning "Undefining common words from the global namespace: READABLE, WRITABLE, EXECUTABLE, IMMUTABLE, PRIVATE"
170# endif
171# undef READABLE
172# undef WRITABLE
173# undef EXECUTABLE
174# undef IMMUTABLE
175# undef PRIVATE
176# endif
177
178 // Accessibility flags
179 static const unsigned NO_ACCESS = 0;
180 static const unsigned READABLE = Sawyer::Access::READABLE;
181 static const unsigned WRITABLE = Sawyer::Access::WRITABLE;
182 static const unsigned EXECUTABLE = Sawyer::Access::EXECUTABLE;
183 static const unsigned IMMUTABLE = Sawyer::Access::IMMUTABLE;
184 static const unsigned PRIVATE = Sawyer::Access::PRIVATE;
185 static const unsigned INITIALIZED = 0x00000200; // Partitioner2: initialized memory even if writable
186
187 // Aggregate accessibility flags
188 static const unsigned READ_WRITE = READABLE | WRITABLE;
189 static const unsigned READ_EXECUTE = READABLE | EXECUTABLE;
190 static const unsigned READ_WRITE_EXECUTE = READABLE | WRITABLE | EXECUTABLE;
191
192 // These bits are reserved for use in ROSE
193 static const unsigned RESERVED_ACCESS_BITS = 0x0000ffff;
194
195
196public:
199 public:
200 Exception(const std::string &mesg, const MemoryMap::Ptr map): Rose::Exception(mesg), map(map) {}
201 virtual ~Exception() throw() {}
202 virtual std::string leader(std::string dflt="memory map problem") const;
203 virtual std::string details(bool) const;
204 virtual void print(std::ostream&, bool verbose=true) const;
205 friend std::ostream& operator<<(std::ostream&, const Exception&);
206 public:
208 };
209
214 struct Inconsistent : public Exception {
215 Inconsistent(const std::string &mesg, const MemoryMap::Ptr &map,
216 const AddressInterval &new_range, const Segment &new_segment,
217 const AddressInterval &old_range, const Segment &old_segment)
218 : Exception(mesg, map),
219 new_range(new_range), old_range(old_range),
220 new_segment(new_segment), old_segment(old_segment) {}
221 virtual ~Inconsistent() throw() {}
222 virtual void print(std::ostream&, bool verbose=true) const;
223 friend std::ostream& operator<<(std::ostream&, const Inconsistent&);
224 AddressInterval new_range, old_range;
225 Segment new_segment, old_segment;
226 };
227
229 struct NotMapped : public Exception {
230 NotMapped(const std::string &mesg, const MemoryMap::Ptr &map, rose_addr_t va)
231 : Exception(mesg, map), va(va) {}
232 virtual ~NotMapped() throw() {}
233 virtual void print(std::ostream&, bool verbose=true) const;
234 friend std::ostream& operator<<(std::ostream&, const NotMapped&);
235 rose_addr_t va;
236 };
237
239 struct NoFreeSpace : public Exception {
240 NoFreeSpace(const std::string &mesg, const MemoryMap::Ptr &map, size_t size)
241 : Exception(mesg, map), size(size) {}
242 virtual ~NoFreeSpace() throw() {}
243 virtual void print(std::ostream&, bool verbose=true) const;
244 friend std::ostream& operator<<(std::ostream&, const NoFreeSpace&);
245 size_t size;
246 };
247
249 struct SyntaxError: public Exception {
250 SyntaxError(const std::string &mesg, const MemoryMap::Ptr &map, const std::string &filename,
251 unsigned linenum, int colnum=-1)
253 virtual ~SyntaxError() throw() {}
254 virtual void print(std::ostream&, bool verbose=true) const;
255 friend std::ostream& operator<<(std::ostream&, const SyntaxError&);
256 std::string filename;
257 unsigned linenum;
258 int colnum;
259 };
260
261protected:
263 MemoryMap(): endianness_(ByteOrder::ORDER_UNSPECIFIED) {}
264
265public:
267 static Ptr instance() {
268 return Ptr(new MemoryMap);
269 }
270
275 return Ptr(new MemoryMap(*this));
276 }
277
285 ByteOrder::Endianness byteOrder() const { return endianness_; }
286 void byteOrder(ByteOrder::Endianness order) { endianness_ = order; }
294 const std::string& name() const;
295 void name(const std::string&);
298 // Note that the order of the enum members is for backward compatibility with an older version of insertFile whose third
299 // argument was "bool writable = false" (MAP_RDONLY, but now intended to be MAP_PRIVATE) and when it was true was the same
300 // as MAP_READWRITE.
301 //
304 MAP_PRIVATE = 0,
306 MAP_READWRITE = 1,
308 MAP_RDONLY = 2
310 };
311
316 size_t insertFile(const std::string &fileName, rose_addr_t va, InsertFileMapMode mode = MAP_PRIVATE,
317 std::string segmentName = "");
318
394 AddressInterval insertFile(const std::string &locatorString);
395
397 static std::string insertFileDocumentation();
398
425 AddressInterval insertData(const std::string &locatorString);
426
428 static std::string insertDataDocumentation();
429
434 void adjustMap(const std::string &locatorString);
435
437 static std::string adjustMapDocumentation();
438
439
442 AddressInterval interval;
443 unsigned accessibility;
444 rose_addr_t fileOffset;
445 std::string deviceName;
446 size_t inode;
447 std::string comment;
451 };
452
456 static std::vector<ProcessMapRecord> readProcessMap(pid_t);
457
458#ifdef BOOST_WINDOWS
459 void insertProcess(int pid, Attach::Boolean attach);
460#else
462 void insertProcess(pid_t pid, Attach::Boolean attach);
463#endif
464
468 void insertProcess(const std::string &locatorString);
469
473 bool insertProcessPid(pid_t, const AddressInterval &where, unsigned accessibility, const std::string &name);
474 void insertProcessPid(pid_t, const std::vector<ProcessMapRecord>&);
475 bool insertProcessMemory(int memFile, const AddressInterval &where, unsigned accessibility, std::string name);
479 static std::string insertProcessDocumentation();
480
494 AddressIntervalSet linkTo(const MemoryMap::Ptr &source, const AddressIntervalSet &where, Clobber = Clobber::YES);
495 AddressIntervalSet linkTo(const MemoryMap::Ptr &source, const AddressInterval &where, Clobber = Clobber::YES);
508 MemoryMap::Ptr align(rose_addr_t lowAlignment, rose_addr_t highAlignment) const;
509
515 static std::pair<Buffer::Ptr, std::string> copyFromFile(int fd, const AddressInterval&);
516
518 void eraseZeros(size_t minsize);
519
531
533 size_t readQuick(void *buf, rose_addr_t startVa, size_t desired) const {
534 return at(startVa).limit(desired).require(READABLE).read((uint8_t*)buf).size();
535 }
536
549 std::string readString(rose_addr_t startVa, size_t desired, int(*validChar)(int)=NULL, int(*invalidChar)(int)=NULL,
550 unsigned requiredPerms=READABLE, unsigned prohibitedPerms=0, char terminator='\0') const;
551
557 template<typename U>
558 Sawyer::Optional<U> readUnsigned(rose_addr_t startVa) const {
559 U val = 0;
560 if (at(startVa).limit(sizeof val).read((uint8_t*)&val).size() != sizeof val)
561 return Sawyer::Nothing();
562 ByteOrder::convert((void*)&val, sizeof val, endianness_, ByteOrder::hostOrder());
563 return val;
564 }
565
571 Sawyer::Optional<uint64_t> readLongUnsinged(rose_addr_t startVa) const {
572 uint64_t val = 0;
573 if (at(startVa).limit(sizeof val).read((uint8_t*)&val).size() != sizeof val)
574 return Sawyer::Nothing();
575 ByteOrder::convert((void*)&val, sizeof val, endianness_, ByteOrder::hostOrder());
576 return val;
577 }
578
583 size_t writeUnsigned(uint32_t value, rose_addr_t startVa) {
584 return at(startVa).limit(sizeof(uint32_t)).write((const uint8_t*)(&value)).size();
585 }
586
591 size_t writeUnsigned(uint64_t value, rose_addr_t startVa) {
592 return at(startVa).limit(sizeof(uint64_t)).write((const uint8_t*)(&value)).size();
593 }
594
599
601 SgUnsignedCharList readVector(rose_addr_t startVa, size_t desired, unsigned requiredPerms=READABLE) const;
602
604 size_t writeQuick(const void *buf, rose_addr_t startVa, size_t desired) {
605 return at(startVa).limit(desired).require(WRITABLE).write((const uint8_t*)buf).size();
606 }
607
615 Sawyer::Optional<rose_addr_t> findAny(const Extent &limits, const std::vector<uint8_t> &bytesToFind,
616 unsigned requiredPerms=READABLE, unsigned prohibitedPerms=0) const;
617 Sawyer::Optional<rose_addr_t> findAny(const AddressInterval &limits, const std::vector<uint8_t> &bytesToFind,
618 unsigned requiredPerms=READABLE, unsigned prohibitedPerms=0) const;
626 Sawyer::Optional<rose_addr_t> findSequence(const AddressInterval &interval, const std::vector<uint8_t> &sequence) const;
627
631 void dump(FILE*, const char *prefix="") const;
632 void dump(std::ostream&, std::string prefix="") const;
633 void print(std::ostream &o, std::string prefix="") const { dump(o, prefix); }
634 void dump() const; // mostly for calling from within GDB or similar
652
654 static std::string segmentTitle(const Segment&);
655
656 friend std::ostream& operator<<(std::ostream&, const MemoryMap&);
657};
658
659} // namespace
660} // namespace
661
662// Register the types needed for serialization since some of them are derived from polymorphic class templates.
663#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
666BOOST_CLASS_EXPORT_KEY(Rose::BinaryAnalysis::MemoryMap::NullBuffer);
668#endif
669
670#endif
671#endif
A contiguous range of values.
Definition rangemap.h:50
Exception for MemoryMap operations.
Definition MemoryMap.h:198
MemoryMap::Ptr map
Map that caused the exception if available, null otherwise.
Definition MemoryMap.h:207
virtual std::string leader(std::string dflt="memory map problem") const
Leading part of the error message.
virtual std::string details(bool) const
Details emitted on following lines, indented two spaces.
An efficient mapping from an address space to stored data.
Definition MemoryMap.h:115
AddressInterval insertData(const std::string &locatorString)
Insert data into a memory map.
MemoryMapPtr Ptr
Reference counting pointer.
Definition MemoryMap.h:118
Sawyer::Optional< uint64_t > readLongUnsinged(rose_addr_t startVa) const
Read a long unsigned value.
Definition MemoryMap.h:571
ByteOrder::Endianness byteOrder() const
Property: Byte order.
Definition MemoryMap.h:285
static std::string segmentTitle(const Segment &)
Title of a segment when printing the map.
void dump(std::ostream &, std::string prefix="") const
Prints the contents of the map for debugging.
bool insertProcessMemory(int memFile, const AddressInterval &where, unsigned accessibility, std::string name)
Insert part of another process's memory into this memory map.
static std::vector< ProcessMapRecord > readProcessMap(pid_t)
Obtain the memory map information for a process.
static std::string insertDataDocumentation()
Documentation string for insertData.
SgUnsignedCharList readVector(rose_addr_t startVa, size_t desired, unsigned requiredPerms=READABLE) const
Read quickly into a vector.
static std::string adjustMapDocumentation()
Documentation string for adjustMap.
bool shrinkUnshare()
Shrink buffers and remove sharing.
size_t insertFile(const std::string &fileName, rose_addr_t va, InsertFileMapMode mode=MAP_PRIVATE, std::string segmentName="")
Insert file contents into memory map.
Sawyer::Optional< U > readUnsigned(rose_addr_t startVa) const
Read an unsigned value.
Definition MemoryMap.h:558
size_t writeUnsigned(uint32_t value, rose_addr_t startVa)
Write an unsigned value.
Definition MemoryMap.h:583
static Ptr instance()
Construct an empty memory map.
Definition MemoryMap.h:267
Sawyer::Optional< rose_addr_t > findAny(const AddressInterval &limits, const std::vector< uint8_t > &bytesToFind, unsigned requiredPerms=READABLE, unsigned prohibitedPerms=0) const
Search for any byte.
void name(const std::string &)
Property: Name.
InsertFileMapMode
Mapping mode for insertFile.
Definition MemoryMap.h:303
@ MAP_PRIVATE
File is mapped privately.
Definition MemoryMap.h:304
@ MAP_READWRITE
File is mapped with read and write permission.
Definition MemoryMap.h:306
@ MAP_RDONLY
File is mapped with read-only permission.
Definition MemoryMap.h:308
bool insertProcessPid(pid_t, const AddressInterval &where, unsigned accessibility, const std::string &name)
Insert part of another process's memory into this memory map.
Combinatorics::Hasher & hash(Combinatorics::Hasher &) const
Compute a hash of the entire memory contents.
void print(std::ostream &o, std::string prefix="") const
Prints the contents of the map for debugging.
Definition MemoryMap.h:633
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.
const std::string & name() const
Property: Name.
void eraseZeros(size_t minsize)
Erases regions of zero bytes that are executable and readable and at least minsize in size.
Ptr shallowCopy()
Create a new copy of the memory map.
Definition MemoryMap.h:274
void insertProcess(const std::string &locatorString)
Insert the memory of some other process into this memory map.
AddressIntervalSet linkTo(const MemoryMap::Ptr &source, const AddressIntervalSet &where, Clobber=Clobber::YES)
Insert part of another map by reference.
void insertProcess(pid_t pid, Attach::Boolean attach)
Insert the memory of some other process into this memory map.
static std::pair< Buffer::Ptr, std::string > copyFromFile(int fd, const AddressInterval &)
Copy part of a file into a buffer.
void dump() const
Prints the contents of the map for debugging.
size_t writeQuick(const void *buf, rose_addr_t startVa, size_t desired)
Write data from buffer.
Definition MemoryMap.h:604
AddressIntervalSet linkTo(const MemoryMap::Ptr &source, const AddressInterval &where, Clobber=Clobber::YES)
Insert part of another map by reference.
MemoryMap()
Constructs an empty memory map.
Definition MemoryMap.h:263
size_t writeUnsigned(uint64_t value, rose_addr_t startVa)
Write a long unsigned value.
Definition MemoryMap.h:591
size_t readQuick(void *buf, rose_addr_t startVa, size_t desired) const
Read data into buffer.
Definition MemoryMap.h:533
Sawyer::Optional< rose_addr_t > findSequence(const AddressInterval &interval, const std::vector< uint8_t > &sequence) const
Search for a byte sequence.
void byteOrder(ByteOrder::Endianness order)
Property: Byte order.
Definition MemoryMap.h:286
static std::string insertFileDocumentation()
Documentation string for insertFile.
void dump(FILE *, const char *prefix="") const
Prints the contents of the map for debugging.
static std::string insertProcessDocumentation()
Documentation string for insertProcess.
AddressInterval insertFile(const std::string &locatorString)
Insert file contents into memory map.
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.
Sawyer::Optional< uint8_t > readByte(rose_addr_t) const
Read a byte from memory.
void insertProcessPid(pid_t, const std::vector< ProcessMapRecord > &)
Insert part of another process's memory into this memory map.
void adjustMap(const std::string &locatorString)
Adjusts a memory map according to the locator string.
Clobber
Overwrite (parts of) existing segments?
Definition MemoryMap.h:141
MemoryMap::Ptr align(rose_addr_t lowAlignment, rose_addr_t highAlignment) const
Create a new map by padding and aligning segments.
Base class for all ROSE exceptions.
Constraints are used to select addresses from a memory map.
Definition AddressMap.h:76
A mapping from address space to values.
Sawyer::Container::Interval< Address > read(Value *buf, const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Reads data into the supplied buffer.
AddressMapConstraints< const AddressMap > at(Address x) const
Constraint: anchor point.
AddressMapConstraints< const AddressMap > limit(size_t x) const
Constraint: limit matched size.
Allocates memory as needed.
Base class for all buffers.
Definition Buffer.h:23
Interval::Value size() const
Returns the number of values represented by this container.
Buffer that has no data.
Definition NullBuffer.h:22
Base class for testing segment constraints.
Definition AddressMap.h:55
Points to static data.
Represents no value.
Definition Optional.h:36
Holds a value or nothing.
Definition Optional.h:56
Base class for reference counted objects.
void convert(void *bytes, size_t nbytes, Endianness from, Endianness to)
Convert data from one byte order to another in place.
Endianness hostOrder()
Byte order of host machine.
Sawyer::SharedPointer< MemoryMap > MemoryMapPtr
Reference counting pointer.
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:40
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:53
The ROSE library.
Attach with ptrace first when reading a process?
Definition MemoryMap.h:133
@ YES
Attach with ptrace, get memory, then detach.
Definition MemoryMap.h:136
@ NO
Assume ptrace is attached and process is stopped.
Definition MemoryMap.h:135
Exception for an inconsistent mapping.
Definition MemoryMap.h:214
Exception thrown by find_free() when there's not enough free space left.
Definition MemoryMap.h:239
Exception for when we try to access a virtual address that isn't mapped.
Definition MemoryMap.h:229
Information about a process map.
Definition MemoryMap.h:441
std::string deviceName
Starting byte offset in the file.
Definition MemoryMap.h:445
std::string comment
Inode on the device, or zero.
Definition MemoryMap.h:447
unsigned accessibility
Mapped virtual addresses.
Definition MemoryMap.h:443
size_t inode
The device from which the data is mapped, or "00:00".
Definition MemoryMap.h:446
rose_addr_t fileOffset
The accessibility flags.
Definition MemoryMap.h:444
Exception thrown by load() when there's a syntax error in the index file.
Definition MemoryMap.h:249
unsigned linenum
Line number (1 origin) where error occurred.
Definition MemoryMap.h:257
int colnum
Optional column number (0-origin; negative if unknown).
Definition MemoryMap.h:258
std::string filename
Name of index file where error occurred.
Definition MemoryMap.h:256