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/type_traits/is_integral.hpp>
27#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
28#include <boost/serialization/access.hpp>
29#include <boost/serialization/base_object.hpp>
30#include <boost/serialization/export.hpp>
35namespace BinaryAnalysis {
42template<
typename T,
typename U>
43typename boost::enable_if_c<boost::is_integral<T>::value && boost::is_integral<U>::value, T>::type
45 ASSERT_require(alignment > 0);
46 T almt =
static_cast<T
>(alignment);
47 return ((address + almt - 1) / almt) * almt;
55template<
typename T,
typename U>
56typename boost::enable_if_c<boost::is_integral<T>::value && boost::is_integral<U>::value, T>::type
58 ASSERT_require(alignment > 0);
59 T almt =
static_cast<T
>(alignment);
60 return (address / almt) * almt;
124 typedef uint8_t Value;
150#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
152 friend class boost::serialization::access;
155 void serialize(S &s,
const unsigned ) {
156 s.template register_type<AllocatingBuffer>();
157 s.template register_type<MappedBuffer>();
158 s.template register_type<NullBuffer>();
159 s.template register_type<StaticBuffer>();
160 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
161 s & BOOST_SERIALIZATION_NVP(endianness_);
168# if defined(READABLE) || defined(WRITABLE) || defined(EXECUTABLE) || defined(IMMUTABLE) || defined(PRIVATE)
170# pragma message("Undefining common words from the global namespace: READABLE, WRITABLE, EXECUTABLE, IMMUTABLE, PRIVATE")
172# warning "Undefining common words from the global namespace: READABLE, WRITABLE, EXECUTABLE, IMMUTABLE, PRIVATE"
182 static const unsigned NO_ACCESS = 0;
183 static const unsigned READABLE = Sawyer::Access::READABLE;
184 static const unsigned WRITABLE = Sawyer::Access::WRITABLE;
185 static const unsigned EXECUTABLE = Sawyer::Access::EXECUTABLE;
186 static const unsigned IMMUTABLE = Sawyer::Access::IMMUTABLE;
187 static const unsigned PRIVATE = Sawyer::Access::PRIVATE;
188 static const unsigned INITIALIZED = 0x00000200;
191 static const unsigned READ_WRITE = READABLE | WRITABLE;
192 static const unsigned READ_EXECUTE = READABLE | EXECUTABLE;
193 static const unsigned READ_WRITE_EXECUTE = READABLE | WRITABLE | EXECUTABLE;
196 static const unsigned RESERVED_ACCESS_BITS = 0x0000ffff;
205 virtual std::string
leader(std::string dflt=
"memory map problem")
const;
207 virtual void print(std::ostream&,
bool verbose=
true)
const;
208 friend std::ostream& operator<<(std::ostream&,
const Exception&);
222 new_range(new_range), old_range(old_range),
223 new_segment(new_segment), old_segment(old_segment) {}
225 virtual void print(std::ostream&,
bool verbose=
true)
const;
226 friend std::ostream& operator<<(std::ostream&,
const Inconsistent&);
228 Segment new_segment, old_segment;
236 virtual void print(std::ostream&,
bool verbose=
true)
const;
237 friend std::ostream& operator<<(std::ostream&,
const NotMapped&);
246 virtual void print(std::ostream&,
bool verbose=
true)
const;
247 friend std::ostream& operator<<(std::ostream&,
const NoFreeSpace&);
257 virtual void print(std::ostream&,
bool verbose=
true)
const;
258 friend std::ostream& operator<<(std::ostream&,
const SyntaxError&);
270 " error at " + std::string(7 + index,
'-') +
"^",
277 struct AddrSizePerm {
287 MemoryMap(): endianness_(ByteOrder::ORDER_UNSPECIFIED) {}
318 const std::string&
name()
const;
565 return at(startVa).limit(desired).require(READABLE).read((uint8_t*)buf).size();
580 std::string
readString(
Address startVa,
size_t desired,
int(*validChar)(
int)=NULL,
int(*invalidChar)(
int)=NULL,
581 unsigned requiredPerms=READABLE,
unsigned prohibitedPerms=0,
char terminator=
'\0')
const;
591 if (
at(startVa).
limit(
sizeof val).
read((uint8_t*)&val).
size() !=
sizeof val)
604 if (
at(startVa).
limit(
sizeof val).
read((uint8_t*)&val).
size() !=
sizeof val)
615 return at(startVa).limit(
sizeof(uint32_t)).write((
const uint8_t*)(&value)).size();
623 return at(startVa).limit(
sizeof(uint64_t)).write((
const uint8_t*)(&value)).size();
632 SgUnsignedCharList
readVector(
Address startVa,
size_t desired,
unsigned requiredPerms=READABLE)
const;
636 return at(startVa).limit(desired).require(WRITABLE).write((
const uint8_t*)buf).size();
647 unsigned requiredPerms=READABLE,
unsigned prohibitedPerms=0)
const;
649 unsigned requiredPerms=READABLE,
unsigned prohibitedPerms=0)
const;
662 void dump(FILE*,
const char *prefix=
"")
const;
663 void dump(std::ostream&, std::string prefix=
"")
const;
664 void print(std::ostream &o, std::string prefix=
"")
const {
dump(o, prefix); }
687 friend std::ostream& operator<<(std::ostream&,
const MemoryMap&);
702 static std::tuple<std::vector<std::tuple<std::string , std::string ,
size_t >>,
703 std::string ,
size_t >
711#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
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.
Exception thrown for an error in a locator string.
An efficient mapping from an address space to stored data.
AddressInterval insertData(const std::string &locatorString)
Insert data into a memory map.
size_t writeUnsigned(uint64_t value, Address startVa)
Write a long unsigned value.
MemoryMapPtr Ptr
Reference counting pointer.
MemoryMap::Ptr align(Address lowAlignment, Address highAlignment) const
Create a new map by padding and aligning segments.
ByteOrder::Endianness byteOrder() const
Property: Byte order.
Sawyer::Optional< Address > 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.
size_t readQuick(void *buf, Address startVa, size_t desired) const
Read data into buffer.
void dump(std::ostream &, std::string prefix="") const
Prints the contents of the map for debugging.
Sawyer::Optional< uint8_t > readByte(Address) const
Read a byte from memory.
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.
size_t writeQuick(const void *buf, Address startVa, size_t desired)
Write data from buffer.
static std::string insertDataDocumentation()
Documentation string for insertData.
static std::string adjustMapDocumentation()
Documentation string for adjustMap.
bool combineAdjacentSegments()
Combine adjacent segments.
bool shrinkUnshare()
Shrink buffers and remove sharing.
size_t insertFile(const std::string &fileName, Address va, InsertFileMapMode mode=MAP_PRIVATE, std::string segmentName="")
Insert file contents into memory map.
std::string readString(Address 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.
static Ptr instance()
Construct an empty memory map.
void name(const std::string &)
Property: Name.
static std::tuple< std::vector< std::tuple< std::string, std::string, size_t > >, std::string, size_t > parseNameValuePairs(const std::string &input)
Parse comma-separated name=value pairs.
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.
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.
Sawyer::Optional< U > readUnsigned(Address startVa) const
Read an unsigned value.
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.
AddressIntervalSet linkTo(const MemoryMap::Ptr &source, const AddressInterval &where, Clobber=Clobber::YES)
Insert part of another map by reference.
SgUnsignedCharList readVector(Address startVa, size_t desired, unsigned requiredPerms=READABLE) const
Read quickly into a vector.
Sawyer::Optional< Address > findSequence(const AddressInterval &interval, const std::vector< uint8_t > &sequence) const
Search for a byte sequence.
MemoryMap()
Constructs an empty memory map.
Sawyer::Optional< uint64_t > readLongUnsinged(Address startVa) const
Read a long unsigned value.
void byteOrder(ByteOrder::Endianness order)
Property: Byte order.
Sawyer::Optional< Address > findAny(const AddressInterval &limits, const std::vector< uint8_t > &bytesToFind, unsigned requiredPerms=READABLE, unsigned prohibitedPerms=0) const
Search for any byte.
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.
size_t writeUnsigned(uint32_t value, Address startVa)
Write an unsigned value.
static Sawyer::Result< AddrSizePerm, std::pair< std::string, size_t > > parseAddrSizePerm(const std::string &)
Parse input of the form "[ADDR][+SIZE][=[r][w][x]]".
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?
Base class for all ROSE exceptions.
Constraints are used to select addresses from a memory map.
A mapping from address space to values.
Address Address
Type for addresses.
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.
Result containing a value or an error.
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.
Address fileOffset
The accessibility flags.
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.
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.