The Pedigree Project  0.1
Classes | Public Member Functions | Static Public Member Functions | Protected Attributes | Private Member Functions | Static Private Member Functions | Friends | List of all members
Elf Class Reference

#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
 

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, uintptr_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)
 
List< char * > & neededLibraries ()
 
StringgetInterpreter ()
 
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)
 
SymbolTablegetSymbolTable ()
 
uintptr_t getEntryPoint ()
 
uintptr_t debugFrameTable ()
 
uintptr_t debugFrameTableLength ()
 
void setName (const String &s)
 
const StringgetName () const
 

Static Public Member Functions

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)
 

Protected Attributes

struct Elf::ElfHeader_t PACKED
 
struct Elf::ElfProgramHeader_t PACKED
 
struct Elf::ElfSectionHeader_t PACKED
 
struct Elf::Elf32SectionHeader_t PACKED
 
struct Elf::ElfSymbol_t PACKED
 
struct Elf::Elf32Symbol_t PACKED
 
struct Elf::ElfDyn_t PACKED
 
struct Elf::ElfRel_t PACKED
 
struct Elf::ElfRela_t PACKED
 
ElfSymbol_tm_pSymbolTable
 
size_t m_nSymbolTableSize
 
char * m_pStringTable
 
size_t m_nStringTableSize
 
char * m_pShstrtab
 
size_t m_nShstrtabSize
 
uintptr_t * m_pGotTable
 
ElfRel_tm_pRelTable
 
ElfRela_tm_pRelaTable
 
size_t m_nRelTableSize
 
size_t m_nRelaTableSize
 
ElfRel_tm_pPltRelTable
 
ElfRela_tm_pPltRelaTable
 
bool m_bUsesRela
 
uint32_t * m_pDebugTable
 
size_t m_nDebugTableSize
 
ElfSymbol_tm_pDynamicSymbolTable
 
size_t m_nDynamicSymbolTableSize
 
char * m_pDynamicStringTable
 
size_t m_nDynamicStringTableSize
 
ElfSectionHeader_tm_pSectionHeaders
 
size_t m_nSectionHeaders
 
ElfProgramHeader_tm_pProgramHeaders
 
size_t m_nProgramHeaders
 
size_t m_nPltSize
 
uintptr_t m_nEntry
 
List< char * > m_NeededLibraries
 
SymbolTable m_SymbolTable
 
uintptr_t m_InitFunc
 
uintptr_t m_FiniFunc
 
String m_sInterpreter
 
String m_Name
 
uintptr_t m_LoadBase
 

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)
 
bool applyRelocation (ElfRela_t rela, ElfSectionHeader_t *pSh, SymbolTable *pSymtab=0, uintptr_t loadBase=0, SymbolTable::Policy policy=SymbolTable::LocalFirst)
 
void rebaseDynamic ()
 
Elfoperator= (const Elf &)
 

Static Private Member Functions

template<typename T >
static T * elfCopy (uint8_t *, ElfProgramHeader_t *, size_t, T *, size_t)
 

Friends

class PosixSubsystem
 

Detailed Description

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.

Definition at line 201 of file Elf.h.

Constructor & Destructor Documentation

Elf::Elf ( )

Default constructor - loads no data.

Definition at line 75 of file linker/Elf.cc.

Referenced by KernelElf::loadModule().

+ Here is the caller graph for this function:

Elf::~Elf ( )
virtual

Destructor.

Definition at line 88 of file linker/Elf.cc.

Elf::Elf ( const Elf elf)

The copy-constructor

Definition at line 105 of file linker/Elf.cc.

References List< T, nodePoolSize >::begin(), SymbolTable::copyTable(), and List< T, nodePoolSize >::end().

Member Function Documentation

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.

Note
If bAllocate is false, the memory will NOT be allocated.
Todo:
Don't rely on this. Look at nchain in the hash table.

Definition at line 837 of file linker/Elf.cc.

References RangeList< T, Reversed >::allocate(), PhysicalMemoryManager::allocatePage(), RangeList< T, Reversed >::allocateSpecific(), ERROR, VirtualAddressSpace::Execute, Process::getDynamicSpaceAllocator(), PhysicalMemoryManager::getPageSize(), Process::getSpaceAllocator(), Hex, Processor::information(), SymbolTable::insert(), SymbolTable::insertMultiple(), PhysicalMemoryManager::instance(), NOTICE, preallocateSymbols(), WARNING, and VirtualAddressSpace::Write.

Referenced by loadModule(), DynamicLinker::loadObject(), and DynamicLinker::loadProgram().

+ Here is the caller graph for this function:

bool Elf::applyRelocation ( ElfRel_t  rel,
ElfSectionHeader_t pSh,
SymbolTable pSymtab = 0,
uintptr_t  loadBase = 0,
SymbolTable::Policy  policy = SymbolTable::LocalFirst 
)
private

Applies one relocation. This overload performs a relocation without addend (REL).

Parameters
relThe relocation entry to apply.
pShA pointer to the section that the relocation entry refers to.
pSymtabThe symbol table to use for lookups.
loadBaseFor a relocatable object, the address at which it is loaded.
policyLookup policy.
Note
Defined in core/processor/.../Elf.cc

Definition at line 38 of file kernel/core/processor/arm_926e/Elf32.cc.

References Dec, ERROR, KernelElf::instance(), SymbolTable::lookup(), SymbolTable::NotOriginatingElf, and WARNING.

Referenced by applySpecificRelocation(), getEntryPoint(), and load().

+ Here is the caller graph for this function:

bool Elf::applyRelocation ( ElfRela_t  rela,
ElfSectionHeader_t pSh,
SymbolTable pSymtab = 0,
uintptr_t  loadBase = 0,
SymbolTable::Policy  policy = SymbolTable::LocalFirst 
)
private

Applies one relocation. This overload performs a relocation with addend (RELA).

Parameters
relThe relocation entry to apply.
pShA pointer to the section that the relocation entry refers to.
pSymtabThe symbol table to use for lookups.
loadBaseFor a relocatable object, the address at which it is loaded.
policyLookup policy.
Note
Defined in core/processor/.../Elf.cc
Todo:
Should be A + B?

Definition at line 140 of file kernel/core/processor/arm_926e/Elf32.cc.

References ERROR.

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 1353 of file linker/Elf.cc.

References applyRelocation().

Referenced by DynamicLinker::resolvePltSymbol().

+ Here is the caller graph for this function:

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 313 of file linker/Elf.cc.

References List< T, nodePoolSize >::begin(), elfCopy(), List< T, nodePoolSize >::end(), ERROR, Hex, NOTICE, List< T, nodePoolSize >::pushBack(), and WARNING.

Referenced by KernelElf::loadModule(), 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 174 of file linker/Elf.cc.

References List< T, nodePoolSize >::begin(), elfCopy(), List< T, nodePoolSize >::end(), ERROR, Hex, NOTICE, and List< T, nodePoolSize >::pushBack().

Referenced by DynamicLinker::loadObject(), and DynamicLinker::loadProgram().

+ Here is the caller graph for this function:

template<typename T >
T * Elf::elfCopy ( uint8_t *  pBuffer,
Elf::ElfProgramHeader_t pProgramHeaders,
size_t  nProgramHeaders,
T *  pCurrent,
size_t  size 
)
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 55 of file linker/Elf.cc.

Referenced by create(), and createNeededOnly().

+ Here is the caller graph for this function:

bool Elf::extractEntryPoint ( uint8_t *  pBuffer,
size_t  length,
uintptr_t &  entry 
)
static

Extracts only the entry point from an ELF file at the given buffer.

Todo:
check magic

Definition at line 1119 of file linker/Elf.cc.

Referenced by PosixSubsystem::invoke().

+ Here is the caller graph for this function:

bool Elf::extractInformation ( uint8_t *  pBuffer,
size_t  length,
size_t &  phdrCount,
size_t &  phdrEntrySize,
uintptr_t &  phdrAddress 
)
static

Extracts information about the ELF file at the given buffer.

Todo:
check magic

Definition at line 1131 of file linker/Elf.cc.

bool Elf::finaliseModule ( uint8_t *  pBuffer,
uintptr_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 792 of file linker/Elf.cc.

References VirtualAddressSpace::Execute, PhysicalMemoryManager::getPageSize(), Processor::information(), VirtualAddressSpace::KernelMode, VirtualAddressSpace::setFlags(), and VirtualAddressSpace::Write.

Referenced by KernelElf::getDependingModule().

+ Here is the caller graph for this function:

uintptr_t Elf::getEntryPoint ( )

Returns the entry point of the file.

Definition at line 1235 of file linker/Elf.cc.

References applyRelocation().

uintptr_t Elf::getGlobalOffsetTable ( )

Gets the address of the global offset table.

Returns
Address of the GOT, or 0 if none was found.

Definition at line 1230 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 1398 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 1147 of file linker/Elf.cc.

const String& Elf::getName ( ) const
inline

Gets the friendly name.

Definition at line 358 of file Elf.h.

size_t Elf::getPltSize ( )

Returns the size of the Procedure Linkage table.

Definition at line 1403 of file linker/Elf.cc.

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 
)

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.

Note
PLT relocations are not performed here - they are defined in a different section to the standard REL and RELA entries, so must be done specifically (via applySpecificRelocation).

Definition at line 1001 of file linker/Elf.cc.

References applyRelocation(), Hex, and NOTICE.

Referenced by DynamicLinker::trap().

+ Here is the caller graph for this function:

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.

Todo:
Figure out how to map to the pages loaded by GRUB instead of copying into newly-allocated pages here.
Todo:
we should handle hidden symbols better so they are only needed for relocation and not tracked forever

Definition at line 552 of file linker/Elf.cc.

References allocate(), PhysicalMemoryManager::allocatePage(), assert, ERROR, PhysicalMemoryManager::getPageSize(), Processor::information(), SymbolTable::insert(), PhysicalMemoryManager::instance(), KernelElf::instance(), VirtualAddressSpace::isMapped(), VirtualAddressSpace::KernelMode, VirtualAddressSpace::map(), NOTICE, populateSymbolTable(), preallocateSymbols(), rebaseDynamic(), and VirtualAddressSpace::Write.

Referenced by KernelElf::loadModule().

+ Here is the caller graph for this function:

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 1221 of file linker/Elf.cc.

References SymbolTable::lookup().

template<class T >
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.

Parameters
[in]addrThe address to look up.
[out]startAddrThe starting address of the found symbol (optional).
Returns
The symbol name, as a C string.
Todo:
we should check for STV_HIDDEN symbol - but can't tell if we're local or not here and if we're local, a hidden symbol is totally fine. Need to indicate which ELF the relocation is for.

Definition at line 1164 of file linker/Elf.cc.

Referenced by LookupCommand::execute(), KernelElf::getDependingModule(), KernelElf::globalLookupSymbol(), KernelElf::loadModule(), lookupSymbol(), and KernelElf::unloadModule().

+ Here is the caller graph for this function:

const char * Elf::lookupSymbol ( uintptr_t  addr,
uintptr_t *  startAddr 
)

Default implementation which just uses the normal internal symbol table.

Definition at line 1153 of file linker/Elf.cc.

References lookupSymbol().

uintptr_t Elf::lookupSymbol ( const char *  pName)

Returns the start address of the symbol with name 'pName'.

Definition at line 1216 of file linker/Elf.cc.

References SymbolTable::lookup().

List< char * > & Elf::neededLibraries ( )

Returns a list of required libraries before this object will load.

Definition at line 1393 of file linker/Elf.cc.

Referenced by DynamicLinker::loadObject(), and DynamicLinker::loadProgram().

+ Here is the caller graph for this function:

Elf& Elf::operator= ( const Elf )
private

The assignment operator

Note
currently not implemented
void Elf::populateSymbolTable ( SymbolTable pSymtab,
uintptr_t  loadBase 
)

Adds all the symbols in this Elf into the given symbol table, adjusted by loadBase.

Parameters
pSymtabSymbol table to populate.
loadBaseOffset to adjust each value by.
Todo:
Don't rely on this. Look at nchain in the hash table.

Definition at line 1408 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 1469 of file linker/Elf.cc.

References NOTICE, SymbolTable::preallocate(), and SymbolTable::preallocateAdditional().

Referenced by allocate(), loadModule(), and populateSymbolTable().

+ Here is the caller graph for this function:

void Elf::rebaseDynamic ( )
private

Rebase all dynamic section pointers to the m_LoadBase value.

Definition at line 1541 of file linker/Elf.cc.

Referenced by loadModule().

+ Here is the caller graph for this function:

void Elf::setName ( const String s)
inline

Sets a friendly name for debugging.

Definition at line 352 of file Elf.h.

Referenced by KernelElf::loadModule().

+ Here is the caller graph for this function:

bool Elf::validate ( uint8_t *  pBuffer,
size_t  length 
)

Validates the ELF object at the given location.

Definition at line 284 of file linker/Elf.cc.

Referenced by PosixSubsystem::invoke().

+ Here is the caller graph for this function:


The documentation for this class was generated from the following files: