bintools/elftools/elftran/elf_file.cpp
changeset 590 360bd6b35136
parent 0 044383f39525
--- 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);
+}
+