void InitSymbolsLists(Elf32_Ehdr * eh,Elf32_Shdr * shdr,int shnum) { Elf32_Sym * symtab = 0; int nSyms = 0; char * strtab = 0; for (int i = 0; (i < shnum); i++) { if (shdr[i].sh_type == SHT_SYMTAB) { symtab = ELFADDR(Elf32_Sym, eh, shdr[i].sh_offset); nSyms = shdr[i].sh_size / shdr[i].sh_entsize; strtab = ELFADDR(char, eh, shdr[shdr[i].sh_link].sh_offset); break; } }
Elf32_Sym * ELFFile::FindSymbol(const TText *aName) { Elf32_Shdr * s = ELFADDR(Elf32_Shdr, iElfFile, iElfFile->e_shoff); TInt symIdx = iSymIdx; Elf32_Sym * sym = iSymTab; TInt nSyms = s[symIdx].sh_size / s[symIdx].sh_entsize; char * symStringtable = ELFADDR(char, iElfFile, s[s[symIdx].sh_link].sh_offset); for (TInt jdx = 0; jdx < nSyms; jdx++) { if (!strcmp(&symStringtable[sym[jdx].st_name], (char *)aName)) return &sym[jdx]; } return (Elf32_Sym *)0; }
TBool ELFFile::InitDllData(void) { if (!iDynamicSegmentHdr) { #if defined(_DEBUG) Print(EWarning, "Image '%s' has no import/export data.\n", iFileName); #endif return ETrue; } iDllData = new ELFDllData(this); if (!iDllData) { Print(EPeError, "Out of memory allocating DLL data\n"); return EFalse; } Elf32_Dyn * dyn = ELFADDR(Elf32_Dyn, iElfFile, iDynamicSegmentHdr->p_offset); TInt idx = 0; TInt soNameOffset = 0; while(dyn[idx].d_tag != DT_NULL) // best to make it explicit { switch (dyn[idx].d_tag) { case DT_HASH: iDllData->iHashTable = ELFADDR(Elf32_HashTable, dyn, dyn[idx].d_val); break; case DT_STRTAB: iDllData->iDynStrTab = ELFADDR(char, dyn, dyn[idx].d_val); break; case DT_SYMTAB: iDllData->iDynSymTab = ELFADDR(Elf32_Sym, dyn, dyn[idx].d_val); break; case DT_RELA: iDllData->iRela = ELFADDR(Elf32_Rela, dyn, dyn[idx].d_val); break; case DT_RELASZ: iDllData->iRelaSz = dyn[idx].d_val; break; case DT_RELAENT: iDllData->iRelaSz = dyn[idx].d_val; break; case DT_STRSZ: iDllData->iDynStrTabSize = dyn[idx].d_val; break; case DT_ARM_SYMTABSZ_21: //For RVCT2.1 //iDllData->iDynSymTabSize = dyn[idx].d_val; case DT_ARM_SYMTABSZ: /* This is same as DT_ARM_SYMTABSZ_21, but for RVCT 2.2 * The tag value has been changed for RVC2.2 from RVCT2.1. * We just ignore this. i.e., we get the symbol table size * from the nchain field of the hash table as noted in section * 3.2.2.2 of the BPABI. */ break; case DT_SYMENT: iDllData->iSymSize = dyn[idx].d_val; break; case DT_SONAME: soNameOffset = dyn[idx].d_val; break; case DT_REL: iDllData->iRel = ELFADDR(Elf32_Rel, dyn, dyn[idx].d_val); break; case DT_RELSZ: iDllData->iRelSz = dyn[idx].d_val; break; case DT_RELENT: iDllData->iRelEnt = dyn[idx].d_val; break; case DT_NEEDED: iDllData->AddToDependency(dyn[idx].d_val); break; case DT_PLTRELSZ: case DT_PLTGOT: case DT_INIT: case DT_FINI: case DT_RPATH: case DT_SYMBOLIC: case DT_PLTREL: case DT_DEBUG: case DT_TEXTREL: case DT_JMPREL: case DT_BIND_NOW: break; default: Print(EPeError,"Unrecognized Dyn Array tag in image '%s'.\n", iFileName); return EFalse; } idx++; } return iDllData->Init(); }
TBool ELFFile::InitHeaders(void) { TInt nphdrs = iElfFile->e_phnum; if (nphdrs) { // Find the dynamic segment Elf32_Phdr * aPhdr = ELFADDR(Elf32_Phdr, iElfFile, iElfFile->e_phoff); iPhdr = aPhdr; for (TInt idx = 0; idx < nphdrs; idx++) { Elf32_Word ptype = aPhdr[idx].p_type; if (ptype == PT_DYNAMIC) { iDynamicSegmentHdr = &aPhdr[idx]; iDynamicSegmentIdx = idx; } else if (ptype == PT_LOAD && (aPhdr[idx].p_flags & (PF_X + PF_ARM_ENTRY))) { iCodeSegmentHdr = &aPhdr[idx]; iCodeSegmentIdx = idx; } else if (ptype == PT_LOAD && (aPhdr[idx].p_flags & (PF_W + PF_R))) { iDataSegmentHdr = &aPhdr[idx]; iDataSegmentIdx = idx; } } } // cache pointer to symbol table // Get section header table Elf32_Shdr * s = ELFADDR(Elf32_Shdr, iElfFile, iElfFile->e_shoff); // Index of section header for section header string table TInt stIdx = iElfFile->e_shstrndx; TInt symIdx = -1; // Section name string table char * stringtable = ELFADDR(char, iElfFile, s[stIdx].sh_offset); // the index at which we find '.symtab' is the index of the symtab section for (TInt idx = 0; idx < iElfFile->e_shnum; idx++) { if (idx != stIdx) { if (!strcmp(&stringtable[s[idx].sh_name], ".symtab")) { symIdx = idx; break; } } } if (symIdx == -1) return EFalse; // save section header table iSectionHeaderTable = s; // save the index iSymIdx = symIdx; // here's the symbol table iSymTab = ELFADDR(Elf32_Sym, iElfFile, s[symIdx].sh_offset); return ETrue; }