+{
+ Elf32_Ehdr *hdr = Base;
+
+ switch(hdr->e_ident[4])
+ {
+ case ELFCLASS32:
+ return Elf32GetSymbol(Base, Name, ret);
+ case ELFCLASS64:
+ return Elf64GetSymbol(Base, Name, ret);
+ default:
+ SysDebug("ld-acess - ElfRelocate: Unknown file class %i", hdr->e_ident[4]);
+ return 0;
+ }
+}
+
+int Elf64GetSymbol(void *Base, const char *Name, void **Ret)
+{
+ Elf64_Ehdr *hdr = Base;
+ Elf64_Sym *symtab;
+ int nbuckets = 0;
+ int iSymCount = 0;
+ int i;
+ Elf64_Word *pBuckets;
+ Elf64_Word *pChains;
+ uint32_t iNameHash;
+ const char *dynstrtab;
+ uintptr_t iBaseDiff = -1;
+
+// DEBUGS("sizeof(uint32_t) = %i, sizeof(Elf64_Word) = %i", sizeof(uint32_t), sizeof(Elf64_Word));
+
+ dynstrtab = NULL;
+ pBuckets = NULL;
+ symtab = NULL;
+
+ // Catch the current executable
+ if( !pBuckets )
+ {
+ Elf64_Phdr *phtab;
+ Elf64_Dyn *dynTab = NULL;
+ int j;
+
+ // Locate the tables
+ phtab = (void*)( Base + hdr->e_phoff );
+ for( i = 0; i < hdr->e_phnum; i ++ )
+ {
+ if(phtab[i].p_type == PT_LOAD && iBaseDiff > phtab[i].p_vaddr)
+ iBaseDiff = phtab[i].p_vaddr;
+ if( phtab[i].p_type == PT_DYNAMIC ) {
+ dynTab = (void*)(intptr_t)phtab[i].p_vaddr;
+ }
+ }
+ if( !dynTab ) {
+ SysDebug("ERROR - Unable to find DYNAMIC segment in %p", Base);
+ return 0;
+ }
+ iBaseDiff = (intptr_t)Base - iBaseDiff; // Make iBaseDiff actually the diff
+ dynTab = (void*)( (intptr_t)dynTab + iBaseDiff );
+
+ for( j = 0; dynTab[j].d_tag != DT_NULL; j++)
+ {
+ switch(dynTab[j].d_tag)
+ {
+ // --- Symbol Table ---
+ case DT_SYMTAB:
+ symtab = (void*)(intptr_t) dynTab[j].d_un.d_val; // Rebased in Relocate
+ break;
+ case DT_STRTAB:
+ dynstrtab = (void*)(intptr_t) dynTab[j].d_un.d_val;
+ break;
+ // --- Hash Table --
+ case DT_HASH:
+ pBuckets = (void*)(intptr_t) dynTab[j].d_un.d_val;
+ break;
+ }
+ }
+ }
+// DEBUGS("pBuckets = %p", pBuckets);
+
+ nbuckets = pBuckets[0];
+ iSymCount = pBuckets[1];
+ pBuckets = &pBuckets[2];
+// DEBUGS("nbuckets = %i", nbuckets);
+ pChains = &pBuckets[ nbuckets ];
+
+ // Get hash
+ iNameHash = ElfHashString(Name);
+ iNameHash %= nbuckets;
+
+ // Walk Chain
+ i = pBuckets[ iNameHash ];
+// DEBUGS("dynstrtab = %p", dynstrtab);
+// DEBUGS("symtab = %p, i = %i", symtab, i);
+ if(symtab[i].st_shndx != SHN_UNDEF && strcmp(dynstrtab + symtab[i].st_name, Name) == 0) {
+ *Ret = (void*) (intptr_t) symtab[i].st_value + iBaseDiff;
+ DEBUGS("%s = %p", Name, *Ret);
+ return 1;
+ }
+
+ while(pChains[i] != STN_UNDEF)
+ {
+ i = pChains[i];
+// DEBUGS("chains i = %i", i);
+ if(symtab[i].st_shndx != SHN_UNDEF && strcmp(dynstrtab + symtab[i].st_name, Name) == 0) {
+ *Ret = (void*)(intptr_t)symtab[i].st_value + iBaseDiff;
+ DEBUGS("%s = %p", Name, *Ret);
+ return 1;
+ }
+ }
+
+// DEBUGS("Elf64GetSymbol: RETURN 0, Symbol '%s' not found", Name);
+ return 0;
+}
+
+int Elf32GetSymbol(void *Base, const char *Name, void **ret)