ROSE 0.11.145.147
|
Base class for loading a static or dynamic object.
The BinaryLoader class is the base class that defines the public interface and provides generic implementations for loading a static or dynamic object. "Loading" means parsing, linking, mapping, and relocating, which are defined as follows:
Some goals of this design are:
The general design is similar to the Disassembler::Base class. The BinaryLoader has class methods to register user-defined loaders with the library and each loader is able to answer whether it is capable of loading a particular kind of binary. ROSE (or any user of this class) can obtain a suitable loader for a particular SgAsmInterpretation, clone it (if desired), modify properties that control its behavior, and use it to load a binary.
Definition at line 57 of file BinaryLoader.h.
#include <Rose/BinaryAnalysis/BinaryLoader.h>
Classes | |
class | Exception |
Base class for exceptions thrown by loaders. More... | |
Public Types | |
enum | MappingContribution { CONTRIBUTE_NONE , CONTRIBUTE_ADD , CONTRIBUTE_SUB } |
Describes how a section contributes to the overall memory map. More... | |
enum | ConflictResolution { RESOLVE_THROW , RESOLVE_OVERMAP , RESOLVE_REMAP , RESOLVE_REMAP_ABOVE } |
Describes how conflicts are resolved when mapping a section. More... | |
using | Ptr = BinaryLoaderPtr |
Referenc counting pointer to BinaryLoader. | |
typedef std::vector< Exception > | FixupErrors |
Public Member Functions | |
virtual Ptr | clone () const |
Creates a new copy of a loader. | |
virtual bool | canLoad (SgAsmGenericHeader *) const |
Predicate determining the suitability of a loader for a specific file header. | |
void | appendDirectories (const std::vector< std::string > &dirnames) |
Appends directories to the list of directories searched for libraries. | |
virtual std::string | findSoFile (const std::string &libname) const |
Convert name to fully qualified name. | |
virtual void | load (SgAsmInterpretation *) |
Top-level method to do everything. | |
virtual void | link (SgAsmInterpretation *interp) |
Finds and parses all shared objects needed by an interpretation. | |
virtual void | remap (SgAsmInterpretation *interp) |
Maps sections of the interpretation into the virtual address space. | |
virtual void | fixup (SgAsmInterpretation *interp, FixupErrors *errors=NULL) |
Performs relocation fixups on the specified interpretation. | |
virtual std::vector< std::string > | dependencies (SgAsmGenericHeader *) |
Finds shared object dependencies of a single binary header. | |
virtual void | remap (Rose::BinaryAnalysis::MemoryMap::Ptr &, SgAsmGenericHeader *) |
Remaps the sections for a particular header. | |
virtual SgAsmGenericSectionPtrList | getRemapSections (SgAsmGenericHeader *header) |
Selects those sections of a header that should be mapped. | |
virtual rose_addr_t | rebase (const MemoryMap::Ptr &, SgAsmGenericHeader *header, const SgAsmGenericSectionPtrList &) |
Returns an alternate base virtual address if necessary for remapping. | |
rose_addr_t | bialign (rose_addr_t val1, rose_addr_t align1, rose_addr_t val2, rose_addr_t align2) |
Calculate adjustment to cause two values to be aligned to two different alignments. | |
virtual MappingContribution | alignValues (SgAsmGenericSection *, const MemoryMap::Ptr &, rose_addr_t *malign_lo, rose_addr_t *malign_hi, rose_addr_t *va, rose_addr_t *mem_size, rose_addr_t *offset, rose_addr_t *file_size, bool *map_private, rose_addr_t *va_offset, bool *anon_lo, bool *anon_hi, ConflictResolution *resolve) |
For a given section, return information about how the section contributes to the memory map. | |
virtual void | addSectionsForRemap (SgAsmGenericHeader *header, SgAsmGenericSectionPtrList &allSections) |
Selects loadable sections. | |
virtual unsigned | mappingPermissions (SgAsmGenericSection *) const |
MemoryMap permissions. | |
bool | performingDynamicLinking () const |
Property: Whether this loader will perform the linking step. | |
void | performingDynamicLinking (bool b) |
Property: Whether this loader will perform the linking step. | |
bool | performingRemap () const |
Property: Whether this loader will perform the mapping step. | |
void | performingRemap (bool b) |
Property: Whether this loader will perform the mapping step. | |
bool | performingRelocations () const |
Property: Whether this loader will perform the relocation step. | |
void | performingRelocations (bool b) |
Property: Whether this loader will perform the relocation step. | |
const std::vector< std::string > & | preloads () const |
Property: List of libraries that will be pre-loaded. | |
std::vector< std::string > & | preloads () |
Property: List of libraries that will be pre-loaded. | |
void | preloads (const std::vector< std::string > &v) |
Property: List of libraries that will be pre-loaded. | |
const std::vector< std::string > & | directories () const |
Property: List of directories searched for libraries. | |
std::vector< std::string > & | directories () |
Property: List of directories searched for libraries. | |
void | directories (const std::vector< std::string > &v) |
Property: List of directories searched for libraries. | |
virtual bool | isLinked (SgBinaryComposite *composite, const std::string &filename) |
Returns true if the specified file name is already linked into the AST. | |
virtual bool | isLinked (SgAsmInterpretation *interp, const std::string &filename) |
Returns true if the specified file name is already linked into the AST. | |
Public Member Functions inherited from Sawyer::SharedObject | |
SharedObject () | |
Default constructor. | |
SharedObject (const SharedObject &) | |
Copy constructor. | |
virtual | ~SharedObject () |
Virtual destructor. | |
SharedObject & | operator= (const SharedObject &) |
Assignment. | |
Static Public Member Functions | |
static Ptr | instance () |
Allocating constructor. | |
static void | initDiagnostics () |
Initialize diagnostic streams for binary loaders. | |
static void | registerSubclass (const Ptr &) |
Register a loader instance. | |
static Ptr | lookup (SgAsmGenericHeader *) |
Finds a suitable loader. | |
static Ptr | lookup (SgAsmInterpretation *) |
Finds a suitable loader. | |
static void | load (SgBinaryComposite *composite, bool read_executable_file_format_only=false) |
Top-level method to do everything. | |
static SgAsmGenericFile * | createAsmAST (SgBinaryComposite *composite, std::string filePath) |
Parses a single binary file. | |
static int64_t | gcd (int64_t a, int64_t b, int64_t *x=NULL, int64_t *y=NULL) |
Extended Euclid Algorithm. | |
static SgAsmGenericHeaderPtrList | findSimilarHeaders (SgAsmGenericHeader *matchHeader, SgAsmGenericHeaderPtrList &candidateHeaders) |
Find headers similar to given header. | |
static bool | isHeaderSimilar (SgAsmGenericHeader *, SgAsmGenericHeader *) |
Determines whether two headers are similar. | |
Static Public Attributes | |
static Sawyer::Message::Facility | mlog |
Logging facility initialized by initDiagnostics(). | |
Protected Member Functions | |
BinaryLoader (const BinaryLoader &other) | |
Copy constructor. | |
Referenc counting pointer to BinaryLoader.
Definition at line 63 of file BinaryLoader.h.
typedef std::vector<Exception> Rose::BinaryAnalysis::BinaryLoader::FixupErrors |
Definition at line 327 of file BinaryLoader.h.
Describes how a section contributes to the overall memory map.
Enumerator | |
---|---|
CONTRIBUTE_NONE | Section does not contribute to final mapping. |
CONTRIBUTE_ADD | Section is added to the mapping. |
CONTRIBUTE_SUB | Section is subtracted from the mapping. |
Definition at line 66 of file BinaryLoader.h.
Describes how conflicts are resolved when mapping a section.
Enumerator | |
---|---|
RESOLVE_THROW | Throw an exception such as MemoryMap::Inconsistent. |
RESOLVE_OVERMAP | Free the part of the original mapping that is in conflict. |
RESOLVE_REMAP | Move the section to any unused part of the address space. |
RESOLVE_REMAP_ABOVE | Move the section to a higher unused part of the address space. |
Definition at line 74 of file BinaryLoader.h.
|
inlineprotected |
Definition at line 112 of file BinaryLoader.h.
|
inlineprotected |
Copy constructor.
Definition at line 117 of file BinaryLoader.h.
|
inlinevirtual |
Definition at line 125 of file BinaryLoader.h.
|
inlinestatic |
Allocating constructor.
Definition at line 128 of file BinaryLoader.h.
|
inlinevirtual |
Creates a new copy of a loader.
The new copy has all the same settings as the original. Subclasses that define data methods should certainly provide an implementation of this method, although all they'll need to change is the data type for the 'new' operator.
Reimplemented in Rose::BinaryAnalysis::BinaryLoaderElf, Rose::BinaryAnalysis::BinaryLoaderElfObj, and Rose::BinaryAnalysis::BinaryLoaderPe.
Definition at line 136 of file BinaryLoader.h.
|
static |
Register a loader instance.
More specific loader instances should be registered after more general loaders since the lookup() method will inspect loaders in reverse order of their registration.
|
inlinevirtual |
Predicate determining the suitability of a loader for a specific file header.
If this loader is capable of loading the specified file header, then this predicate returns true, otherwise it returns false. The implementation in BinaryLoader always returns true because BinaryLoader is able to generically load all types of files, albeit with limited functionality. Subclasses should certainly redefine this method so it returns true only for certain headers.
Reimplemented in Rose::BinaryAnalysis::BinaryLoaderElf, Rose::BinaryAnalysis::BinaryLoaderElfObj, and Rose::BinaryAnalysis::BinaryLoaderPe.
Definition at line 165 of file BinaryLoader.h.
|
static |
Finds a suitable loader.
Looks through the list of registered loader instances (from most recently registered to earliest registered) and returns the first one whose can_load() predicate returns true. Throws an exception if no suitable loader can be found.
|
static |
Finds a suitable loader.
Looks through the list of registered loader instances (from most recently registered to earliest registered) and returns the first one whose can_load() predicate returns true. This is done for each header contained in the interpretation and the loader for each header must match the other headers. An exception is thrown if no suitable loader can be found.
|
inline |
Property: Whether this loader will perform the linking step.
To "link" means to recursively determine what shared objects are dependencies of the objects already in the AST and to parse them, adding them to the AST also.
Definition at line 196 of file BinaryLoader.h.
|
inline |
Property: Whether this loader will perform the linking step.
To "link" means to recursively determine what shared objects are dependencies of the objects already in the AST and to parse them, adding them to the AST also.
Definition at line 197 of file BinaryLoader.h.
|
inline |
Property: Whether this loader will perform the mapping step.
To "map" a section means to make the section's content available through a MemoryMap object attached to the interpretation that holds the section. This step also resolves conflicts between two or more sections that request overlapping areas of memory.
Definition at line 207 of file BinaryLoader.h.
|
inline |
Property: Whether this loader will perform the mapping step.
To "map" a section means to make the section's content available through a MemoryMap object attached to the interpretation that holds the section. This step also resolves conflicts between two or more sections that request overlapping areas of memory.
Definition at line 208 of file BinaryLoader.h.
|
inline |
Property: Whether this loader will perform the relocation step.
To "relocate" means to process the relocation sections of an executable and apply "fixups" to parts of memory that have been mapped. The fixups are computed based on the original contents of that memory and the difference in locations from the section's preferred memory location and the location chosen by this loader during the mapping phase. There are many kinds of relocation fixups.
Definition at line 219 of file BinaryLoader.h.
|
inline |
Property: Whether this loader will perform the relocation step.
To "relocate" means to process the relocation sections of an executable and apply "fixups" to parts of memory that have been mapped. The fixups are computed based on the original contents of that memory and the difference in locations from the section's preferred memory location and the location chosen by this loader during the mapping phase. There are many kinds of relocation fixups.
Definition at line 220 of file BinaryLoader.h.
|
inline |
Property: List of libraries that will be pre-loaded.
These libraries are linked into the AST in the order they were added to the preload list. The libname
should be either the base name of a library, such as "libm.so" (in which case the search directories are consulted) or a path-qualified name like "/usr/lib/libm.so".
Definition at line 237 of file BinaryLoader.h.
|
inline |
Property: List of libraries that will be pre-loaded.
These libraries are linked into the AST in the order they were added to the preload list. The libname
should be either the base name of a library, such as "libm.so" (in which case the search directories are consulted) or a path-qualified name like "/usr/lib/libm.so".
Definition at line 238 of file BinaryLoader.h.
|
inline |
Property: List of libraries that will be pre-loaded.
These libraries are linked into the AST in the order they were added to the preload list. The libname
should be either the base name of a library, such as "libm.so" (in which case the search directories are consulted) or a path-qualified name like "/usr/lib/libm.so".
Definition at line 239 of file BinaryLoader.h.
|
inline |
Property: List of directories searched for libraries.
This is similar to the LD_LIBRARY_PATH environment variable of the ld-linux.so dynamic loader (see the ld.so man page). ROSE searches for libraries in directories in the order that directories were added.
Definition at line 248 of file BinaryLoader.h.
|
inline |
Property: List of directories searched for libraries.
This is similar to the LD_LIBRARY_PATH environment variable of the ld-linux.so dynamic loader (see the ld.so man page). ROSE searches for libraries in directories in the order that directories were added.
Definition at line 249 of file BinaryLoader.h.
|
inline |
Property: List of directories searched for libraries.
This is similar to the LD_LIBRARY_PATH environment variable of the ld-linux.so dynamic loader (see the ld.so man page). ROSE searches for libraries in directories in the order that directories were added.
Definition at line 250 of file BinaryLoader.h.
|
inline |
Appends directories to the list of directories searched for libraries.
This is similar to the LD_LIBRARY_PATH environment variable of the ld-linux.so dynamic loader (see the ld.so man page). ROSE searches for libraries in directories in the order that directories were added.
Definition at line 257 of file BinaryLoader.h.
|
virtual |
Convert name to fully qualified name.
Given the name of a shared object, return the fully qualified name where the library is located in the file system. Throws a BinaryLoader::Exception if the library cannot be found.
Reimplemented in Rose::BinaryAnalysis::BinaryLoaderPe.
|
static |
Top-level method to do everything.
Class method to parse, map, link, and/or relocate all interpretations of the specified binary composite. This should only be called for an SgBinaryComposite object that has been created but for which no binary files have been parsed yet. It's only called from sage_support.C by SgBinaryComposite::buildAST(). A BinaryLoader::Exception is thrown if there's an error of some sort.
|
virtual |
Top-level method to do everything.
Conditionally parse, map, link, and/or relocate the interpretation according to properties of this loader. If an error occurs, a BinaryLoader::Exception will be thrown. The interpretation must be one that can be loaded by this loader as returned by this loader's can_load() method.
|
virtual |
Finds and parses all shared objects needed by an interpretation.
Links an interpretation by parsing all shared objects required by that interpretation. In other words, all dependencies of the interpretation are parsed and added to the AST. As mentioned in the BinaryLoader documentation, this process is referred to as "linking".
Recursively perform a breadth-first search of all headers, starting with the headers already in the interpretation. For each header, obtain a list of necessary shared objects (pruning away those that have already been processed) and parse the shared object, adding it to the AST and adding its appropriate headers to the interpretation. Parsing of the shared objects is performed by calling createAsmAST().
This process is recursive in nature. A dynamically linked executable has a list of libraries on which it depends, and those libraries also often have dependencies. The recursion is breadth-first because ELF specifies a particular order that symbols should be resolved. Order is not important for a PE binary since its shared object symbols are scoped to a library.
The list of dependencies for a particular header is obtained by the getDLLs() method, which is also responsible for not returning any shared object that we've already parsed.
Throws a BinaryLoader::Exception if any error occurs.
Reimplemented in Rose::BinaryAnalysis::BinaryLoaderPe.
|
virtual |
Maps sections of the interpretation into the virtual address space.
This function uses the existing MemoryMap attached to the interpretation if it is available, or creates and attaches a new, empty MemoryMap. When using an existing MemoryMap, the map is not cleared. This enables the caller to reserve space in memory.
The mapping algorithms consult each section's preferred address (SgAsmGenericSection::get_mapped_preferred_rva()) and update the section's actual address (SgAsmGenericSection::get_mapped_actual_rva()), adjusting the interpretation's MemoryMap in the process. The algorithms are applied to one binary file header at a time in the order the headers appear in the interpretation. The algorithms may control the order that sections are mapped within any given header.
Subclasses normally don't override this method, but rather the remap() method that is called by this method, namely the remap() that takes a memory map and file header as arguments.
This method throws a BinaryLoader::Exception if an error occurs.
|
virtual |
Performs relocation fixups on the specified interpretation.
This should be called after sections are mapped into memory by remap(). If an error occurs, then this function either throws the error (BinaryLoader::Exception) or appends it to the errors
container (if errors
is non-null).
Reimplemented in Rose::BinaryAnalysis::BinaryLoaderElf, and Rose::BinaryAnalysis::BinaryLoaderPe.
|
virtual |
Returns true if the specified file name is already linked into the AST.
Reimplemented in Rose::BinaryAnalysis::BinaryLoaderPe.
|
virtual |
Returns true if the specified file name is already linked into the AST.
Reimplemented in Rose::BinaryAnalysis::BinaryLoaderPe.
|
static |
Parses a single binary file.
The file may be an executable, core dump, or shared library. The machine instructions in the file are not parsed–only the binary container is parsed. The new SgAsmGenericFile is added to the supplied binary composite
and a new interpretation is created if necessary. Dwarf debugging information is also parsed and added to the AST if Dwarf support is enable and the information is present in the binary container.
|
virtual |
Finds shared object dependencies of a single binary header.
Returns a list of dependencies, which are usually library names rather than actual files. The library names can be turned into file names by calling find_so_file(). Only one header is inspected (i.e., this function is not recursive) and no attempt is made to remove names from the return value that have already been parsed into the AST.
|
virtual |
Remaps the sections for a particular header.
This method is often replaced by subclasses since this is where decisions are made about alignment. Different operating systems and their loaders have different alignment policies.
|
inlinevirtual |
Selects those sections of a header that should be mapped.
Returns the sections in the order they should be mapped.
Reimplemented in Rose::BinaryAnalysis::BinaryLoaderElf, Rose::BinaryAnalysis::BinaryLoaderElfObj, and Rose::BinaryAnalysis::BinaryLoaderPe.
Definition at line 370 of file BinaryLoader.h.
References SgAsmGenericHeader::get_mappedSections().
|
inlinevirtual |
Returns an alternate base virtual address if necessary for remapping.
For instance, when mapping multiple ELF files, each file should be mapped above a particular address that doesn't conflict with anything that's already mapped. If a new base address is returned, then the remapper will temporarily adjust the base address of the file header for the duration of the mapping operation. The default is to return the current base address.
This method is called with a memory map that describes what has been mapped so far, a file header for the sections that are about to be mapped, and a list of sections about to be mapped.
Reimplemented in Rose::BinaryAnalysis::BinaryLoaderElf, and Rose::BinaryAnalysis::BinaryLoaderPe.
Definition at line 383 of file BinaryLoader.h.
References SgAsmGenericHeader::get_baseVa().
|
static |
Extended Euclid Algorithm.
The Euclid algorithm for finding the greatest common divisor (GCD) of two natural numbers, extended to also compute a solution to Bezout's Identity. Bezout's Identity states that if a
and b
are two non-zero integers with greatest common divisor d
, then there exist integers x
and y
(called Bezout Coefficients), such that . Additionally d
is the smallest positive integer for which there are integer solutions to the preceding equation.
The returned value is the greatest common divisor of a
and b
. If the caller supplies non-null pointers for x
and y
then a pair of Bezout Coefficients are returned through those pointers.
rose_addr_t Rose::BinaryAnalysis::BinaryLoader::bialign | ( | rose_addr_t | val1, |
rose_addr_t | align1, | ||
rose_addr_t | val2, | ||
rose_addr_t | align2 | ||
) |
Calculate adjustment to cause two values to be aligned to two different alignments.
Given two values and two alignments, return the smallest integer adjustment such that subtracting the adjustment from both values results in each value satisfying its alignment constraint.
Note that it is not always possible to find an adjustment. When no adjustment can be found an Exception is thrown.
|
virtual |
For a given section, return information about how the section contributes to the memory map.
The algorithm may use information from the section itself and the memory map as defined up to this point in the mapping process. The main return value is an indication of whether the section adds to the map, subtracts from the map, or does nothing to the map. The remaining arguments are grouped according to their purpose:
malign_lo
and malign_hi
indicate how the section must be aligned in memory. In particular, the va
return value will be a multiple of malign_lo
, and the sum of va
and mem_size
will be a multiple of malign_hi
. va
value is the low virtual address of the new mapping, and the mem_size
is the number of bytes to map. offset
value is the byte offset from the beginning of the file in which this section appears, and the file_size
is the number of bytes to map from the file into memory. The file_size
may be smaller than the mem_size
(see below). va_offset
is the offset of the section with respect to va
(it must be non-negative). The boolean return values anon_lo
and anon_hi
determine whether ROSE will map file contents (false) or zeros (true) below and above the section when the section is smaller than the mapped region. Zeros are always used for areas that are beyond the end of the file. resolve
result indicates what should happen. Subclasses often override this method since each operating system tends to have unique rules about how things are mapped and how conflicts are resolved.
If so desired, the conflict resolution may be handled by the align_values() method itself since the memory map is available there. However, a benefit of allowing a higher layer to resolve the conflict is that diagnostics will be produced automatically when debugging is enabled.
Likewise, this method is allowed to perform the mapping itself if the algorithm in the caller, remap(), cannot be sufficiently influenced by the values that are returned. In this case, this method should perform the mapping and return CONTRIB_NONE to prevent the caller from doing any further mapping.
Reimplemented in Rose::BinaryAnalysis::BinaryLoaderElf, Rose::BinaryAnalysis::BinaryLoaderElfObj, and Rose::BinaryAnalysis::BinaryLoaderPe.
|
virtual |
Selects loadable sections.
Selects those sections which should be layed out by the Loader and inserts them into the allSections
argument. The default implementation (in this base class) is to add all sections to the list. Subclasses will likely restrict this to a subset of sections.
|
static |
Find headers similar to given header.
Find all headers in candidateHeaders
that are similar to matchHeader
.
This is used to determine whether two headers can be placed in the same SgAsmInterpretation. In order to be similar the headers must be of the same class and belong to the same architecture. In other words, an x86_64 header will not be similar to an i386 header even though they are both ELF headers and both x86 architectures.
|
static |
Determines whether two headers are similar.
Determines whether two headers are similar enough to be in the same interpretation. Two headers are similar if disassembly would use the same Disassembler::Base for both. See findSimilarHeaders().
|
virtual |
MemoryMap permissions.
Returns the permissions that should be used when mapping the specified section into memory. The default implementation in the base class uses the access permissions stored in the section. Subclasses can override this method to provide other permissions without resorting to changing the AST (which would be misleading for other analysis).
Reimplemented in Rose::BinaryAnalysis::BinaryLoaderElfObj.
|
static |
Logging facility initialized by initDiagnostics().
Definition at line 98 of file BinaryLoader.h.