+ } while( (idx = pChains[idx]) != STN_UNDEF && idx != pBuckets[iNameHash] );
+
+ TRACE("No symbol");
+ return 1;
+}
+
+int Elf32GetSymbol(void *Base, const char *Name, void **ret, size_t *Size)
+{
+ int section;
+ TRACE("Elf32GetSymbol(%p,%s,...)", Base, Name);
+ if( Elf32GetSymbolInfo(Base, Name, ret, Size, §ion, NULL, NULL) )
+ return 0;
+ if( section == SHN_UNDEF ) {
+ TRACE("Elf32GetSymbol: Undefined", *ret, (Size?*Size:0), section);
+ return 0;
+ }
+ TRACE("Elf32GetSymbol: Found %p+0x%x,section=%i", *ret, (Size?*Size:0), section);
+ return 1;
+}
+
+#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, NULL) ) return 1;
+ *(uint64_t*)ptr = (uintptr_t)symval + addend;
+ break;
+ case R_X86_64_COPY: {
+ size_t size;
+ if( !GetSymbol(symname, &symval, &size, NULL) ) return 1;
+ memcpy(ptr, symval, size);
+ } break;
+ case R_X86_64_GLOB_DAT:
+ if( !GetSymbol(symname, &symval, NULL, NULL) ) return 1;
+ *(uint64_t*)ptr = (uintptr_t)symval;
+ break;
+ case R_X86_64_JUMP_SLOT:
+ if( !GetSymbol(symname, &symval, NULL, 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;
+ Elf64_Ehdr *hdr = Base;
+ Elf64_Phdr *phtab;
+ Elf64_Dyn *dyntab = NULL;
+ Elf64_Addr compiledBase = -1, baseDiff;
+ Elf64_Sym *symtab = NULL;
+ char *strtab = NULL;
+ Elf64_Word *hashtab = NULL;
+ Elf64_Rel *rel = NULL;
+ int rel_count = 0;
+ Elf64_Rela *rela = NULL;
+ int rela_count = 0;
+ void *pltrel = NULL;
+ int plt_size = 0, plt_type = 0;
+
+ TRACE("hdr = {");
+ TRACE(" e_ident = '%.16s'", hdr->e_ident);
+ TRACE(" e_type = 0x%x", hdr->e_type);
+ TRACE(" e_machine = 0x%x", hdr->e_machine);
+ TRACE(" e_version = 0x%x", hdr->e_version);
+ TRACE(" e_entry = %p", hdr->e_entry);
+ TRACE(" e_phoff = 0x%llx", hdr->e_phoff);
+ TRACE(" e_shoff = 0x%llx", hdr->e_shoff);
+ TRACE(" e_flags = 0x%x", hdr->e_flags);
+ TRACE(" e_ehsize = 0x%x", hdr->e_ehsize);
+ TRACE(" e_phentsize = 0x%x", hdr->e_phentsize);
+ TRACE(" e_phnum = %i", hdr->e_phnum);
+
+ // Scan for the dynamic table (and find the compiled base)
+ phtab = (void*)((uintptr_t)Base + (uintptr_t)hdr->e_phoff);
+ for( i = 0; i < hdr->e_phnum; i ++ )
+ {
+ if(phtab[i].p_type == PT_DYNAMIC)
+ dyntab = (void *)(intptr_t)phtab[i].p_vaddr;
+ if(phtab[i].p_type == PT_LOAD && compiledBase > phtab[i].p_vaddr)
+ compiledBase = phtab[i].p_vaddr;
+ }
+
+ baseDiff = (uintptr_t)Base - compiledBase;
+
+ TRACE("baseDiff = %p", baseDiff);
+
+ if(dyntab == NULL) {
+ SysDebug(" Elf64Relocate: No PT_DYNAMIC segment in image %p, returning", Base);
+ return (void *)(uintptr_t)(hdr->e_entry + baseDiff);
+ }
+
+ dyntab = (void *)(uintptr_t)((uintptr_t)dyntab + baseDiff);
+
+ // Parse the dynamic table (first pass)
+ // - Search for String, Symbol and Hash tables
+ for(i = 0; dyntab[i].d_tag != DT_NULL; i ++)
+ {
+ switch(dyntab[i].d_tag)