X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Fld-acess.so_src%2Felf.c;h=676f5c3f4d7bad73c4576f4d826802795a8dc6cc;hb=4e565693a59be0da434790ec32a97596732f6ee4;hp=15e84209b043ab41b6d6eb86f2ad1f767478f113;hpb=17ebf0cdf584b5eb63aa96149de3e4f76cb82e01;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/ld-acess.so_src/elf.c b/Usermode/Libraries/ld-acess.so_src/elf.c index 15e84209..676f5c3f 100644 --- a/Usermode/Libraries/ld-acess.so_src/elf.c +++ b/Usermode/Libraries/ld-acess.so_src/elf.c @@ -43,6 +43,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename); int elf_doRelocate_arm(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff); int elf_doRelocate_unk(uint32_t , uint32_t *, Elf32_Addr , int , int , const char *, intptr_t); #ifdef SUPPORT_ELF64 +int _Elf64DoReloc_X86_64(void *Base, const char *strtab, Elf64_Sym *symtab, Elf64_Xword r_info, void *ptr, Elf64_Sxword addend); void *Elf64Relocate(void *Base, char **envp, const char *Filename); int Elf64GetSymbol(void *Base, const char *Name, void **Ret, size_t *Size); #endif @@ -204,12 +205,10 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) { Elf32_Ehdr *hdr = Base; Elf32_Phdr *phtab; - int i, j; // Counters char *libPath; intptr_t iRealBase = -1; intptr_t iBaseDiff; int iSegmentCount; -// int iSymCount; Elf32_Rel *rel = NULL; Elf32_Rela *rela = NULL; void *plt = NULL; @@ -229,20 +228,24 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) // Parse Program Header to get Dynamic Table phtab = (void*)( (uintptr_t)Base + hdr->phoff ); iSegmentCount = hdr->phentcount; - for(i=0;i phtab[i].VAddr) - iRealBase = phtab[i].VAddr; - - // Find Dynamic Section - if(phtab[i].Type == PT_DYNAMIC) { - if(dynamicTab) { + switch(phtab[i].Type) + { + case PT_LOAD: + // Determine linked base address + if( iRealBase > phtab[i].VAddr) + iRealBase = phtab[i].VAddr; + break; + case PT_DYNAMIC: + // Find Dynamic Section + if(!dynamicTab) { + dynamicTab = (void *) (intptr_t) phtab[i].VAddr; + } + else { DEBUGS(" WARNING - elf_relocate: Multiple PT_DYNAMIC segments"); - continue; } - dynamicTab = (void *) (intptr_t) phtab[i].VAddr; - j = i; // Save Dynamic Table ID + break; } } @@ -263,7 +266,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) // Allow writing to read-only segments, just in case they need to be relocated // - Will be reversed at the end of the function - for( i = 0; i < iSegmentCount; i ++ ) + for( int i = 0; i < iSegmentCount; i ++ ) { if(phtab[i].Type == PT_LOAD && !(phtab[i].Flags & PF_W) ) { uintptr_t addr = phtab[i].VAddr + iBaseDiff; @@ -278,7 +281,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) // === Get Symbol table and String Table === dynsymtab = NULL; - for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++) + for( int j = 0; dynamicTab[j].d_tag != DT_NULL; j++) { switch(dynamicTab[j].d_tag) { @@ -314,7 +317,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) // === Parse Relocation Data === DEBUGS(" elf_relocate: dynamicTab = 0x%x", dynamicTab); - for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++) + for( int j = 0; dynamicTab[j].d_tag != DT_NULL; j++) { switch(dynamicTab[j].d_tag) { @@ -398,8 +401,8 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) { Elf32_Word *ptr; DEBUGS(" elf_relocate: rel=0x%x, relSz=0x%x, relEntSz=0x%x", rel, relSz, relEntSz); - j = relSz / relEntSz; - for( i = 0; i < j; i++ ) + int max = relSz / relEntSz; + for( int i = 0; i < max; i++ ) { //DEBUGS(" Rel %i: 0x%x+0x%x", i, iBaseDiff, rel[i].r_offset); ptr = (void*)(iBaseDiff + rel[i].r_offset); @@ -411,8 +414,8 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) { Elf32_Word *ptr; DEBUGS(" elf_relocate: rela=0x%x, relaSz=0x%x, relaEntSz=0x%x", rela, relaSz, relaEntSz); - j = relaSz / relaEntSz; - for( i = 0; i < j; i++ ) + int count = relaSz / relaEntSz; + for( int i = 0; i < count; i++ ) { ptr = (void*)(iBaseDiff + rela[i].r_offset); fail |= _doRelocate(rel[i].r_info, ptr, 1, rela[i].r_addend); @@ -427,9 +430,9 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) if(pltType == DT_REL) { Elf32_Rel *pltRel = plt; - j = pltSz / sizeof(Elf32_Rel); - DEBUGS(" elf_relocate: PLT Reloc Type = Rel, %i entries", j); - for(i=0;iphoff ); - for( i = 0; i < hdr->phentcount; i ++ ) + for( int i = 0; i < hdr->phentcount; i ++ ) { if(phtab[i].Type == PT_LOAD && iBaseDiff > phtab[i].VAddr) iBaseDiff = phtab[i].VAddr; @@ -501,7 +503,7 @@ int Elf32GetSymbol(void *Base, const char *Name, void **ret, size_t *Size) } iBaseDiff = (intptr_t)Base - iBaseDiff; // Make iBaseDiff actually the diff dynTab = (void*)( (intptr_t)dynTab + iBaseDiff ); - for( i = 0; dynTab[i].d_tag != DT_NULL; i++) + for( int i = 0; dynTab[i].d_tag != DT_NULL; i++) { switch(dynTab[i].d_tag) { @@ -545,28 +547,23 @@ int Elf32GetSymbol(void *Base, const char *Name, void **ret, size_t *Size) // iSymCount = pBuckets[1]; pBuckets = &pBuckets[2]; pChains = &pBuckets[ nbuckets ]; + assert(pChains); // Get hash iNameHash = ElfHashString(Name); iNameHash %= nbuckets; // Walk Chain - i = pBuckets[ iNameHash ]; - if(symtab[i].shndx != SHN_UNDEF && strcmp(dynstrtab + symtab[i].nameOfs, Name) == 0) { - *ret = (void*)( (uintptr_t) symtab[ i ].value + iBaseDiff ); - if(Size) *Size = symtab[i].size; - return 1; - } - - while(pChains[i] != STN_UNDEF) - { - i = pChains[i]; - if(symtab[i].shndx != SHN_UNDEF && strcmp(dynstrtab + symtab[ i ].nameOfs, Name) == 0) { - *ret = (void*)( (uintptr_t)symtab[ i ].value + iBaseDiff ); - if(Size) *Size = symtab[i].size; + int idx = pBuckets[ iNameHash ]; + do { + Elf32_Sym *sym = &symtab[idx]; + assert(sym); + if(sym->shndx != SHN_UNDEF && strcmp(dynstrtab + sym->nameOfs, Name) == 0) { + *ret = (void*)( (uintptr_t)sym->value + iBaseDiff ); + if(Size) *Size = sym->size; return 1; } - } + } while( (idx = pChains[idx]) != STN_UNDEF && idx != pBuckets[iNameHash] ); return 0; }