diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-03 17:32:24 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-03 17:32:24 +0100 |
| commit | be17349a5d8e2ea323a793384b43653e3e9c22a6 (patch) | |
| tree | 4b856b728da01c04f6d822887a2ce1e602730b1f /src/elfs/elfloader.c | |
| parent | 9aabe9c97fecb77f70361e0e0df8380f1489fc81 (diff) | |
| download | box64-be17349a5d8e2ea323a793384b43653e3e9c22a6.tar.gz box64-be17349a5d8e2ea323a793384b43653e3e9c22a6.zip | |
Added some X86_64 RelocA and a few wrapped function (wrapper still not correct anyway)
Diffstat (limited to 'src/elfs/elfloader.c')
| -rwxr-xr-x | src/elfs/elfloader.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c index bf90c9e1..6c30018e 100755 --- a/src/elfs/elfloader.c +++ b/src/elfs/elfloader.c @@ -520,15 +520,22 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int c { for (int i=0; i<cnt; ++i) { Elf64_Sym *sym = &head->DynSym[ELF64_R_SYM(rela[i].r_info)]; + int bind = ELF64_ST_BIND(sym->st_info); const char* symname = SymName(head, sym); - uint32_t *p = (uint32_t*)(rela[i].r_offset + head->delta); + uint64_t *p = (uint64_t*)(rela[i].r_offset + head->delta); uintptr_t offs = 0; uintptr_t end = 0; + uintptr_t globoffs, globend; + uint64_t* globp; switch(ELF64_R_TYPE(rela[i].r_info)) { case R_X86_64_NONE: case R_X86_64_PC32: // can be ignored break; + case R_X86_64_RELATIVE: + printf_log(LOG_DUMP, "Apply %s R_X86_64_RELATIVE @%p (%p -> %p)\n", (bind==STB_LOCAL)?"Local":"Global", p, *(void**)p, (void*)((*p)+head->delta)); + *p += head->delta; + break; case R_X86_64_COPY: if(local_maplib) GetNoSelfSymbolStartEnd(local_maplib, symname, &offs, &end, head); @@ -542,6 +549,29 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int c printf_log(LOG_NONE, "Error: Symbol %s not found, cannot apply RELA R_X86_64_COPY @%p (%p) in %s\n", symname, p, *(void**)p, head->name); } break; + case R_X86_64_GLOB_DAT: + if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname) && FindR64COPYRel(my_context->elfs[0], symname, &globoffs, &globp)) { + // set global offs / size for the symbol + offs = sym->st_value + head->delta; + end = offs + sym->st_size; + printf_log(LOG_DUMP, "Apply %s R_X86_64_GLOB_DAT with R_X86_64_COPY @%p/%p (%p/%p -> %p/%p) size=%ld on sym=%s \n", (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), (void*)(globp?(*globp):0), (void*)offs, (void*)globoffs, sym->st_size, symname); + *p = globoffs + rela[i].r_addend; + AddWeakSymbol(GetGlobalData(maplib), symname, offs, end-offs+1); + } else { + // Look for same symbol already loaded but not in self (so no need for local_maplib here) + if (GetGlobalNoWeakSymbolStartEnd(maplib, symname, &globoffs, &globend)) { + offs = globoffs; + end = globend; + } + if (!offs) { + if(strcmp(symname, "__gmon_start__")) + printf_log(LOG_NONE, "Error: Global Symbol %s not found, cannot apply R_X86_64_GLOB_DAT @%p (%p) in %s\n", symname, p, *(void**)p, head->name); + } else { + printf_log(LOG_DUMP, "Apply %s R_X86_64_GLOB_DAT @%p (%p -> %p) on sym=%s\n", (bind==STB_LOCAL)?"Local":"Global", p, (void*)(p?(*p):0), (void*)offs, symname); + *p = offs + rela[i].r_addend; + } + } + break; default: printf_log(LOG_INFO, "Warning, don't know of to handle rela #%d %s on %s\n", i, DumpRelType(ELF64_R_TYPE(rela[i].r_info)), symname); } |