--- a/bintools/elftools/elftran/elf_file.cpp Wed Jun 16 16:51:40 2010 +0300
+++ b/bintools/elftools/elftran/elf_file.cpp Wed Jun 23 16:56:47 2010 +0800
@@ -1,540 +1,527 @@
-/*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description:
-*
-*/
-
-
-
-#include <e32def.h>
-#include <e32std.h>
-#include "elftran.h"
-#include <elfdefs.h>
-#include "elffile.h"
-#include "elfdll.h"
-#include <h_utl.h>
-#include <string.h>
-#include <stdlib.h>
-
-TBool hadText, hadReloc = EFalse;
-
-ELFFile::ELFFile()
- :
- iHeapCommittedSize(0x1000),
- iHeapReservedSize(0x100000),
- iStackCommittedSize(0),
-
- iFileName(0),
- iFileHandle(-1),
- iElfFile(0),
-
- iDynamicSegmentHdr(0),
- iDynamicSegmentIdx(0),
-
- iCodeSegmentHdr(0),
- iCodeSegmentIdx(0),
-
- iDataSegmentHdr(0),
- iDataSegmentIdx(0),
-
- iDllData(0),
- iCpu(ECpuUnknown)
- {}
-
-
-
-
-ELFFile::~ELFFile()
- {
- delete [] iFileName;
- delete iElfFile;
- delete iDllData;
- }
-
-
-TBool ELFFile::Init(const TText * const aFileName)
-//
-// Read the ELF file into memory
-//
- {
-
- delete [] iFileName;
- iFileName = new TText[strlen((const char *)aFileName)+1];
- strcpy ((char *)iFileName, (const char *)aFileName);
-
- TInt error = HFile::Open(iFileName, &iFileHandle);
- if (error!=0)
- return EFalse;
-
- TInt flength = HFile::GetLength(iFileHandle);
-
- iElfFile = (Elf32_Ehdr *)HMem::Alloc(0,flength);
- if (!iElfFile)
- {
- Print(EPeError,"Failed to allocate memory to read in file.\n");
- Close();
- return EFalse;
- }
-
- if (!HFile::Read(iFileHandle,iElfFile,flength))
- {
- Print(EPeError,"Unable to read file %s.\n",iFileName);
- Close();
- return EFalse;
- }
-
- Close();
-
- if (!IsValidFileHeader(iElfFile))
- {
- Print(EPeError,"Invalid file header.\n");
- return EFalse;
- }
- // we only support this....for the moment
- iCpu = ECpuArmV4;
-
- if (!InitHeaders()) return EFalse;
-
- if (!InitDllData()) return EFalse;
-
- iEntryPoint = iElfFile->e_entry;
-
- iCodeSize = GetCodeSize();
- iDataSize = GetDataSize();
- iBssSize = GetBssSize();
-
- iStackReservedSize = 0x2000;
- iStackCommittedSize = 0x2000;
-
- iLinkedBase = iCodeSegmentHdr->p_vaddr;
-
- iImageIsDll = iDllData->ImageIsDll();
-
- return ETrue;
- }
-
-char * ELFFile::CreateImportSection(TInt &aSize)
-//
-// get ELFDLLData to do it
-//
- {
- TInt size;
- char * newSection = iDllData->CreateImportSection(size);
- aSize = size;
- return newSection;
- }
-
-TUint ELFFile::GetExportTableOffset(void)
- {
- return iDllData->GetExportTableOffset();
- }
-
-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;
- }
-
-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();
- }
-
-
-void ELFFile::Close()
-//
-// close the ELF file
-//
- {
- HFile::Close(iFileHandle);
- }
-
-
-
-TInt ELFFile::NumberOfImports() const
-//
-// Count the total number of imports for this image
-//
- {
- return iDllData->NumberOfImports();
- }
-
-TInt ELFFile::NumberOfImportDlls() const
-//
-// Count the number of referenced Dlls
-//
- {
- return iDllData->NumberOfImportDlls();
- }
-
-TInt ELFFile::NumberOfExports() const
-//
-// Count the number of exported symbols
-//
- {
- return iDllData->NumberOfExports();
- }
-
-TInt ELFFile::NumberOfCodeRelocs()
- {
- return iDllData->NumberOfCodeRelocs();
- }
-
-TInt ELFFile::NumberOfDataRelocs()
- {
- return iDllData->NumberOfDataRelocs();
- }
-
-Elf32_Phdr * ELFFile::GetSegmentFromAddr(Elf32_Addr addr)
- {
- TInt nphdrs = iElfFile->e_phnum;
- for (TInt idx = 0; idx < nphdrs; idx++)
- {
- // take advantage of unsignedness
- if ((addr - iPhdr[idx].p_vaddr) < iPhdr[idx].p_memsz) return &iPhdr[idx];
- }
- return NULL;
- }
-
-
-TInt ELFFile::NumberOfRelocs()
- {
- return iDllData->NumberOfRelocs();
- }
-
-TUint16 ELFFile::GetRelocType(Elf32_Rel *aReloc)
- {
- // We work out the type by figuring out the segment of the reloc
- TInt segmentIdx = ELF32_R_SYM(aReloc->r_info);
-
- // check to see if its a reserved or special index.
- if ((!segmentIdx) || ((segmentIdx >= SHN_LORESERVE) && (segmentIdx <= SHN_HIRESERVE)))
- // up until now these have been treated as KInferredRelocType, so lets continue...
- return KInferredRelocType;
-
- // need to see if this section is executable or writable
- if (iPhdr[segmentIdx-1].p_flags & PF_X)
- return KTextRelocType;
- if (iPhdr[segmentIdx-1].p_flags & PF_W)
- return KDataRelocType;
- // perhaps we should error here.
- return KInferredRelocType;
- }
-
-TBool ELFFile::GetRelocs(Elf32_Rel **aCodeRelocs, Elf32_Rel **aDataRelocs)
- {
- return iDllData->GetRelocs(aCodeRelocs, aDataRelocs);
- }
-
-TUint ELFFile::GetCodeSize()
- {
- return iCodeSegmentHdr->p_filesz;
- }
-
-TBool ELFFile::HasInitialisedData()
- {
- return iDataSegmentHdr != NULL && iDataSegmentHdr->p_filesz != 0;
- }
-
-TUint ELFFile::GetDataSize()
- {
- return iDataSegmentHdr != NULL ? iDataSegmentHdr->p_filesz : 0;
- }
-
-TBool ELFFile::HasBssData()
- {
- return iDataSegmentHdr != NULL && (iDataSegmentHdr->p_memsz - iDataSegmentHdr->p_filesz) != 0;
- }
-
-TUint ELFFile::GetBssSize()
- {
- return iDataSegmentHdr != NULL ? iDataSegmentHdr->p_memsz - iDataSegmentHdr->p_filesz: 0;
- }
-
-
-
-
-
-
-TBool ELFFile::IsValidFileHeader(Elf32_Ehdr * iElfFile)
- {
- if (!(iElfFile->e_ident[EI_MAG0] == ELFMAG0 &&
- iElfFile->e_ident[EI_MAG1] == ELFMAG1 &&
- iElfFile->e_ident[EI_MAG2] == ELFMAG2 &&
- iElfFile->e_ident[EI_MAG3] == ELFMAG3))
- {
- Print(EPeError,"Invalid ELF magic.\n");
- return EFalse;
- }
-
- if (iElfFile->e_ident[EI_CLASS] != ELFCLASS32)
- {
- Print(EPeError,"File is not a 32 bit object file.\n");
- return EFalse;
- }
- if (iElfFile->e_ident[EI_DATA] != ELFDATA2LSB)
- {
- Print(EPeError,"File data encoding is not Little Endian.\n");
- return EFalse;
- }
-
- if (iElfFile->e_machine != EM_ARM)
- {
- Print(EPeError,"File does not target ARM/THUMB processors.\n");
- return EFalse;
- }
-
- if (!(iElfFile->e_type == ET_EXEC || iElfFile->e_type == ET_DYN))
- {
- Print(EPeError,"File is neither an executable nor a shared object\n");
- return EFalse;
- }
-
- return ETrue;
- }
-
-
-// Get details of the next import to fix-up in the current file. Fill in the name of the dll
-//it is imported from, the ordinal number and the address to write back to.
-#define ORDINAL_DONE 0x40000000
-
-
-// The following static functions are passed an array of PE files to operate on
-
-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::SymbolPresent(TText *aName)
- {
- return (FindSymbol(aName) != 0);
- }
-
-TBool ELFFile::GetExceptionIndexInfo(TUint32 &aOffset)
- {
- const TText * aBase = (TText *)".ARM.exidx$$Base";
- const TText * aLimit = (TText *)".ARM.exidx$$Limit";
- Elf32_Sym * exidxBase = FindSymbol(aBase);
- Elf32_Sym * exidxLimit = FindSymbol(aLimit);
- if (exidxBase && exidxLimit && (exidxLimit->st_value - exidxBase->st_value))
- {
- const TText * aExceptionDescriptor = (TText *)"Symbian$$CPP$$Exception$$Descriptor";
- Elf32_Sym * aED = FindSymbol(aExceptionDescriptor);
- if (aED)
- {
- // Set bottom bit so 0 in header slot means an old binary.
- // The decriptor is always aligned on a 4 byte boundary.
- aOffset = (aED->st_value - iLinkedBase) | 0x00000001;
- return ETrue;
- }
- else
- {
- Print(EPeError,"Executable has exception table but no exception descriptor\n");
- exit(666);
- }
- }
- return EFalse;
- }
-
-TBool ELFFile::SetUpLookupTable()
-{
- if(!iDllData->CreateSymLookupTable() ) {
- Print(EPeError,"Failed to create named symbol lookup information\n");
- return FALSE;
- }
- if(!iDllData->CreateDependency()){
- Print(EPeError,"Failed to create dependency ordering for named symbol lookup\n");
- return FALSE;
- }
-
- iDllData->SetExportSymInfo();
- return TRUE;
-}
-
-void ELFFile::GetExportSymInfoHeader(E32EpocExpSymInfoHdr& aSymInfoHdr)
-{
- iDllData->GetExportSymInfoHeader(aSymInfoHdr);
-}
-
-void ELFFile::SetLookupTblBase(TInt aBaseOffset)
-{
- iDllData->SetLookupTblBase(aBaseOffset);
-}
-
-TInt ELFFile::GetLookupTblSize()
-{
- return iDllData->GetLookupTblSize();
-}
-
-TUint ELFFile::GetSymLookupSection(char* aBuff)
-{
- return iDllData->GetSymLookupSection(aBuff);
-}
-
+/*
+* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+#include <e32def.h>
+#include <e32std.h>
+#include "elftran.h"
+#include "elfdefs.h"
+#include "elffile.h"
+#include "elfdll.h"
+#include "h_utl.h"
+#include <string.h>
+#include <stdlib.h>
+
+TBool hadText, hadReloc = EFalse;
+
+ELFFile::ELFFile()
+ : iHeapCommittedSize(0x1000), iHeapReservedSize(0x100000), iStackCommittedSize(0),
+ iFileName(0), iFileHandle(-1) , iElfFile(0),
+ iDynamicSegmentHdr(0), iDynamicSegmentIdx(0),
+ iCodeSegmentHdr(0), iCodeSegmentIdx(0),
+ iDataSegmentHdr(0), iDataSegmentIdx(0),
+ iDllData(0), iCpu(ECpuUnknown)
+ {}
+
+ELFFile::~ELFFile()
+ //
+ // Destructor
+ //
+ {
+ if(iFileName)
+ delete [] iFileName;
+ delete iElfFile;
+ delete iDllData;
+ }
+
+
+TBool ELFFile::Init(const char* aFileName)
+//
+// Read the ELF file into memory
+//
+ {
+ if(iFileName){
+ delete [] iFileName;
+ iFileName = 0;
+ }
+ size_t length = strlen(aFileName) + 1 ;
+ iFileName = new char[length];
+ memcpy (iFileName, aFileName,length);
+
+ TInt error = HFile::Open(iFileName, &iFileHandle);
+ if (error!=0)
+ return EFalse;
+
+ TInt flength = HFile::GetLength(iFileHandle);
+
+ iElfFile = (Elf32_Ehdr *)HMem::Alloc(0,flength);
+ if (!iElfFile)
+ {
+ Print(EPeError,"Failed to allocate memory to read in file.\n");
+ Close();
+ return EFalse;
+ }
+
+ if (!HFile::Read(iFileHandle,iElfFile,flength))
+ {
+ Print(EPeError,"Unable to read file %s.\n",iFileName);
+ Close();
+ return EFalse;
+ }
+
+ Close();
+
+ if (!IsValidFileHeader(iElfFile))
+ {
+ Print(EPeError,"Invalid file header.\n");
+ return EFalse;
+ }
+ // we only support this....for the moment
+ iCpu = ECpuArmV4;
+
+ if (!InitHeaders()) return EFalse;
+
+ if (!InitDllData()) return EFalse;
+
+ iEntryPoint = iElfFile->e_entry;
+
+ iCodeSize = GetCodeSize();
+ iDataSize = GetDataSize();
+ iBssSize = GetBssSize();
+
+ iStackReservedSize = 0x2000;
+ iStackCommittedSize = 0x2000;
+
+ iLinkedBase = iCodeSegmentHdr->p_vaddr;
+
+ iImageIsDll = iDllData->ImageIsDll();
+
+ return ETrue;
+ }
+
+char * ELFFile::CreateImportSection(TInt &aSize)
+//
+// get ELFDLLData to do it
+//
+ {
+ TInt size;
+ char * newSection = iDllData->CreateImportSection(size);
+ aSize = size;
+ return newSection;
+ }
+
+TUint ELFFile::GetExportTableOffset(void)
+ {
+ return iDllData->GetExportTableOffset();
+ }
+
+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;
+ }
+
+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();
+ }
+
+
+void ELFFile::Close()
+//
+// close the ELF file
+//
+ {
+ HFile::Close(iFileHandle);
+ }
+
+
+
+TInt ELFFile::NumberOfImports() const
+//
+// Count the total number of imports for this image
+//
+ {
+ return iDllData->NumberOfImports();
+ }
+
+TInt ELFFile::NumberOfImportDlls() const
+//
+// Count the number of referenced Dlls
+//
+ {
+ return iDllData->NumberOfImportDlls();
+ }
+
+TInt ELFFile::NumberOfExports() const
+//
+// Count the number of exported symbols
+//
+ {
+ return iDllData->NumberOfExports();
+ }
+
+TInt ELFFile::NumberOfCodeRelocs()
+ {
+ return iDllData->NumberOfCodeRelocs();
+ }
+
+TInt ELFFile::NumberOfDataRelocs()
+ {
+ return iDllData->NumberOfDataRelocs();
+ }
+
+Elf32_Phdr * ELFFile::GetSegmentFromAddr(Elf32_Addr addr)
+ {
+ TInt nphdrs = iElfFile->e_phnum;
+ for (TInt idx = 0; idx < nphdrs; idx++)
+ {
+ // take advantage of unsignedness
+ if ((addr - iPhdr[idx].p_vaddr) < iPhdr[idx].p_memsz) return &iPhdr[idx];
+ }
+ return NULL;
+ }
+
+
+TInt ELFFile::NumberOfRelocs()
+ {
+ return iDllData->NumberOfRelocs();
+ }
+
+TUint16 ELFFile::GetRelocType(Elf32_Rel *aReloc)
+ {
+ // We work out the type by figuring out the segment of the reloc
+ TInt segmentIdx = ELF32_R_SYM(aReloc->r_info);
+
+ // check to see if its a reserved or special index.
+ if ((!segmentIdx) || ((segmentIdx >= SHN_LORESERVE) && (segmentIdx <= SHN_HIRESERVE)))
+ // up until now these have been treated as KInferredRelocType, so lets continue...
+ return KInferredRelocType;
+
+ // need to see if this section is executable or writable
+ if (iPhdr[segmentIdx-1].p_flags & PF_X)
+ return KTextRelocType;
+ if (iPhdr[segmentIdx-1].p_flags & PF_W)
+ return KDataRelocType;
+ // perhaps we should error here.
+ return KInferredRelocType;
+ }
+
+TBool ELFFile::GetRelocs(Elf32_Rel **aCodeRelocs, Elf32_Rel **aDataRelocs)
+ {
+ return iDllData->GetRelocs(aCodeRelocs, aDataRelocs);
+ }
+
+TUint ELFFile::GetCodeSize()
+ {
+ return iCodeSegmentHdr->p_filesz;
+ }
+
+TBool ELFFile::HasInitialisedData()
+ {
+ return iDataSegmentHdr != NULL && iDataSegmentHdr->p_filesz != 0;
+ }
+
+TUint ELFFile::GetDataSize()
+ {
+ return iDataSegmentHdr != NULL ? iDataSegmentHdr->p_filesz : 0;
+ }
+
+TBool ELFFile::HasBssData()
+ {
+ return iDataSegmentHdr != NULL && (iDataSegmentHdr->p_memsz - iDataSegmentHdr->p_filesz) != 0;
+ }
+
+TUint ELFFile::GetBssSize()
+ {
+ return iDataSegmentHdr != NULL ? iDataSegmentHdr->p_memsz - iDataSegmentHdr->p_filesz: 0;
+ }
+
+
+
+
+
+
+TBool ELFFile::IsValidFileHeader(Elf32_Ehdr * iElfFile)
+ {
+ if (!(iElfFile->e_ident[EI_MAG0] == ELFMAG0 &&
+ iElfFile->e_ident[EI_MAG1] == ELFMAG1 &&
+ iElfFile->e_ident[EI_MAG2] == ELFMAG2 &&
+ iElfFile->e_ident[EI_MAG3] == ELFMAG3))
+ {
+ Print(EPeError,"Invalid ELF magic.\n");
+ return EFalse;
+ }
+
+ if (iElfFile->e_ident[EI_CLASS] != ELFCLASS32)
+ {
+ Print(EPeError,"File is not a 32 bit object file.\n");
+ return EFalse;
+ }
+ if (iElfFile->e_ident[EI_DATA] != ELFDATA2LSB)
+ {
+ Print(EPeError,"File data encoding is not Little Endian.\n");
+ return EFalse;
+ }
+
+ if (iElfFile->e_machine != EM_ARM)
+ {
+ Print(EPeError,"File does not target ARM/THUMB processors.\n");
+ return EFalse;
+ }
+
+ if (!(iElfFile->e_type == ET_EXEC || iElfFile->e_type == ET_DYN))
+ {
+ Print(EPeError,"File is neither an executable nor a shared object\n");
+ return EFalse;
+ }
+
+ return ETrue;
+ }
+
+
+// Get details of the next import to fix-up in the current file. Fill in the name of the dll
+//it is imported from, the ordinal number and the address to write back to.
+#define ORDINAL_DONE 0x40000000
+
+
+// The following static functions are passed an array of PE files to operate on
+
+Elf32_Sym * ELFFile::FindSymbol(const char* 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::SymbolPresent(const char* aName)
+ {
+ return (FindSymbol(aName) != 0);
+ }
+
+TBool ELFFile::GetExceptionIndexInfo(TUint32 &aOffset)
+ {
+ Elf32_Sym * exidxBase = FindSymbol(".ARM.exidx$$Base");
+ Elf32_Sym * exidxLimit = FindSymbol(".ARM.exidx$$Limit");
+ if (exidxBase && exidxLimit && (exidxLimit->st_value - exidxBase->st_value))
+ {
+ Elf32_Sym * aED = FindSymbol("Symbian$$CPP$$Exception$$Descriptor");
+ if (aED)
+ {
+ // Set bottom bit so 0 in header slot means an old binary.
+ // The decriptor is always aligned on a 4 byte boundary.
+ aOffset = (aED->st_value - iLinkedBase) | 0x00000001;
+ return ETrue;
+ }
+ else
+ {
+ Print(EPeError,"Executable has exception table but no exception descriptor\n");
+ exit(666);
+ }
+ }
+ return EFalse;
+ }
+
+TBool ELFFile::SetUpLookupTable()
+{
+ if(!iDllData->CreateSymLookupTable() ) {
+ Print(EPeError,"Failed to create named symbol lookup information\n");
+ return FALSE;
+ }
+ if(!iDllData->CreateDependency()){
+ Print(EPeError,"Failed to create dependency ordering for named symbol lookup\n");
+ return FALSE;
+ }
+
+ iDllData->SetExportSymInfo();
+ return TRUE;
+}
+
+void ELFFile::GetExportSymInfoHeader(E32EpocExpSymInfoHdr& aSymInfoHdr)
+{
+ iDllData->GetExportSymInfoHeader(aSymInfoHdr);
+}
+
+void ELFFile::SetLookupTblBase(TInt aBaseOffset)
+{
+ iDllData->SetLookupTblBase(aBaseOffset);
+}
+
+TInt ELFFile::GetLookupTblSize()
+{
+ return iDllData->GetLookupTblSize();
+}
+
+TUint ELFFile::GetSymLookupSection(char* aBuff)
+{
+ return iDllData->GetSymLookupSection(aBuff);
+}
+