|
The Pedigree Project 0.1
|
#include <Elf.h>
Inheritance diagram for Elf:
Collaboration diagram for Elf:Classes | |
| struct | Elf32SectionHeader_t |
| struct | Elf32Symbol_t |
| struct | ElfDyn_t |
| struct | ElfHash_t |
| struct | ElfHeader_t |
| struct | ElfProgramHeader_t |
| struct | ElfRel_t |
| struct | ElfRela_t |
| struct | ElfSectionHeader_t |
| struct | ElfSymbol_t |
| struct | ExecutableMetadata |
Public Types | |
| enum class | ExecutableValidationResult { Valid , Malformed , WrongArchitecture , UnsupportedType , UnsupportedLayout , MultipleInterpreters } |
Public Member Functions | |
| Elf () | |
| virtual | ~Elf () |
| Elf (const Elf &) | |
| bool | validate (uint8_t *pBuffer, size_t length) |
| bool | create (uint8_t *pBuffer, size_t length) |
| bool | createNeededOnly (uint8_t *pBuffer, size_t length) |
| bool | loadModule (uint8_t *pBuffer, size_t length, uintptr_t &loadBase, size_t &loadSize, SymbolTable *pSymbolTableCopy=0) |
| bool | finaliseModule (uint8_t *pBuffer, size_t length) |
| bool | allocate (uint8_t *pBuffer, size_t length, uintptr_t &loadBase, SymbolTable *pSymtab=0, bool bAllocate=true, size_t *pSize=0) |
| bool | load (uint8_t *pBuffer, size_t length, uintptr_t loadBase, SymbolTable *pSymtab=0, uintptr_t nStart=0, uintptr_t nEnd=~0, bool relocate=true, uintptr_t destinationBase=0) |
| List< char * > & | neededLibraries () |
| String & | getInterpreter () |
| uintptr_t | getLastAddress () |
| uintptr_t | getInitFunc () |
| uintptr_t | getFiniFunc () |
| template<class T = ElfSymbol_t> | |
| const char * | lookupSymbol (uintptr_t addr, uintptr_t *startAddr, T *symbolTable) |
| const char * | lookupSymbol (uintptr_t addr, uintptr_t *startAddr) |
| uintptr_t | lookupSymbol (const char *pName) |
| uintptr_t | lookupDynamicSymbolAddress (const char *str, uintptr_t loadBase) |
| uintptr_t | applySpecificRelocation (uintptr_t off, SymbolTable *pSymtab, uintptr_t loadBase, SymbolTable::Policy policy=SymbolTable::LocalFirst) |
| uintptr_t | getGlobalOffsetTable () |
| size_t | getPltSize () |
| void | populateSymbolTable (SymbolTable *pSymtab, uintptr_t loadBase) |
| void | preallocateSymbols (SymbolTable *pSymtabOverride=nullptr, SymbolTable *pAdditionalSymtab=nullptr) |
| SymbolTable * | getSymbolTable () |
| uintptr_t | getEntryPoint () |
| uintptr_t | debugFrameTable () |
| uintptr_t | debugFrameTableLength () |
| void | setName (const String &s) |
| const String & | getName () const |
Static Public Member Functions | |
| static ExecutableValidationResult | validateExecutableHeader (const uint8_t *pBuffer, size_t length, size_t fileSize, ExecutableMetadata &metadata) |
| static ExecutableValidationResult | validateExecutableProgramHeaders (const uint8_t *pBuffer, size_t length, size_t fileSize, ExecutableMetadata &metadata) |
| static ExecutableValidationResult | validateExecutableInterpreter (const uint8_t *pBuffer, size_t length, const ExecutableMetadata &metadata) |
| static bool | extractEntryPoint (uint8_t *pBuffer, size_t length, uintptr_t &entry) |
| static bool | extractInformation (uint8_t *pBuffer, size_t length, size_t &phdrCount, size_t &phdrEntrySize, uintptr_t &phdrAddress) |
Static Public Attributes | |
| static constexpr size_t | MaximumProgramHeaderTableSize = 65536 |
| static constexpr size_t | MaximumInterpreterSize = 4096 |
Private Member Functions | |
| bool | relocate (uint8_t *pBuffer, uintptr_t length) |
| bool | relocateModinfo (uint8_t *pBuffer, uintptr_t length) |
| bool | applyRelocation (ElfRel_t rel, ElfSectionHeader_t *pSh, SymbolTable *pSymtab=0, uintptr_t loadBase=0, SymbolTable::Policy policy=SymbolTable::LocalFirst, uintptr_t destinationAddress=0, uintptr_t destinationEnd=0) |
| bool | applyRelocation (ElfRela_t rela, ElfSectionHeader_t *pSh, SymbolTable *pSymtab=0, uintptr_t loadBase=0, SymbolTable::Policy policy=SymbolTable::LocalFirst, uintptr_t destinationAddress=0, uintptr_t destinationEnd=0) |
| void | rebaseDynamic () |
| Elf & | operator= (const Elf &) |
Static Private Member Functions | |
| template<typename T > | |
| static T * | elfCopy (uint8_t *, ElfProgramHeader_t *, size_t, T *, size_t) |
Friends | |
| class | PosixSubsystem |
| class | ModuleImage |
Provides an implementation of a 32-bit Executable and Linker format file parser. The ELF data can be loaded either by supplying an entire ELF file in a buffer, or by supplying details of each section seperately.
| Elf::Elf | ( | ) |
Default constructor - loads no data.
Definition at line 77 of file linker/Elf.cc.
|
virtual |
Destructor.
Definition at line 110 of file linker/Elf.cc.
| Elf::Elf | ( | const Elf & | elf | ) |
The copy-constructor
Definition at line 126 of file linker/Elf.cc.
References List< T, nodePoolSize >::begin(), SymbolTable::copyTable(), and List< T, nodePoolSize >::end().
| bool Elf::allocate | ( | uint8_t * | pBuffer, |
| size_t | length, | ||
| uintptr_t & | loadBase, | ||
| SymbolTable * | pSymtab = 0, |
||
| bool | bAllocate = true, |
||
| size_t * | pSize = 0 |
||
| ) |
Performs the prerequisite allocation for any normal ELF file - library or executable. For a library, this allocates loadBase, and allocates memory for the entire object - this is not filled however.
Definition at line 777 of file linker/Elf.cc.
References PhysicalMemoryManager::allocatePage(), VirtualAddressSpace::Execute, PhysicalMemoryManager::getPageSize(), Process::getParent(), Hex, ProcessorBase::information(), SymbolTable::insert(), SymbolTable::insertMultiple(), PhysicalMemoryManager::instance(), preallocateSymbols(), and VirtualAddressSpace::Write.
Referenced by loadModule(), DynamicLinker::loadObject(), and DynamicLinker::loadProgram().
Here is the caller graph for this function:
|
private |
Applies one relocation. This overload performs a relocation without addend (REL).
| rel | The relocation entry to apply. |
| pSh | A pointer to the section that the relocation entry refers to. |
| pSymtab | The symbol table to use for lookups. |
| loadBase | For a relocatable object, the address at which it is loaded. |
| policy | Lookup policy. |
Definition at line 19 of file core/processor/arm64/Elf.cc.
Referenced by applySpecificRelocation(), and load().
Here is the caller graph for this function:
|
private |
Applies one relocation. This overload performs a relocation with addend (RELA).
| rel | The relocation entry to apply. |
| pSh | A pointer to the section that the relocation entry refers to. |
| pSymtab | The symbol table to use for lookups. |
| loadBase | For a relocatable object, the address at which it is loaded. |
| policy | Lookup policy. |
Definition at line 25 of file core/processor/arm64/Elf.cc.
References Dec, KernelElf::instance(), SymbolTable::lookup(), and SymbolTable::NotOriginatingElf.
| uintptr_t Elf::applySpecificRelocation | ( | uintptr_t | off, |
| SymbolTable * | pSymtab, | ||
| uintptr_t | loadBase, | ||
| SymbolTable::Policy | policy = SymbolTable::LocalFirst |
||
| ) |
Applies the n'th relocation in the relocation table. Used by PLT entries.
Definition at line 1233 of file linker/Elf.cc.
References applyRelocation().
| bool Elf::create | ( | uint8_t * | pBuffer, |
| size_t | length | ||
| ) |
Constructs an Elf object, and assumes the given pointer to be to a contiguous region of memory containing an ELF object.
Definition at line 304 of file linker/Elf.cc.
References List< T, nodePoolSize >::begin(), elfCopy(), List< T, nodePoolSize >::end(), Hex, and List< T, nodePoolSize >::pushBack().
Referenced by DynamicLinker::loadObject(), and DynamicLinker::loadProgram().
Here is the caller graph for this function:| bool Elf::createNeededOnly | ( | uint8_t * | pBuffer, |
| size_t | length | ||
| ) |
Merely loads "needed libraries" and then returns success or failure.
Definition at line 203 of file linker/Elf.cc.
References List< T, nodePoolSize >::begin(), elfCopy(), EMIT_IF, List< T, nodePoolSize >::end(), Hex, and List< T, nodePoolSize >::pushBack().
Referenced by DynamicLinker::loadObject(), and DynamicLinker::loadProgram().
Here is the caller graph for this function:| uintptr_t Elf::debugFrameTable | ( | ) |
Definition at line 1259 of file linker/Elf.cc.
| uintptr_t Elf::debugFrameTableLength | ( | ) |
Definition at line 1263 of file linker/Elf.cc.
|
staticprivate |
Helper function: iterates through all program headers given to find where pCurrent resides, then copies that data into a new buffer and returns it.
Definition at line 62 of file linker/Elf.cc.
Referenced by create(), and createNeededOnly().
Here is the caller graph for this function:
|
static |
Extracts only the entry point from an ELF file at the given buffer.
Definition at line 1034 of file linker/Elf.cc.
|
static |
Extracts information about the ELF file at the given buffer.
Definition at line 1045 of file linker/Elf.cc.
| bool Elf::finaliseModule | ( | uint8_t * | pBuffer, |
| size_t | length | ||
| ) |
Finalises a module - applies all relocations except those in the .modinfo section. At this point it is assumed that all of this module's dependencies have been loaded.
The load base must be given again for reentrancy reasons.
Definition at line 736 of file linker/Elf.cc.
References VirtualAddressSpace::Execute, PhysicalMemoryManager::getPageSize(), ProcessorBase::information(), VirtualAddressSpace::KernelMode, VirtualAddressSpace::setFlags(), and VirtualAddressSpace::Write.
| uintptr_t Elf::getEntryPoint | ( | ) |
Returns the entry point of the file.
Definition at line 1134 of file linker/Elf.cc.
| uintptr_t Elf::getGlobalOffsetTable | ( | ) |
Gets the address of the global offset table.
Definition at line 1130 of file linker/Elf.cc.
Referenced by DynamicLinker::initPlt().
Here is the caller graph for this function:| String & Elf::getInterpreter | ( | ) |
Returns the name of the interpreter set aside for this program, or an empty string.
Definition at line 1271 of file linker/Elf.cc.
Referenced by DynamicLinker::loadProgram().
Here is the caller graph for this function:| uintptr_t Elf::getLastAddress | ( | ) |
Returns the virtual address of the last byte to be written. Used to calculate the sbrk memory breakpoint.
Definition at line 1059 of file linker/Elf.cc.
|
inline |
| size_t Elf::getPltSize | ( | ) |
Returns the size of the Procedure Linkage table.
Definition at line 1275 of file linker/Elf.cc.
|
inline |
| bool Elf::load | ( | uint8_t * | pBuffer, |
| size_t | length, | ||
| uintptr_t | loadBase, | ||
| SymbolTable * | pSymtab = 0, |
||
| uintptr_t | nStart = 0, |
||
| uintptr_t | nEnd = ~0, |
||
| bool | relocate = true, |
||
| uintptr_t | destinationBase = 0 |
||
| ) |
Loads (part) of a 'normal' file. This could be an executable or a library. By default the entire file is loaded (memory copied and relocated) but this can be changed using the nStart and nEnd parameters. This allows for lazy loading.
Definition at line 925 of file linker/Elf.cc.
References applyRelocation(), ProcessorBase::flushDCacheAndInvalidateICache(), Hex, and SymbolTable::LocalFirst.
| bool Elf::loadModule | ( | uint8_t * | pBuffer, |
| size_t | length, | ||
| uintptr_t & | loadBase, | ||
| size_t & | loadSize, | ||
| SymbolTable * | pSymbolTableCopy = 0 |
||
| ) |
Maps memory at a specified address, loads code there and applies relocations only for the .modinfo section. Intended use is for loading kernel modules only, there is no provision for dynamic relocations.
Definition at line 519 of file linker/Elf.cc.
References allocate(), PhysicalMemoryManager::allocatePage(), PhysicalMemoryManager::getPageSize(), Hex, ProcessorBase::information(), SymbolTable::insert(), KernelElf::instance(), PhysicalMemoryManager::instance(), VirtualAddressSpace::isMapped(), VirtualAddressSpace::KernelMode, VirtualAddressSpace::map(), populateSymbolTable(), preallocateSymbols(), rebaseDynamic(), and VirtualAddressSpace::Write.
| uintptr_t Elf::lookupDynamicSymbolAddress | ( | const char * | str, |
| uintptr_t | loadBase | ||
| ) |
Same as lookupSymbol, but acts on the dynamic symbol table instead of the normal one.
Definition at line 1122 of file linker/Elf.cc.
References SymbolTable::lookup().
| uintptr_t Elf::lookupSymbol | ( | const char * | pName | ) |
Returns the start address of the symbol with name 'pName'.
Definition at line 1118 of file linker/Elf.cc.
References SymbolTable::lookup().
| const char * Elf::lookupSymbol | ( | uintptr_t | addr, |
| uintptr_t * | startAddr | ||
| ) |
Default implementation which just uses the normal internal symbol table.
Definition at line 1064 of file linker/Elf.cc.
References lookupSymbol().
| const char * Elf::lookupSymbol | ( | uintptr_t | addr, |
| uintptr_t * | startAddr, | ||
| T * | symbolTable | ||
| ) |
Returns the name of the symbol which contains 'addr', and also the starting address of that symbol in 'startAddr' if startAddr != 0.
| [in] | addr | The address to look up. |
| [out] | startAddr | The starting address of the found symbol (optional). |
Definition at line 1072 of file linker/Elf.cc.
Referenced by LookupCommand::execute(), and lookupSymbol().
Here is the caller graph for this function:| List< char * > & Elf::neededLibraries | ( | ) |
Returns a list of required libraries before this object will load.
Definition at line 1267 of file linker/Elf.cc.
Referenced by DynamicLinker::loadObject(), and DynamicLinker::loadProgram().
Here is the caller graph for this function:| void Elf::populateSymbolTable | ( | SymbolTable * | pSymtab, |
| uintptr_t | loadBase | ||
| ) |
Adds all the symbols in this Elf into the given symbol table, adjusted by loadBase.
| pSymtab | Symbol table to populate. |
| loadBase | Offset to adjust each value by. |
Definition at line 1279 of file linker/Elf.cc.
References SymbolTable::insert(), and preallocateSymbols().
Referenced by loadModule().
Here is the caller graph for this function:| void Elf::preallocateSymbols | ( | SymbolTable * | pSymtabOverride = nullptr, |
| SymbolTable * | pAdditionalSymtab = nullptr |
||
| ) |
Preallocate space for the symbols in this ELF in the symbol table.
Definition at line 1326 of file linker/Elf.cc.
References SymbolTable::hasPreallocated(), SymbolTable::preallocate(), and SymbolTable::preallocateAdditional().
Referenced by allocate(), loadModule(), and populateSymbolTable().
Here is the caller graph for this function:
|
private |
Rebase all dynamic section pointers to the m_LoadBase value.
Definition at line 1390 of file linker/Elf.cc.
Referenced by loadModule().
Here is the caller graph for this function:
|
private |
Definition at line 1138 of file linker/Elf.cc.
|
private |
Definition at line 1187 of file linker/Elf.cc.
|
inline |
| bool Elf::validate | ( | uint8_t * | pBuffer, |
| size_t | length | ||
| ) |
Validates the ELF object at the given location.
Definition at line 285 of file linker/Elf.cc.
|
static |
Validates an executable ELF header and reports the bounded metadata required to read its program header table.
Definition at line 82 of file Elf-validation.cc.
Referenced by PosixSubsystem::prepareExecutable().
Here is the caller graph for this function:
|
static |
Validates the bounded PT_INTERP contents described by metadata.
Definition at line 241 of file Elf-validation.cc.
Referenced by PosixSubsystem::prepareExecutable().
Here is the caller graph for this function:
|
static |
Validates an executable's program headers and reports its load and interpreter metadata. The buffer begins at programHeaderOffset.
Definition at line 131 of file Elf-validation.cc.
Referenced by PosixSubsystem::loadElf(), and PosixSubsystem::prepareExecutable().
Here is the caller graph for this function:
|
friend |
|
friend |
|
protected |
|
protected |
|
protected |
|
protected |
|
protected |
|
staticconstexpr |
|
staticconstexpr |