X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Fld-acess.so_src%2Felf.c;h=e3109b4a624eb386ef1534dd0b669880c557aa67;hb=89fa44978be88e59366ee3e8939a1621f1ebc146;hp=bcf66ccd34f280109ed91efbc7d2c42df2fa1c63;hpb=e785cf0b01276ae9ebbb018dae2fe83d11e77701;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 bcf66ccd..e3109b4a 100644 --- a/Usermode/Libraries/ld-acess.so_src/elf.c +++ b/Usermode/Libraries/ld-acess.so_src/elf.c @@ -4,8 +4,10 @@ * * elf.c * - ELF32/ELF64 relocation + * + * TODO: Have GetSymbol() return a symbol "strength" on success. Allows STB_WEAK to be overriden by STB_GLOBAL */ -#ifndef DEBUG // This code is #include'd from the kernel, so DEBUG may already be defined +#ifndef KERNEL_VERSION # define DEBUG 0 #endif @@ -29,7 +31,8 @@ #define WARNING(f,...) SysDebug("WARN: "f ,## __VA_ARGS__) // Malformed file #define NOTICE(f,...) SysDebug("NOTICE: "f ,## __VA_ARGS__) // Missing relocation -#define TRACE(f,...) DEBUG_OUT("TRACE:%s:%i "f, __func__, __LINE__ ,## __VA_ARGS__) // Debugging trace +//#define TRACE(f,...) DEBUG_OUT("TRACE:%s:%i "f, __func__, __LINE__ ,## __VA_ARGS__) // Debugging trace +#define TRACE(f,...) DEBUG_OUT("TRACE:%s "f, __func__,## __VA_ARGS__) // Debugging trace #ifndef DISABLE_ELF64 # define SUPPORT_ELF64 @@ -151,12 +154,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: @@ -223,7 +237,6 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) const Elf32_Ehdr *hdr = Base; char *libPath; intptr_t iRealBase = -1; - intptr_t iBaseDiff; Elf32_Rel *rel = NULL; Elf32_Rela *rela = NULL; void *plt = NULL; @@ -264,10 +277,11 @@ void *Elf32Relocate(void *Base, char **envp, const char *Filename) // Page Align real base iRealBase &= ~0xFFF; - TRACE("True Base = 0x%x, Compiled Base = 0x%x", Base, iRealBase); // Adjust "Real" Base - iBaseDiff = (intptr_t)Base - iRealBase; + const intptr_t iBaseDiff = (intptr_t)Base - iRealBase; + + TRACE("True Base = 0x%x, Compiled Base = 0x%x, Difference = 0x%x", Base, iRealBase, iBaseDiff); // Check if a PT_DYNAMIC segement was found if(!dynamicTab) { @@ -342,15 +356,25 @@ 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 (local)", i, name, sym->st_value + iBaseDiff); + sym->st_value += iBaseDiff; + } + // If GetSymbol doesn't return a strong/global symbol value + else if( GetSymbol(name, &newval, &newsize, Base) != 1 ) { - WARNING("TODO: Weak bound local symbols '%s'", name); - //assert(ELF32_ST_BIND(sym->st_info) != STB_WEAK); - //return NULL; + TRACE("Sym %i'%s' = %p (Local weak)", i, name, sym->st_value + iBaseDiff); + sym->st_value += iBaseDiff; + } + else + { + TRACE("Sym %i'%s' = %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; } } @@ -670,14 +694,18 @@ int Elf32GetSymbolInfo(void *Base, const char *Name, void **Addr, size_t *Size, int Elf32GetSymbol(void *Base, const char *Name, void **ret, size_t *Size) { - int section; + int section, binding; TRACE("Elf32GetSymbol(%p,%s,...)", Base, Name); - if( Elf32GetSymbolInfo(Base, Name, ret, Size, §ion, NULL, NULL) ) + if( Elf32GetSymbolInfo(Base, Name, ret, Size, §ion, &binding, NULL) ) return 0; if( section == SHN_UNDEF ) { - TRACE("Elf32GetSymbol: Undefined", *ret, (Size?*Size:0), section); + TRACE("Elf32GetSymbol: Undefined %p", *ret, (Size?*Size:0), section); return 0; } + if( binding == STB_WEAK ) { + TRACE("Elf32GetSymbol: Weak, return %p+0x%x,section=%i", *ret, (Size?*Size:0), section); + return 2; + } TRACE("Elf32GetSymbol: Found %p+0x%x,section=%i", *ret, (Size?*Size:0), section); return 1; }