From b87cb350c00ea497f52a98e189662934c7eb036c Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 21 Jun 2014 23:42:39 +0800 Subject: [PATCH] Usermode/ld-acess - STB_WEAK local symbols --- Usermode/Libraries/ld-acess.so_src/elf.c | 44 +++++++++++++++++------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/Usermode/Libraries/ld-acess.so_src/elf.c b/Usermode/Libraries/ld-acess.so_src/elf.c index bcf66ccd..0adb2a70 100644 --- a/Usermode/Libraries/ld-acess.so_src/elf.c +++ b/Usermode/Libraries/ld-acess.so_src/elf.c @@ -151,12 +151,23 @@ int elf_doRelocate_386(tElfRelocInfo *Info, uint32_t r_info, uint32_t *ptr, Elf3 case R_386_COPY: { void *old_symval = symval; GetSymbol(Info->strtab + sym->st_name, &symval, &size, Info->Base); - if( symval == old_symval ) { - WARNING("Can't find required external symbol '%s'", Info->strtab + sym->st_name); - return 1; + if( symval == old_symval ) + { + if( ELF32_ST_BIND(sym->st_info) != STB_WEAK ) + { + WARNING("sym={val:%p,size:0x%x,info:0x%x,other:0x%x,shndx:%i}", + sym->st_value, sym->st_size, sym->st_info, sym->st_other, sym->st_shndx); + WARNING("Can't find required external symbol '%s' for R_386_COPY", Info->strtab + sym->st_name); + return 1; + } + // Don't bother doing the memcpy + TRACE("R_386_COPY (%p, %p, %i)", ptr, symval, size); + } + else + { + TRACE("R_386_COPY (%p, %p, %i)", ptr, symval, size); + memcpy(ptr, symval, size); } - TRACE("R_386_COPY (%p, %p, %i)", ptr, symval, size); - memcpy(ptr, symval, size); break; } default: @@ -342,15 +353,24 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) } else { - // TODO: What about weak locally-defined symbols? - if( ELF32_ST_BIND(sym->st_info) == STB_WEAK ) + void *newval; + size_t newsize; + if( ELF32_ST_BIND(sym->st_info) != STB_WEAK ) + { + TRACE("Sym %i'%s' %p += 0x%x", i, name, sym->st_value, iBaseDiff); + sym->st_value += iBaseDiff; + } + else if( !GetSymbol(name, &newval, &newsize, Base) ) + { + TRACE("Sym %i'%s' %p += 0x%x (Local weak)", i, name, sym->st_value, iBaseDiff); + sym->st_value += iBaseDiff; + } + else { - WARNING("TODO: Weak bound local symbols '%s'", name); - //assert(ELF32_ST_BIND(sym->st_info) != STB_WEAK); - //return NULL; + TRACE("Sym %i'%s' %p = %p+0x%x (Extern weak)", i, name, newval, newsize); + sym->st_value = (uintptr_t)newval; + sym->st_size = newsize; } - TRACE("Sym %i'%s' %p += 0x%x", i, name, sym->st_value, iBaseDiff); - sym->st_value += iBaseDiff; } } -- 2.20.1