- // === Parse Relocation Data ===
- TRACE("dynamicTab = 0x%x", dynamicTab);
- for( int j = 0; dynamicTab[j].d_tag != DT_NULL; j++)
- {
- const Elf32_Dyn *dt = &dynamicTab[j];
- switch(dt->d_tag)
- {
- // --- Shared Library Name ---
- case DT_SONAME:
- TRACE(".so Name '%s'", dynstrtab + dt->d_val);
- break;
- // --- Needed Library ---
- case DT_NEEDED:
- //assert(dt->d_val <= sizeof_dynstrtab);
- libPath = dynstrtab + dt->d_val;
- TRACE(" Required Library '%s'", libPath);
- if(LoadLibrary(libPath, NULL, envp) == 0) {
- SysDebug("Unable to load required library '%s'", libPath);
- return 0;
- }
- TRACE(" Lib loaded");
- break;
- // --- PLT/GOT ---
-// case DT_PLTGOT: pltgot = (void*)(iBaseDiff + dt->d_val); break;
- case DT_JMPREL: plt = (void*)(iBaseDiff + dt->d_val); break;
- case DT_PLTREL: pltType = dt->d_val; break;
- case DT_PLTRELSZ: pltSz = dt->d_val; break;
-
- // --- Relocation ---
- case DT_REL: rel = (void*)(iBaseDiff + dt->d_val); break;
- case DT_RELSZ: relSz = dt->d_val; break;
- case DT_RELENT: relEntSz = dt->d_val; break;
- case DT_RELA: rela = (void*)(iBaseDiff + dt->d_val); break;
- case DT_RELASZ: relaSz = dt->d_val; break;
- case DT_RELAENT: relaEntSz = dt->d_val; break;
-
- // --- Symbol Table ---
- case DT_SYMTAB:
- // --- Hash Table ---
- case DT_HASH:
- // --- String Table ---
- case DT_STRTAB:
- break;
-
- // --- Unknown ---
- default:
- if(dt->d_tag > DT_JMPREL) continue;
- //DEBUGS(" elf_relocate: %i-%i = %s,0x%x",
- // i,j, csaDT_NAMES[dynamicTab[j].d_tag],dynamicTab[j].d_val);
- break;
- }
- }
-
- // Resolve symbols (second pass)
- // - #0 is defined as ("" SHN_UNDEF), so skip it
- int fail = 0;
- for( int i = 1; i < iSymCount; i ++ )
- {
- Elf32_Sym *sym = &dynsymtab[i];
- const char *name = dynstrtab + sym->st_name;
- if( sym->st_shndx == SHN_UNDEF )
- {
- void *newval;
- size_t newsize;
- if( !GetSymbol(name, &newval, &newsize, Base) ) {
- if( ELF32_ST_BIND(sym->st_info) != STB_WEAK ) {
- // Not a weak binding, set fail and move on
- WARNING("Elf32Relocate: Can't find required symbol '%s' for '%s'",
- name, Filename);
- fail = 1;
- continue ;
- }
- // Leave the symbol value as-is
- }
- else {
- TRACE("Sym %i'%s' bound to %p+0x%x", i, name, newval, newsize);
- sym->st_value = (intptr_t)newval;
- sym->st_size = newsize;
- }
- }
- else if( sym->st_shndx == SHN_ABS )
- {
- // Leave as is
- }
- else
- {
- // Handled previously
- // TODO: What about weak locally-defined symbols?
- //assert( ELF32_ST_BIND(sym->st_info) != STB_WEAK );
- }
- }
- if( fail ) {
- WARNING("Relocation of '%s' failed", Filename);
- return NULL;
- }
-
- TRACE("Beginning Relocation on '%s'", Filename);