X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Fld-acess.so_src%2Felf.c;h=531b32d7980e97cb3a2df11b5ffd1be84ad52263;hb=8481db38ad481ab13963d44c33352bc8af740f25;hp=0b3656b26a44ed4745b2595a360074eef5227029;hpb=1409c5235c5228061ba6605fc1f41302f4f3fe78;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 0b3656b2..531b32d7 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; @@ -214,7 +220,6 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) char *dynstrtab = NULL; // .dynamic String Table Elf32_Sym *dynsymtab; int (*do_relocate)(uint32_t t_info, uint32_t *ptr, Elf32_Addr addend, int Type, int bRela, const char *Sym, intptr_t iBaseDiff); - auto int _doRelocate(uint32_t r_info, uint32_t *ptr, int bRela, Elf32_Addr addend); DEBUGS("ElfRelocate: (Base=0x%x)", Base); @@ -264,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 } } @@ -272,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) @@ -363,13 +369,7 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) DEBUGS(" elf_relocate: Beginning Relocation"); - int _doRelocate(uint32_t r_info, uint32_t *ptr, int bRela, Elf32_Addr addend) - { - int type = ELF32_R_TYPE(r_info); - int sym = ELF32_R_SYM(r_info); - const char *symname = dynstrtab + dynsymtab[sym].nameOfs; - return do_relocate(r_info, ptr, addend, type, bRela, symname, iBaseDiff); - } + int fail = 0; switch(hdr->machine) { @@ -381,13 +381,16 @@ 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); // Parse Relocation Entries if(rel && relSz) @@ -452,7 +455,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 } } @@ -461,6 +464,8 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) return NULL; } + #undef _doRelocate + DEBUGS("ElfRelocate: RETURN 0x%x to %p", hdr->entrypoint + iBaseDiff, __builtin_return_address(0)); return (void*)(intptr_t)( hdr->entrypoint + iBaseDiff ); } @@ -566,6 +571,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; @@ -706,45 +752,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 )