1#ifndef ROSE_BinaryAnalysis_MemoryMap_H
2#define ROSE_BinaryAnalysis_MemoryMap_H
3#include <featureTests.h>
4#ifdef ROSE_ENABLE_BINARY_ANALYSIS
6#include <Rose/BinaryAnalysis/AddressIntervalSet.h>
7#include <Rose/BinaryAnalysis/BasicTypes.h>
8#include <Rose/BinaryAnalysis/ByteOrder.h>
9#include <Rose/Exception.h>
11#include <Combinatorics.h>
12#include <rose_extent.h>
13#include <sageContainer.h>
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>
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>
31namespace BinaryAnalysis {
38template<
typename T,
typename U>
39typename boost::enable_if_c<boost::is_integral<T>::value && boost::is_integral<U>::value, T>::type
41 ASSERT_require(alignment > 0);
42 T almt =
static_cast<T
>(alignment);
43 return ((address + almt - 1) / almt) * almt;
51template<
typename T,
typename U>
52typename boost::enable_if_c<boost::is_integral<T>::value && boost::is_integral<U>::value, T>::type
54 ASSERT_require(alignment > 0);
55 T almt =
static_cast<T
>(alignment);
56 return (address / almt) * almt;
120 typedef rose_addr_t Address;
121 typedef uint8_t Value;
147#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
149 friend class boost::serialization::access;
152 void serialize(S &s,
const unsigned ) {
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_);
165# if defined(READABLE) || defined(WRITABLE) || defined(EXECUTABLE) || defined(IMMUTABLE) || defined(PRIVATE)
167# pragma message("Undefining common words from the global namespace: READABLE, WRITABLE, EXECUTABLE, IMMUTABLE, PRIVATE")
169# warning "Undefining common words from the global namespace: READABLE, WRITABLE, EXECUTABLE, IMMUTABLE, PRIVATE"
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;
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;
193 static const unsigned RESERVED_ACCESS_BITS = 0x0000ffff;
202 virtual std::string
leader(std::string dflt=
"memory map problem")
const;
204 virtual void print(std::ostream&,
bool verbose=
true)
const;
205 friend std::ostream& operator<<(std::ostream&,
const Exception&);
219 new_range(new_range), old_range(old_range),
220 new_segment(new_segment), old_segment(old_segment) {}
222 virtual void print(std::ostream&,
bool verbose=
true)
const;
223 friend std::ostream& operator<<(std::ostream&,
const Inconsistent&);
225 Segment new_segment, old_segment;
233 virtual void print(std::ostream&,
bool verbose=
true)
const;
234 friend std::ostream& operator<<(std::ostream&,
const NotMapped&);
243 virtual void print(std::ostream&,
bool verbose=
true)
const;
244 friend std::ostream& operator<<(std::ostream&,
const NoFreeSpace&);
254 virtual void print(std::ostream&,
bool verbose=
true)
const;
255 friend std::ostream& operator<<(std::ostream&,
const SyntaxError&);
263 MemoryMap(): endianness_(ByteOrder::ORDER_UNSPECIFIED) {}
294 const std::string&
name()
const;
317 std::string segmentName =
"");
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();
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;
560 if (
at(startVa).
limit(
sizeof val).
read((uint8_t*)&val).
size() !=
sizeof val)
573 if (
at(startVa).
limit(
sizeof val).
read((uint8_t*)&val).
size() !=
sizeof val)
584 return at(startVa).limit(
sizeof(uint32_t)).write((
const uint8_t*)(&value)).size();
592 return at(startVa).limit(
sizeof(uint64_t)).write((
const uint8_t*)(&value)).size();
601 SgUnsignedCharList
readVector(rose_addr_t startVa,
size_t desired,
unsigned requiredPerms=READABLE)
const;
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();
616 unsigned requiredPerms=READABLE,
unsigned prohibitedPerms=0)
const;
618 unsigned requiredPerms=READABLE,
unsigned prohibitedPerms=0)
const;
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); }
656 friend std::ostream& operator<<(std::ostream&,
const MemoryMap&);
663#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
A contiguous range of values.
Exception for MemoryMap operations.
MemoryMap::Ptr map
Map that caused the exception if available, null otherwise.
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.
AddressInterval insertData(const std::string &locatorString)
Insert data into a memory map.
MemoryMapPtr Ptr
Reference counting pointer.
Sawyer::Optional< uint64_t > readLongUnsinged(rose_addr_t startVa) const
Read a long unsigned value.
ByteOrder::Endianness byteOrder() const
Property: Byte order.
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.
size_t writeUnsigned(uint32_t value, rose_addr_t startVa)
Write an unsigned value.
static Ptr instance()
Construct an empty memory map.
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.
@ MAP_PRIVATE
File is mapped privately.
@ MAP_READWRITE
File is mapped with read and write permission.
@ MAP_RDONLY
File is mapped with read-only permission.
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.
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.
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.
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.
size_t writeUnsigned(uint64_t value, rose_addr_t startVa)
Write a long unsigned value.
size_t readQuick(void *buf, rose_addr_t startVa, size_t desired) const
Read data into buffer.
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.
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?
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.
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.
Interval::Value size() const
Returns the number of values represented by this container.
Base class for testing segment constraints.
Holds a value or nothing.
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.
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.
Attach with ptrace first when reading a process?
@ YES
Attach with ptrace, get memory, then detach.
@ NO
Assume ptrace is attached and process is stopped.
Exception for an inconsistent mapping.
Exception thrown by find_free() when there's not enough free space left.
Exception for when we try to access a virtual address that isn't mapped.
Information about a process map.
std::string deviceName
Starting byte offset in the file.
std::string comment
Inode on the device, or zero.
unsigned accessibility
Mapped virtual addresses.
size_t inode
The device from which the data is mapped, or "00:00".
ProcessMapRecord()
Optional comment.
rose_addr_t fileOffset
The accessibility flags.
Exception thrown by load() when there's a syntax error in the index file.
unsigned linenum
Line number (1 origin) where error occurred.
int colnum
Optional column number (0-origin; negative if unknown).
std::string filename
Name of index file where error occurred.