X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Fld-acess.so_src%2Felf.c;h=15e84209b043ab41b6d6eb86f2ad1f767478f113;hb=3efa0bc1d46a4bcda04763a89d54a6802e717231;hp=4a87896d68e2c44c4328c317fe117af8841e5bb6;hpb=ea8e0fad3dfc8bf735d41eedbad2a8e6198059aa;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 4a87896d..15e84209 100644 --- a/Usermode/Libraries/ld-acess.so_src/elf.c +++ b/Usermode/Libraries/ld-acess.so_src/elf.c @@ -41,6 +41,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename); int Elf32GetSymbol(void *Base, const char *Name, void **Ret, size_t *Size); int elf_doRelocate_386(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff); 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 void *Elf64Relocate(void *Base, char **envp, const char *Filename); int Elf64GetSymbol(void *Base, const char *Name, void **Ret, size_t *Size); @@ -194,6 +195,11 @@ int elf_doRelocate_arm(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int ty return 0; } +int elf_doRelocate_unk(uint32_t r_info, uint32_t *ptr, Elf32_Addr addend, int type, int bRela, const char *Sym, intptr_t iBaseDiff) +{ + return 1; +} + void *Elf32Relocate(void *Base, char **envp, const char *Filename) { Elf32_Ehdr *hdr = Base; @@ -263,7 +269,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) uintptr_t addr = phtab[i].VAddr + iBaseDiff; uintptr_t end = addr + phtab[i].MemSize; for( ; addr < end; addr += PAGE_SIZE ) - SysSetMemFlags(addr, 0, 1); // Unset RO + _SysSetMemFlags(addr, 0, 1); // Unset RO } } @@ -271,6 +277,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) dynamicTab = (void *)( (intptr_t)dynamicTab + iBaseDiff ); // === Get Symbol table and String Table === + dynsymtab = NULL; for( j = 0; dynamicTab[j].d_tag != DT_NULL; j++) { switch(dynamicTab[j].d_tag) @@ -279,19 +286,19 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) case DT_SYMTAB: DEBUGS(" elf_relocate: DYNAMIC Symbol Table 0x%x (0x%x)", dynamicTab[j].d_val, dynamicTab[j].d_val + iBaseDiff); - if(iBaseDiff != 0) dynamicTab[j].d_val += iBaseDiff; - dynsymtab = (void*)(intptr_t)dynamicTab[j].d_val; + dynsymtab = (void*)((intptr_t)dynamicTab[j].d_val + iBaseDiff); + //if(iBaseDiff != 0) dynamicTab[j].d_val += iBaseDiff; break; // --- String Table --- case DT_STRTAB: DEBUGS(" elf_relocate: DYNAMIC String Table 0x%x (0x%x)", dynamicTab[j].d_val, dynamicTab[j].d_val + iBaseDiff); - if(iBaseDiff != 0) dynamicTab[j].d_val += iBaseDiff; - dynstrtab = (void*)(intptr_t)dynamicTab[j].d_val; + dynstrtab = (void*)((intptr_t)dynamicTab[j].d_val + iBaseDiff); + //if(iBaseDiff != 0) dynamicTab[j].d_val += iBaseDiff; break; // --- Hash Table -- case DT_HASH: - if(iBaseDiff != 0) dynamicTab[j].d_val += iBaseDiff; + //if(iBaseDiff != 0) dynamicTab[j].d_val += iBaseDiff; // iSymCount = ((Elf32_Word*)(intptr_t)dynamicTab[j].d_val)[1]; break; } @@ -318,6 +325,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) // --- Needed Library --- case DT_NEEDED: libPath = dynstrtab + dynamicTab[j].d_val; + DEBUGS(" dynstrtab = %p, d_val = 0x%x", dynstrtab, dynamicTab[j].d_val); DEBUGS(" Required Library '%s'", libPath); if(LoadLibrary(libPath, NULL, envp) == 0) { #if DEBUG @@ -362,6 +370,8 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) DEBUGS(" elf_relocate: Beginning Relocation"); + int fail = 0; + switch(hdr->machine) { case EM_386: @@ -372,14 +382,13 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) break; default: SysDebug("Elf32Relocate: Unknown machine type %i", hdr->machine); - // TODO: Chuck sad + do_relocate = elf_doRelocate_unk; + fail = 1; break; } DEBUGS("do_relocate = %p (%p or %p)", do_relocate, &elf_doRelocate_386, &elf_doRelocate_arm); - int fail = 0; - #define _doRelocate(r_info, ptr, bRela, addend) \ do_relocate(r_info, ptr, addend, ELF32_R_TYPE(r_info), bRela, \ dynstrtab + dynsymtab[ELF32_R_SYM(r_info)].nameOfs, iBaseDiff); @@ -447,7 +456,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) uintptr_t addr = phtab[i].VAddr + iBaseDiff; uintptr_t end = addr + phtab[i].MemSize; for( ; addr < end; addr += PAGE_SIZE ) - SysSetMemFlags(addr, 1, 1); // Unset RO + _SysSetMemFlags(addr, 1, 1); // Unset RO } } @@ -498,14 +507,14 @@ int Elf32GetSymbol(void *Base, const char *Name, void **ret, size_t *Size) { // --- Symbol Table --- case DT_SYMTAB: - symtab = (void*)(intptr_t) dynTab[i].d_val; // Rebased in Relocate + symtab = (void*)((intptr_t)dynTab[i].d_val + iBaseDiff); // Rebased in Relocate break; case DT_STRTAB: - dynstrtab = (void*)(intptr_t) dynTab[i].d_val; + dynstrtab = (void*)((intptr_t)dynTab[i].d_val + iBaseDiff); break; // --- Hash Table -- case DT_HASH: - pBuckets = (void*)(intptr_t) dynTab[i].d_val; + pBuckets = (void*)((intptr_t)dynTab[i].d_val + iBaseDiff); break; } } @@ -563,6 +572,47 @@ int Elf32GetSymbol(void *Base, const char *Name, void **ret, size_t *Size) } #ifdef SUPPORT_ELF64 +typedef int (*t_elf64_doreloc)(void *Base, const char *strtab, Elf64_Sym *symtab, Elf64_Xword r_info, void *ptr, Elf64_Sxword addend); + +int _Elf64DoReloc_X86_64(void *Base, const char *strtab, Elf64_Sym *symtab, Elf64_Xword r_info, void *ptr, Elf64_Sxword addend) +{ + int sym = ELF64_R_SYM(r_info); + int type = ELF64_R_TYPE(r_info); + const char *symname = strtab + symtab[sym].st_name; + void *symval; + //DEBUGS("_Elf64DoReloc: %s", symname); + switch( type ) + { + case R_X86_64_NONE: + break; + case R_X86_64_64: + if( !GetSymbol(symname, &symval, NULL) ) return 1; + *(uint64_t*)ptr = (uintptr_t)symval + addend; + break; + case R_X86_64_COPY: { + size_t size; + if( !GetSymbol(symname, &symval, &size) ) return 1; + memcpy(ptr, symval, size); + } break; + case R_X86_64_GLOB_DAT: + if( !GetSymbol(symname, &symval, NULL) ) return 1; + *(uint64_t*)ptr = (uintptr_t)symval; + break; + case R_X86_64_JUMP_SLOT: + if( !GetSymbol(symname, &symval, NULL) ) return 1; + *(uint64_t*)ptr = (uintptr_t)symval; + break; + case R_X86_64_RELATIVE: + *(uint64_t*)ptr = (uintptr_t)Base + addend; + break; + default: + SysDebug("ld-acess - _Elf64DoReloc: Unknown relocation type %i", type); + return 2; + } + //DEBUGS("_Elf64DoReloc: - Good"); + return 0; +} + void *Elf64Relocate(void *Base, char **envp, const char *Filename) { int i; @@ -703,45 +753,8 @@ void *Elf64Relocate(void *Base, char **envp, const char *Filename) } // Relocation function - auto int _Elf64DoReloc(Elf64_Xword r_info, void *ptr, Elf64_Sxword addend); - int _Elf64DoReloc(Elf64_Xword r_info, void *ptr, Elf64_Sxword addend) - { - int sym = ELF64_R_SYM(r_info); - int type = ELF64_R_TYPE(r_info); - const char *symname = strtab + symtab[sym].st_name; - void *symval; - //DEBUGS("_Elf64DoReloc: %s", symname); - switch( type ) - { - case R_X86_64_NONE: - break; - case R_X86_64_64: - if( !GetSymbol(symname, &symval, NULL) ) return 1; - *(uint64_t*)ptr = (uintptr_t)symval + addend; - break; - case R_X86_64_COPY: { - size_t size; - if( !GetSymbol(symname, &symval, &size) ) return 1; - memcpy(ptr, symval, size); - } break; - case R_X86_64_GLOB_DAT: - if( !GetSymbol(symname, &symval, NULL) ) return 1; - *(uint64_t*)ptr = (uintptr_t)symval; - break; - case R_X86_64_JUMP_SLOT: - if( !GetSymbol(symname, &symval, NULL) ) return 1; - *(uint64_t*)ptr = (uintptr_t)symval; - break; - case R_X86_64_RELATIVE: - *(uint64_t*)ptr = (uintptr_t)Base + addend; - break; - default: - SysDebug("ld-acess - _Elf64DoReloc: Unknown relocation type %i", type); - return 2; - } - //DEBUGS("_Elf64DoReloc: - Good"); - return 0; - } + t_elf64_doreloc fpElf64DoReloc = &_Elf64DoReloc_X86_64; + #define _Elf64DoReloc(info, ptr, addend) fpElf64DoReloc(Base, strtab, symtab, info, ptr, addend) int fail = 0; if( rel )