the corresponding table's string table */ unsigned char st_info; /* Symbol type and binding attributes */ unsigned char st_other; /* Symbol visibility */ uint16_t st_shndx; /* Each symbol is defined for a particular section */ Elf64_Addr st_value; /* Either an address or offset */ uint64_t st_size; /* Size of the actual reference */ } Elf64_Sym; /* A single entry in any of the symbol table */
linking. Not needed for program execution, can be stripped. Each entry’s st_name is an offset in .strtab • .dynsym - Contains references to external sources (shared libraries). Used by the dynamic linker to resolve references at run time. Each entry’s st_name is an offset into .dynstr
dynamic linking typedef struct { Elf64_Addr r_offset; // The address that requires to be relocated uint64_t r_info; // Index into symbol table + type of relocation } Elf64_Rel;
handles it’s own relocation • Loads needed shared libraries (recursively) • For every ELF file loaded, it creates an array of ‘link_map’ structures. (The first entry being of the executable binary itself)
points to the ‘dymanic section’ of the executable GOT[1] - points to the first element of link_map structure array GOT[2] - points to _dl_runtime_resolve() GOT[3] .. onwards relocation entries for external functions
called • [func@plt] ‘func@plt’ jumps to GOT entry for func • [func@plt] Initially GOT entry points to next instruction in ‘func@plt’ • [func@plt] Pushes an offset (index of ‘func’ in .rel.plt) on stack • [func@plt] Jump to a common stub in ‘plt’ section • [common@plt] Pushes GOT[1] (ptr to link_map) on stack • [common@plt] Jump to GOT[2] (__dl_runtime_resolve()) Stack has the relocation entry offset and address of link_map structure array. __dl_runtime_resolve() calls _dl_fixup() with these two as parameters
from the first link map’s l->l_info. • Retrieves the particular relocation entry in the table using the relocation offset • Relocation entry gives symbol table entry, which gives offset into the string table for the name of the symbol • Computes the address to be patched as: l->l_addr (the load address for the ELF) + reloc->r_offset (the address within the ELF to be patched) • Search for the symbol by name in shared libraries and patch the corresponding address calculated. • Also return the address that has been resolved
‘else’ • The target value written is l->l_addr + sym->st_value • Make symbol entry point to some address already resolved by libc, say ‘read’ address in GOT (such that sym->st_value = address of read) • Make relocation entry point to appropriate index into symbol table containing ‘read’ • Setup l_addr with (offset_system - offset_read) so that instead of read’s address, system’s address is returned. • puts will be resolved to system!