bintools/elftools/elftran/elf_dlld.cpp
changeset 590 360bd6b35136
parent 0 044383f39525
--- a/bintools/elftools/elftran/elf_dlld.cpp	Wed Jun 16 16:51:40 2010 +0300
+++ b/bintools/elftools/elftran/elf_dlld.cpp	Wed Jun 23 16:56:47 2010 +0800
@@ -1,954 +1,928 @@
-/*
-* 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 <string.h>
-#include <stdlib.h>
-#include <e32std.h>
-#include <elfdefs.h>
-#include "elfdll.h"
-#include "elffile.h"
-#include <h_utl.h>
-#include <e32ldr.h>
-
-ELFFile::ELFDllData::ELFDllData(ELFFile * f)
-    :
-        iElfFile(f),
-
-        iDynStrTab(0),
-        iDynStrTabSize(0),
-        iDynSymTab(0),
-
-        iSymSize(0),
-        iRela(0),
-        iRelaSz(0),
-        iRelaEnt(0),
-
-        iRel(0),
-        iRelSz(0),
-        iRelEnt(0),
-
-        iHashTable(0),
-
-        iNamedExportSymbolHead(0),
-        iNamedExportCount(0),
-
-        iSymStringTableSize(0),
-        iStringNameOffset(0),
-
-        iDepRecords(0),
-        iDepRecordsTail(0),
-
-        iNeededDllNames(0),
-        iNeededDllNamesTail(0),
-
-        iOrdZeroRec(0),
-
-        iNamedLookupEnabled(0),
-
-        iDllHead(0),
-        iDllTail(0),
-
-        iNumberOfImports(0),
-        iNumberOfExports(0),
-        iNumberOfImportDlls(0),
-
-        iStringTableSize(0),
-
-        iNumberOfRelocs(0),
-        iNumberOfCodeRelocs(0),
-        iNumberOfDataRelocs(0)
-		{
-		}
-
-ELFFile::ELFDllData::~ELFDllData()
-	{
-		delete iOrdZeroRec;
-		delete iDepRecords;
-		delete iNeededDllNames;
-	}
-
-TBool ELFFile::ELFDllData::Init()
-	{
-	// process imported symbols
-	// There will be at least one relocation (assumed to be Elf32_Rel) for each such symbol.
-	// S iterate over relocations looking for DLL symbols and add them to the record of
-	// of import info.
-	TInt nrelocs = iRelSz/iRelEnt;
-	TInt SrcSegIdx = -1;
-	TInt errors = 0;
-
-	for (TInt idx = 0; idx < nrelocs; idx++)
-			{
-			Elf32_Rel * rel = &iRel[idx];
-			TUint relType = ELF32_R_TYPE(rel->r_info);
-
-			if (relType == R_ARM_ABS32)      
-					{	
-					TInt symIdx = ELF32_R_SYM(rel->r_info);
-					Elf32_Sym * sym = &iDynSymTab[symIdx];
-					DllSymbol * dllSym = DllSymbolP(sym);
-					if (dllSym) 
-							{
-							dllSym->iRel = rel;
-							dllSym->iSegment = iElfFile->GetSegment(SrcSegIdx);
-							if (!AddSymbol(dllSym)) return EFalse;
-							}
-					else errors++;
-					}
-			else if (relType == R_ARM_RABS32)
-					{
-					iNumberOfRelocs++;
-					if (iElfFile->CodeSegmentP(SrcSegIdx)) iNumberOfCodeRelocs++;
-					else iNumberOfDataRelocs++;
-					}
-			else if (relType == R_ARM_RBASE)
-				    {
-					SrcSegIdx = ELF32_R_SYM(rel->r_info);
-					if (SrcSegIdx) SrcSegIdx--;
-					}
-			else 
-				    {
-					// Gives error with all other Relocation types..
-					TInt symIdx = ELF32_R_SYM(rel->r_info);
-					Elf32_Sym * s = &iDynSymTab[symIdx];
-					char * symName = ELFADDR(char,iDynStrTab,s->st_name);
-					Print(EPeError, "Unresolved symbol: %s\n", symName);
-					errors++;
-					}
-			}
-	// Set up export info
-	if (InitExportInfo())
-	       {
-	       TText * sym = (TText *)"_E32Startup";
-	       // If _E32Startup is defined then this is not a DLL
-	       iImageIsDll = !iElfFile->SymbolPresent(sym);
-	       }
-	if (errors > 0) return EFalse;
-	return ETrue;
-	}
-
-TBool ELFFile::ELFDllData::ParseDllSymbol(Elf32_Sym * s, char *& dll, TUint& len, TInt& ord)
-    {
-	char * sym = ELFADDR(char,iDynStrTab,s->st_name);
-	if (!strncmp(sym, DLLSYMPREFIX, strlen(DLLSYMPREFIX)))
-			{
-			dll = sym + strlen(DLLSYMPREFIX);
-			TUint lim = strlen(dll);
-			TUint index = strcspn(dll, DLLSYMPREFIX0);
-			if ((index + strlen(DLLSYMSUFFIX)) < lim)
-					{
-					len = index;
-					char * dllSuffix = dll+index;
-					char * match = DLLSYMSUFFIX;
-					int suflen = strlen(DLLSYMSUFFIX);
-					if (!strncmp(dllSuffix, match, suflen))
-							{
-							char * ordString = dll+index+suflen;
-							char * final;
-							TUint X = strtoul(ordString, &final, ORDBASE);
-							if (ordString != final)
-									{
-									ord = (TInt)X;
-									return ETrue;
-									}
-			     
-							}
-					}
-			}
-	dll = 0;
-	len = 0;
-	ord = -1;
-	return EFalse;
-	}
-
-ELFFile::ELFDllData::DllSymbol * ELFFile::ELFDllData::DllSymbolP(Elf32_Sym * s)
-    {
-	char * dllName;
-	TUint nameLen;
-	TInt symOrd;
-	if (ParseDllSymbol(s, dllName, nameLen, symOrd))
-	       {
-	       DllSymbol * ds = new DllSymbol(dllName, nameLen, symOrd);
-	       if (ds) return ds;
-	       Print(EPeError, "Out of memory.\n");
-	       return NULL;
-	       }
-	// If we get here its not a valid 'dll symbol' and so it is an unresolved symbol
-	char * sym = ELFADDR(char,iDynStrTab,s->st_name);
-	Print(EPeError, "Unresolved symbol: %s\n", sym);
-    return NULL;
-	}
-
-TBool ELFFile::ELFDllData::AddSymbol(ELFFile::ELFDllData::DllSymbol * s)
-    {
-	DllRec * aDll = NULL;
-     
-	for (DllRec * r = iDllHead; r != NULL; r = r->iNext)
-			{
-			if (!strncmp(s->iDll, r->iName, s->iLen))
-					{
-					aDll = r;
-					break;
-					}
-			}
-	if (aDll)
-			{
-		    iNumberOfImports++;
-		    aDll->AddSymbol(s);
-			return ETrue;
-			}
-	else
-			{
-			aDll = new DllRec(s->iDll, s->iLen, s);
-			if (aDll)
-					{
-					if (!iDllHead) 
-							{
-							iDllHead = iDllTail = aDll;
-							}
-					else
-							{
-							iDllTail->iNext = aDll;
-							iDllTail = aDll;
-							}
-					iStringTableSize += (s->iLen + 1);
-	      			iNumberOfImportDlls++;
-					iNumberOfImports++;
-					return ETrue;
-					}
-			else
-					{
-					Print(EPeError, "Out of memory.\n");
-					return EFalse;
-					}
-			}
-	}
-
-void ELFFile::ELFDllData::DllRec::AddSymbol(ELFFile::ELFDllData::DllSymbol * s)
-	{
-	nImports++;
-    iTail->iNext = s;
-    iTail = s;
-    }
-
-static unsigned long elf_hash(const unsigned char *name)
-    {
-    unsigned long h, g;
-    for (h = 0; *name != 0; ++name)
-	        {
-			h = (h << 4) + *name;
-			g = h & 0xf0000000;
-			if (g != 0) h ^= g >> 24;
-			h &= ~g;
-			}
-	return h;
-    }
-
-Elf32_Word ELFFile::ELFDllData::FindSymbolIndex(TText * s)
-    {
-	TUint h = elf_hash(s);
-	TUint nb = iHashTable[0].nBuckets;
-	TUint probe = h%nb;
-	Elf32_Sword * bucket = ELFADDR(Elf32_Sword, iHashTable, sizeof(Elf32_HashTable));
-	Elf32_Sword * chain = ELFADDR(Elf32_Sword, bucket, nb * sizeof(Elf32_Sword));
-	Elf32_Sword idx = bucket[probe];
-
-	do 	
-			{
-			if (!strcmp(ELFADDR(char, iDynStrTab, iDynSymTab[idx].st_name), (char *)s)) return idx;
-			idx = chain[idx];
-			} while (idx > 0);
-	if (idx == 0) idx = -1;
-	return idx;
-	}
-
-TBool ELFFile::ELFDllData::InitExportInfo()
-	{
-	memset(&iSymInfoHdr, 0, sizeof(iSymInfoHdr));
-	TText * exp = (TText *)EXPORTTABLENAME;
-	if ( int(iExportTableSymIdx = FindSymbolIndex(exp)) != -1 )
-			{
-			TText * exps = (TText *)EXPORTTABLESIZENAME;
-			iExportTableSizeSymIdx = FindSymbolIndex(exps);
-			//TUint offset = iDynSymTab[iExportTableSizeSymIdx].st_value - (TUint)code;
-			Elf32_Word * pNumberOfExports = iElfFile->CodePtrFromAddr(iDynSymTab[iExportTableSizeSymIdx].st_value);
-			iNumberOfExports = * pNumberOfExports;
-			iImageIsDll = ETrue;
-			return ETrue;
-			}
-	else iImageIsDll = EFalse;
-	return EFalse;
-	}
-
-TInt ELFFile::ELFDllData::NumberOfImports(void)
-    {
-	return iNumberOfImports;
-	}
-
-TInt ELFFile::ELFDllData::NumberOfExports(void)
-    {
-	return iNumberOfExports;
-	}
-
-TInt ELFFile::ELFDllData::NumberOfImportDlls(void)
-    {
-	return iNumberOfImportDlls;
-	}
-
-TInt ELFFile::ELFDllData::NumberOfRelocs()
-	{
-	return iNumberOfRelocs;
-	}
-
-char * ELFFile::ELFDllData::CreateImportSection(TInt &aSize)
-	{
-	if (!iNumberOfImports)
-			{
-			aSize = 0;
-			return 0;
-			}
-
-	TInt byteSize = sizeof(E32ImportSection) + 
-	                (sizeof(E32ImportBlock) * iNumberOfImportDlls) +
-					(sizeof(TUint) * iNumberOfImports) +
-					iStringTableSize;
-	if(iNamedLookupEnabled)
-	{
-		// 0th ordinal of each DLL imported from.
-		byteSize += (sizeof(TUint) * iNumberOfImportDlls);
-	}
-	char * newSection = new char[byteSize];
-
-	if (!newSection)
-	       {
-	       Print(EPeError, "Failed to allocate new import section.\n");
-	       aSize = 0;
-	       return 0;
-	       }
-
-	((E32ImportSection *)newSection)->iSize = byteSize;
-
-	// used to point to current ImportBlock
-	E32ImportBlock * bp = ELFADDR(E32ImportBlock, newSection, sizeof(E32ImportSection));
-	// used to point to current import relocation entry
-	TUint * rp;
-	// used to point to current location in string table
-	char * sp = ELFADDR(char, newSection, (byteSize - iStringTableSize));
-	OrdZeroRecord *aDep = iDepRecords;
-
-	for (DllRec * dll = iDllHead; dll != NULL ; dll = dll->iNext, bp = (E32ImportBlock *)rp )
-	        {
-			// set up the offset from E32ImportBlock.iOffsetOfDllName to the
-			// corresponding  string table location
-			bp->iOffsetOfDllName = (sp - (char *)newSection);
-			bp->iNumberOfImports = dll->nImports;
-			if(iNamedLookupEnabled)
-			{
-				bp->iNumberOfImports++;
-			}
-
-			// copy the DLL name to the string table
-			memcpy(sp , dll->iName, dll->iLen);
-			sp[dll->iLen] = 0;
-			sp = sp + dll->iLen + 1;
-
-			// sort out the import 'relocs'
-			rp = ELFADDR(TUint, bp, sizeof(E32ImportBlock));
-		
-			for (DllSymbol * sym = dll->iHead; sym != NULL; sym = sym->iNext, rp++)
-				    {
-					Elf32_Phdr * segment = sym->iSegment;
-					Elf32_Addr segBase = segment->p_vaddr;
-
-					// sanity check: segment should be the code segment
-					if (!iElfFile->CodeSegmentP(segment))
-							{
-							Print(EPeError, "Import relocation does not refer to code segment.\n");
-							aSize = 0;
-							return 0;
-							}
-
-					// This field is misnamed because it is actually given as a virtual address in 
-					// dynamic relocations
-					Elf32_Addr dynOffset = sym->iRel->r_offset;
-					//So this is the 'real' offset of the reloc in  the segment in which it occurs
-					Elf32_Addr segOffset = dynOffset - segBase;
-					TUint * relocAddr = ELFADDR(TUint, iElfFile->ELFFileBase(), (segment->p_offset + segOffset));
-					// The only non-zero reloc vals we expect are for vtables.
-					// We store there reloc offset in the top 16 bits of the 'reloc info'.
-					// NB the ELF reloc values should only ever be multiples of 4. So we could optimize here,
-					// but we won't.
-					TUint relocVal = *relocAddr;
-					TUint importOrdinal = sym->iOrd;
-					if (relocVal > 0xFFFF)
-							Print(EPeError, "ELF relocation exceeds E32Image limit of 64K.\n");
-					if (importOrdinal > 0xFFFF)
-							Print(EPeError, "Import ordinal exceeds E32Image limit of 64K.\n");
-   
-   					*rp = segOffset;
-   			
-   					// eek !! surgery on the code segment....
-					*relocAddr = (relocVal<<16) | importOrdinal;
-					}
-			
-				if(iNamedLookupEnabled)
-				{
-					aDep = FindDependency(dll->iName, dll->iLen);
-					if( aDep )
-					{
-						*rp = aDep->iOffset;
-						rp++;
-					}
-				}
-			}
-	
-	aSize = byteSize;
-	return newSection;
-	}
-
-TUint ELFFile::ELFDllData::GetExportTableOffset(void)
-    {
-	Elf32_Sym * et = &iDynSymTab[iExportTableSymIdx];
-	Elf32_Phdr * segment = iElfFile->GetSegment(et->st_shndx - 1);
-	
-	return et->st_value - segment->p_vaddr;
-	}
-
-TBool ELFFile::ELFDllData::GetRelocs(Elf32_Rel **aCodeRelocs, Elf32_Rel **aDataRelocs)
-	//	
-	// load the relocs from the reloc section into relocation and relocsection arrays
-	//
-	{
-	TInt nrelocs = iRelSz/iRelEnt;
-
-	TInt SrcSegIdx = -1;
-
-	TInt cidx = 0;
-	TInt didx = 0;
-
-	for (TInt idx = 0; idx < nrelocs; idx++)
-	        {
-			Elf32_Rel * rel = &iRel[idx];
-
-			if (ELF32_R_TYPE(rel->r_info) == R_ARM_RABS32)
-					{
-					if (iElfFile->CodeSegmentP(SrcSegIdx))
-							aCodeRelocs[cidx++]=rel;
-					else if (iElfFile->DataSegmentP(SrcSegIdx))
-							aDataRelocs[didx++]=rel;
-					}
-			else if (ELF32_R_TYPE(rel->r_info) == R_ARM_RBASE)
-					{
-					SrcSegIdx = ELF32_R_SYM(rel->r_info);
-					if (!(iElfFile->CodeSegmentP(SrcSegIdx-1) || iElfFile->DataSegmentP(SrcSegIdx-1)))
-							{
-							Print(EPeError, "Source segment for relocations is neither Code or Data.\n");
-							return EFalse;
-							}
-					SrcSegIdx--;
-					}
-			}
-
-	if(!iNamedLookupEnabled)
-		return ETrue;
-
-	// Add the 0th ordinal of this binary - The relocation info is already setup.
-	aCodeRelocs[cidx++] = &iOrdZeroRec->iReloc;
-
-	// add relocation entries for each of the symbols
-	NamedExportSymbol *aSym = iNamedExportSymbolHead;
-	while(aSym)
-	{
-		// The symbol name info is part of the code section hence all relocations
-		// are collected as part of Code relocations.
-		aCodeRelocs[cidx++] = &aSym->iReloc;
-		aSym = aSym->Next();
-	}
-
-	// Since we have added a few relocations, lets make sure
-	// they are still sorted on addresses they refer to.
-	
-	//Sorting the code relocs
-	TInt aIdx1, aIdx2;
-	Elf32_Rel *aTmp;
-	for (aIdx1 = 0; aIdx1 < cidx; aIdx1++) {
-		for (aIdx2 = aIdx1; aIdx2 < cidx; aIdx2++) {
-			if(aCodeRelocs[aIdx1]->r_offset > aCodeRelocs[aIdx2]->r_offset) {
-				aTmp = aCodeRelocs[aIdx2];
-				aCodeRelocs[aIdx2] = aCodeRelocs[aIdx1];
-				aCodeRelocs[aIdx1] = aTmp;
-			}
-		}
-	}
-	
-	//Sorting the data relocs
-	for (aIdx1 = 0; aIdx1 < didx; aIdx1++) {
-		for (aIdx2 = aIdx1; aIdx2 < didx; aIdx2++) {
-			if(aDataRelocs[aIdx1]->r_offset > aDataRelocs[aIdx2]->r_offset) {
-				aTmp = aDataRelocs[aIdx2];
-				aDataRelocs[aIdx2] = aDataRelocs[aIdx1];
-				aDataRelocs[aIdx1] = aTmp;
-			}
-		}
-	}
-
-	return ETrue;
-	}
-
-NamedExportSymbol::NamedExportSymbol(char* aName, Elf32_Addr aValue) : \
-	iSymbolName(aName), iValue(aValue), iNext(NULL)
-{
-}
-
-TBool ELFFile::ELFDllData::CreateSymLookupTable()
-{
-	if( !SetupSymbolValues() )
-		return FALSE;
-
-	if( !SetupSymbolNames() )
-		return FALSE;
-
-	return TRUE;
-}
-
-TBool ELFFile::ELFDllData::SetupSymbolValues()
-{
-	NamedExportSymbol *aSym, *aPrevSym;
-
-	if( int(iExportTableSymIdx) == -1 || int(iExportTableSizeSymIdx) == -1)
-		return FALSE;
-
-	// Fetch the 'export table' symbol from the dynamic symbol table.
-	Elf32_Sym *aElfExpTbl = &iDynSymTab[iExportTableSymIdx];
-
-	// Fetch the 'export table size' symbol from the dynamic symbol table.
-	Elf32_Sym *aElfExpTblSz = &iDynSymTab[iExportTableSizeSymIdx];
-
-	if((aElfExpTbl->st_value - aElfExpTblSz->st_value) != 4)
-	{
-		// Check that the word prior to the export table is not the export table size
-		// This is to make sure that there is space for the 0th ordinal and
-		// we dont overwrite the 'export table size' entry.
-		iNamedLookupEnabled = 1;
-	}
-	else 
-		return FALSE;
-
-	// Fetch the export table contents
-	Elf32_Word * aExpEntries = iElfFile->CodePtrFromAddr(aElfExpTbl->st_value);
-
-	if(!aExpEntries)
-		return FALSE;
-
-	aSym = aPrevSym = NULL;
-	TInt idx;
-	// Create symbols corresponding to export table entries.
-	for(idx = 0;  idx < iNumberOfExports; idx++)
-	{
-		//Symbols marked Absent are ignored.
-		if( aExpEntries[idx] == iElfFile->iEntryPoint)
-			continue;
-
-		aSym = new NamedExportSymbol(0, aExpEntries[idx]);
-		iNamedExportCount++;
-		if(aPrevSym)
-		{
-			aPrevSym->Next(aSym);
-		}
-		else
-		{
-			iNamedExportSymbolHead = aSym;
-		}
-
-		aPrevSym = aSym;
-	}
-
-	return TRUE;
-}
-
-TBool ELFFile::ELFDllData::SetupSymbolNames()
-{
-	char *aSymName = NULL;
-	NamedExportSymbol *aSym;
-	TUint aDynSymbolTblCount = iHashTable->nChains;
-	TInt aCount = 0;
-	TInt aCodeSegIdx = iElfFile->CodeSegmentIndex() + 1;
-	TInt aDataSegIdx = iElfFile->DataSegmentIndex() + 1;
-
-	// Traverse the dynamic symbol table
-	for(TUint idx = 0; idx < aDynSymbolTblCount; idx++)
-	{
-		//Consider only the the defined symbols
-		if( ELF32_ST_TYPE(iDynSymTab[idx].st_info) == STT_OBJECT || 
-			ELF32_ST_TYPE(iDynSymTab[idx].st_info) == STT_FUNC )
-		{
-			aSym = iNamedExportSymbolHead;
-			while(aSym)
-			{
-				// Name already set
-				if(aSym->Name())
-				{
-					aSym = aSym->Next();
-					continue;
-				}
-				Elf32_Addr aAddr = aSym->Value();
-
-				// If the exported symbol and the dynamic symbol table entry have the 
-				// same values, setup the name
-				if(iDynSymTab[idx].st_value == aAddr)
-				{
-					aSymName = ELFADDR(char, iDynStrTab, iDynSymTab[idx].st_name);
-					aSym->Name(aSymName);
-					
-					if(iElfFile->CodeSegmentP (iElfFile->GetSegmentFromAddr(aAddr)) ) {
-						aSym->iReloc.r_info = aCodeSegIdx << 8 | R_ARM_RABS32;
-						aSym->iSymRelocType = KTextRelocType;
-					}
-					else {
-						aSym->iReloc.r_info = aDataSegIdx << 8 | R_ARM_RABS32;
-						aSym->iSymRelocType = KDataRelocType;
-					}
-					
-					iNumberOfCodeRelocs++;
-					iNumberOfRelocs++;
-
-					// The offset to the name is always 4 byte aligned.
-					iStringNameOffset = iSymStringTableSize >> 2;
-					aSym->NameOffset( iSymStringTableSize );
-					// These are NULL-terminated strings
-					iSymStringTableSize += (strlen(aSymName) + 1);
-					iSymStringTableSize = ALIGN4(iSymStringTableSize);
-
-					aCount++;
-					break;
-				}
-				aSym = aSym->Next();
-			}
-		}
-	}
-
-	if(aCount != iNamedExportCount)
-		return FALSE;
-
-	// Sort symbols on their names...
-	if(iNamedExportCount > 1)
-	{
-		NamedExportSymbol **aTmpStart = &iNamedExportSymbolHead;
-		Sort(aTmpStart, iNamedExportSymbolHead);
-	}
-
-	return TRUE;
-}
-
-void ELFFile::ELFDllData::SetLookupTblBase(TInt aBaseOffset)
-{
-	Elf32_Addr	aBaseAddr = iElfFile->iLinkedBase + iElfFile->GetCodeSize();
-
-	Elf32_Addr	aAddr;
-
-	// setup relocations of each of the exported symbols.
-	aAddr = aBaseAddr + iSymInfoHdr.iSymbolTblOffset;
-	NamedExportSymbol *aSym = iNamedExportSymbolHead;
-	while(aSym)
-	{
-		aSym->iReloc.r_offset = aAddr;
-		aAddr += sizeof(Elf32_Addr);
-		aSym = aSym->Next();
-	}
-
-	// setup relocations for the 0th ordinal of this binary. 
-
-	iOrdZeroRec = new OrdZeroRecord(0);
-	Elf32_Sym * et = &iDynSymTab[iExportTableSymIdx];
-	iOrdZeroRec->iReloc.r_offset = et->st_value - 4; // The word prior ro the first entry
-											// of the export table is the 0th ordinal entry.
-
-	//At the 0th ordinal, write the address of the start of symbol info	
-	TUint32 aZeroOrdOff = et->st_value - 4 - iElfFile->iLinkedBase;
-	aZeroOrdOff += (iElfFile->GetSegment(et->st_shndx - 1))->p_offset;
-	TUint32 *aZeroOrdLocation = ELFADDR(TUint32, iElfFile->ELFFileBase(), aZeroOrdOff);
-	*aZeroOrdLocation = aBaseAddr;
-
-	iOrdZeroRec->iReloc.r_info = ELF32_R_INFO(et->st_shndx, R_ARM_RABS32);
-	iNumberOfCodeRelocs++;
-	iNumberOfRelocs++;
-
-	TInt aOffset = aBaseOffset + iSymInfoHdr.iDepDllZeroOrdTableOffset;
-
-	OrdZeroRecord *aDepRecord = iDepRecords;
-
-	while( aDepRecord )
-	{
-		// Setup the offset - This offset (relative code segment) is filled in the 
-		// import table to point to this dependency record.
-		aDepRecord->iOffset = aOffset;
-
-		aOffset += 4;
-		aDepRecord = aDepRecord->iNext;
-	}
-}
-
-TBool ELFFile::ELFDllData::AddToDependency(TUint aOff)
-{
-	// Add the name found in DT_NEEDED into a list.
-	// The dynamic string table might not have been found in dynamic table yet.
-	// So store the offset (wrt base of dynamic string table) for now.
-	NeededDLLsList *aNeeded = new NeededDLLsList(aOff);
-	if(!aNeeded)
-		return FALSE;
-
-	if ( iNeededDllNames ) {
-	 iNeededDllNamesTail->iNext= aNeeded;
-	 iNeededDllNamesTail = aNeeded; 
-	}
-	else {
-		iNeededDllNames = iNeededDllNamesTail = aNeeded;
-	}
-	
-	return TRUE;
-}
-
-TBool ELFFile::ELFDllData::CreateDependency()
-{
-	OrdZeroRecord *aDep;
-	NeededDLLsList *aNeeded = iNeededDllNames;
-	char *aDllName = NULL;
-	DllRec *aRec;
-	TInt aNeededFound;
-
-	for(aNeededFound = 0; (aNeededFound < iNumberOfImportDlls) && aNeeded;)
-	{
-		aRec = 0;
-		while(aNeeded) {
-			aDllName = iDynStrTab + aNeeded->iOffset;
-			// aNeeded is just a guess that this binary might be dependent on aDllName
-			// Search through the import table to find if the guess was correct.
-			aRec = SearchImports(aDllName);
-			if(aRec && FindDependency(aRec->iName, aRec->iLen) == NULL) {
-				// Check if aDllName is listed in import table and it
-				// not added already in the depedency records.
-				aNeededFound++;
-				break;
-			}
-			// Bad guess...go to the next aNeeded
-			aNeeded = aNeeded->iNext;
-		}
-
-		if( !aRec )
-			return FALSE;
-
-		aDep = new OrdZeroRecord(aDllName);
-		if(!iDepRecords)
-		{
-			iDepRecords = iDepRecordsTail = aDep;
-		}
-		else
-		{
-			iDepRecordsTail->iNext = aDep;
-			iDepRecordsTail = aDep;
-		}
-		aNeeded = aNeeded->iNext;
-	}
-
-	return (aNeededFound == iNumberOfImportDlls);
-}
-
-ELFFile::ELFDllData::DllRec* ELFFile::ELFDllData::SearchImports(char *aName)
-{
-	DllRec *aRec = iDllHead;
-	while (aRec)
-	{
-		if(strncmp(aRec->iName, aName, aRec->iLen) == 0)
-			return aRec;
-		aRec = aRec->iNext;
-	}
-	return NULL;
-}
-
-OrdZeroRecord* ELFFile::ELFDllData::FindDependency(char* aName, TUint aLen)
-{
-	OrdZeroRecord* aDep = iDepRecords;
-	while(aDep)
-	{
-		if(strncmp(aName, aDep->iName, aLen) == 0)
-			return aDep;
-		aDep = aDep->iNext;
-	}
-	return NULL;
-}
-
-void ELFFile::ELFDllData::GetExportSymInfoHeader(E32EpocExpSymInfoHdr& aSymInfoHdr)
-{
-	memcpy(&aSymInfoHdr, &iSymInfoHdr, sizeof(E32EpocExpSymInfoHdr));
-}
-
-void ELFFile::ELFDllData::SetExportSymInfo()
-{
-	iSymInfoHdr.iSymCount = (TUint16)iNamedExportCount;
-	iSymInfoHdr.iSymbolTblOffset = sizeof(E32EpocExpSymInfoHdr);
-	iSymInfoHdr.iStringTableSz = iSymStringTableSize;
-	TInt aSymTabSz;
-	if( iStringNameOffset > 0xffff){
-		iSymInfoHdr.iFlags = KNameLookupOffsetFlag32;  // Flag indicating 32 bit offsets 
-													   // for symbol names
-		aSymTabSz = iNamedExportCount* sizeof(TUint32);// symbol addresses
-		aSymTabSz += iNamedExportCount* sizeof(TUint32);// symbol name 32-bit offsets
-	}
-	else
-	{
-		iSymInfoHdr.iFlags &= ~KNameLookupOffsetFlag32;// Flag indicating 16-bit offsets 
-													   // for symbol names
-		aSymTabSz = iNamedExportCount* sizeof(TUint32);	// symbol addresses
-		aSymTabSz += iNamedExportCount* sizeof(TUint16);// symbol name 16-bit offsets
-		aSymTabSz = ALIGN4(aSymTabSz);
-	}
-	iSymInfoHdr.iStringTableOffset = iSymInfoHdr.iSymbolTblOffset + aSymTabSz;
-	iSymInfoHdr.iDllCount = iNumberOfImportDlls;
-	iSymInfoHdr.iDepDllZeroOrdTableOffset = iSymInfoHdr.iStringTableOffset + \
-								iSymInfoHdr.iStringTableSz;
-
-	iSymInfoHdr.iSize = iSymInfoHdr.iDepDllZeroOrdTableOffset + \
-						iSymInfoHdr.iDllCount * sizeof(Elf32_Addr);
-}
-
-TUint ELFFile::ELFDllData::GetSymLookupSection(char* aBuff)
-{
-	if( !iNamedLookupEnabled)
-		return 0;
-
-	memcpy(aBuff, &iSymInfoHdr, sizeof(iSymInfoHdr));
-	
-	// Name offsets start after the end of symbol addresses.
-	TUint32 aNameOffsetStart = iSymInfoHdr.iSymbolTblOffset + \
-								iNamedExportCount* sizeof(TUint32);
-																
-	TUint32 *aAddrPtr = (TUint32*)(aBuff + iSymInfoHdr.iSymbolTblOffset);
-	TUint32 aStringTabOff = 0;
-	char *aStringTab = aBuff + iSymInfoHdr.iStringTableOffset;//Start of the string table.
-	NamedExportSymbol *aSym = iNamedExportSymbolHead;
-	while(aSym)
-	{
-		*aAddrPtr = aSym->Value();
-		aStringTabOff = aSym->NameOffset(); // Get the offset of symbol name (which is wrt 
-											// string table base).
-		if( iSymInfoHdr.iFlags & KNameLookupOffsetFlag32 )
-		{
-			TUint32 *aNameOffPtr = (TUint32*)(aBuff + aNameOffsetStart);
-			*aNameOffPtr = (aStringTabOff >> 2);//write the offset of the name
-			strcpy(aStringTab + aStringTabOff, aSym->Name());//write the symbol name
-			aNameOffsetStart +=4;
-		}
-		else
-		{
-			TUint16 *aNameOffPtr = (TUint16*)(aBuff + aNameOffsetStart);
-			*aNameOffPtr = (TUint16)(aStringTabOff >> 2);//write the offset of the name
-			strcpy(aStringTab + aStringTabOff, aSym->Name());//write the symbol name
-			aNameOffsetStart +=2;
-		}
-		aAddrPtr++;
-		aSym = aSym->Next();
-	}
-
-	OrdZeroRecord *aRec = iDepRecords;
-	TUint32* aDepsTable = (TUint32*)(aBuff + iSymInfoHdr.iDepDllZeroOrdTableOffset);
-	while(aRec)
-	{
-		*aDepsTable++ = 0;
-		aRec = aRec->iNext;
-	}
-	return iSymInfoHdr.iSize;
-}
-
-void ELFFile::ELFDllData::Sort(NamedExportSymbol** aDstList, NamedExportSymbol* aSrcList)
-{
-	NamedExportSymbol *aSym = aSrcList;
-	NamedExportSymbol **aSymbols = new NamedExportSymbol*[iNamedExportCount];
-	
-	TInt pos;
-	for (pos = 0; pos < iNamedExportCount; pos++) {
-		aSymbols[pos] = aSym;
-		aSym = aSym->Next();
-	}
-	
-	NamedExportSymbol **aResult = new NamedExportSymbol*[iNamedExportCount];
-	MergeSort(aResult, aSymbols);
-	iNamedExportSymbolHead = aResult[0];
-	for (pos = 0; pos < iNamedExportCount; pos++) {
-		aSym = aResult[pos];
-		if( pos == iNamedExportCount-1)
-			aSym->Next(NULL);
-		else
-			aSym->Next(aResult[pos+1]);
-	}
-	*aDstList = aResult[0];
-	delete [] aResult;
-	delete [] aSymbols;
-}
-
-void ELFFile::ELFDllData::MergeSort(NamedExportSymbol** aDstList, NamedExportSymbol** aSrcList)
-{
-	MergeSort(aDstList, aSrcList, 0, iNamedExportCount);
-}
-
-void ELFFile::ELFDllData::MergeSort(NamedExportSymbol** aDstList, NamedExportSymbol** aSrcList, \
-									TUint aLeft, TUint aRight)
-{
-	if( (aRight - aLeft) <= 1)
-		return;
-
-	TUint aSize = aRight - aLeft;
-	TUint aCenter = aLeft + aSize/2;
-
-	MergeSort(aDstList, aSrcList, aLeft, aCenter);
-	MergeSort(aDstList, aSrcList, aCenter, aRight);
-
-	TUint aLPos, aRPos, aCnt;
-	aLPos = aLeft;
-	aRPos = aCenter;
-	for(aCnt = 0; aCnt < aSize; aCnt++)
-	{
-		if( (aLPos < aCenter) &&
-			(aRPos == aRight || (strcmp(aSrcList[aLPos]->Name(), aSrcList[aRPos]->Name()) < 0) )
-		  )
-		{
-			// Compare the left half with the right and add the lesser one.
-			// The comparision is done on the topmost element on each half.
-			// if aRPos is past the last element of the right half, the left element has 
-			// nothing to compare with. Just add it to the result list.
-			aDstList[aCnt] = aSrcList[aLPos];
-			aLPos++;
-		}
-		else
-		{
-			// Add the greater one into the list.
-			// if aLPos is past the element at the center, it anyway belongs to the
-			// right half. Add it to the result list.
-			aDstList[aCnt] = aSrcList[aRPos];
-			aRPos++;
-		}
-	}
-
-	// Once the sublist is sorted, put it back to the source list
-	// so that the parent has its left and right sublists are sorted.
-	for(aCnt = 0; aCnt < aSize; aCnt++)
-	{
-		aSrcList[aLeft+aCnt] = aDstList[aCnt];
-	}
-}
-
+/*
+* 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 <string.h>
+#include <stdlib.h>
+#include <e32std.h>
+#include "elfdefs.h"
+#include "elfdll.h"
+#include "elffile.h"
+#include "h_utl.h"
+#include <e32ldr.h>
+
+ELFFile::ELFDllData::ELFDllData(ELFFile * f) :
+         iElfFile(f), iDynStrTab(0), iDynStrTabSize(0), iDynSymTab(0),
+ 		iSymSize(0), iRela(0), iRelaSz(0), iRelaEnt(0), 
+ 		iRel(0), iRelSz(0), iRelEnt(0),
+ 		iHashTable(0), iNamedExportSymbolHead(0),  iNamedExportCount(0),
+		iSymStringTableSize(0),iStringNameOffset(0), 
+		iDepRecords(0), iDepRecordsTail(0),iNeededDllNames(0),iNeededDllNamesTail(0),
+		iOrdZeroRec(0), iNamedLookupEnabled(0), 
+		iDllHead(0), iDllTail(0), 
+ 		iNumberOfImports(0),  iNumberOfExports(0), iNumberOfImportDlls(0),
+ 		iStringTableSize(0), iNumberOfRelocs(0), iNumberOfCodeRelocs(0),
+ 		iNumberOfDataRelocs(0)
+ 		  		
+		{
+		}
+
+ELFFile::ELFDllData::~ELFDllData()
+	{
+		delete iOrdZeroRec;
+		delete iDepRecords;
+		delete iNeededDllNames;
+	}
+
+TBool ELFFile::ELFDllData::Init()
+	{
+	// process imported symbols
+	// There will be at least one relocation (assumed to be Elf32_Rel) for each such symbol.
+	// S iterate over relocations looking for DLL symbols and add them to the record of
+	// of import info.
+	TInt nrelocs = iRelSz/iRelEnt;
+	TInt SrcSegIdx = -1;
+	TInt errors = 0;
+
+	for (TInt idx = 0; idx < nrelocs; idx++)
+			{
+			Elf32_Rel * rel = &iRel[idx];
+			TUint relType = ELF32_R_TYPE(rel->r_info);
+
+			if (relType == R_ARM_ABS32)      
+					{	
+					TInt symIdx = ELF32_R_SYM(rel->r_info);
+					Elf32_Sym * sym = &iDynSymTab[symIdx];
+					DllSymbol * dllSym = DllSymbolP(sym);
+					if (dllSym) 
+							{
+							dllSym->iRel = rel;
+							dllSym->iSegment = iElfFile->GetSegment(SrcSegIdx);
+							if (!AddSymbol(dllSym)) return EFalse;
+							}
+					else errors++;
+					}
+			else if (relType == R_ARM_RABS32)
+					{
+					iNumberOfRelocs++;
+					if (iElfFile->CodeSegmentP(SrcSegIdx)) iNumberOfCodeRelocs++;
+					else iNumberOfDataRelocs++;
+					}
+			else if (relType == R_ARM_RBASE)
+				    {
+					SrcSegIdx = ELF32_R_SYM(rel->r_info);
+					if (SrcSegIdx) SrcSegIdx--;
+					}
+			else 
+				    {
+					// Gives error with all other Relocation types..
+					TInt symIdx = ELF32_R_SYM(rel->r_info);
+					Elf32_Sym * s = &iDynSymTab[symIdx];
+					char * symName = ELFADDR(char,iDynStrTab,s->st_name);
+					Print(EPeError, "Unresolved symbol: %s\n", symName);
+					errors++;
+					}
+			}
+	// Set up export info
+	if (InitExportInfo())
+	       { 
+	       // If _E32Startup is defined then this is not a DLL
+	       iImageIsDll = !iElfFile->SymbolPresent("_E32Startup");
+	       }
+	if (errors > 0) return EFalse;
+	return ETrue;
+	}
+
+TBool ELFFile::ELFDllData::ParseDllSymbol(Elf32_Sym * s, char *& dll, TUint& len, TInt& ord)
+    {
+	char * sym = ELFADDR(char,iDynStrTab,s->st_name);
+	if (!strncmp(sym, DLLSYMPREFIX, strlen(DLLSYMPREFIX)))
+			{
+			dll = sym + strlen(DLLSYMPREFIX);
+			TUint lim = strlen(dll);
+			TUint index = strcspn(dll, DLLSYMPREFIX0);
+			if ((index + strlen(DLLSYMSUFFIX)) < lim)
+					{
+					len = index;
+					char * dllSuffix = dll+index;
+					char * match = DLLSYMSUFFIX;
+					int suflen = strlen(DLLSYMSUFFIX);
+					if (!strncmp(dllSuffix, match, suflen))
+							{
+							char * ordString = dll+index+suflen;
+							char * final;
+							TUint X = strtoul(ordString, &final, ORDBASE);
+							if (ordString != final)
+									{
+									ord = (TInt)X;
+									return ETrue;
+									}
+			     
+							}
+					}
+			}
+	dll = 0;
+	len = 0;
+	ord = -1;
+	return EFalse;
+	}
+
+ELFFile::ELFDllData::DllSymbol * ELFFile::ELFDllData::DllSymbolP(Elf32_Sym * s)
+    {
+	char * dllName;
+	TUint nameLen;
+	TInt symOrd;
+	if (ParseDllSymbol(s, dllName, nameLen, symOrd))
+	       {
+	       DllSymbol * ds = new DllSymbol(dllName, nameLen, symOrd);
+	       if (ds) return ds;
+	       Print(EPeError, "Out of memory.\n");
+	       return NULL;
+	       }
+	// If we get here its not a valid 'dll symbol' and so it is an unresolved symbol
+	char * sym = ELFADDR(char,iDynStrTab,s->st_name);
+	Print(EPeError, "Unresolved symbol: %s\n", sym);
+    return NULL;
+	}
+
+TBool ELFFile::ELFDllData::AddSymbol(ELFFile::ELFDllData::DllSymbol * s)
+    {
+	DllRec * aDll = NULL;
+     
+	for (DllRec * r = iDllHead; r != NULL; r = r->iNext)
+			{
+			if (!strncmp(s->iDll, r->iName, s->iLen))
+					{
+					aDll = r;
+					break;
+					}
+			}
+	if (aDll)
+			{
+		    iNumberOfImports++;
+		    aDll->AddSymbol(s);
+			return ETrue;
+			}
+	else
+			{
+			aDll = new DllRec(s->iDll, s->iLen, s);
+			if (aDll)
+					{
+					if (!iDllHead) 
+							{
+							iDllHead = iDllTail = aDll;
+							}
+					else
+							{
+							iDllTail->iNext = aDll;
+							iDllTail = aDll;
+							}
+					iStringTableSize += (s->iLen + 1);
+	      			iNumberOfImportDlls++;
+					iNumberOfImports++;
+					return ETrue;
+					}
+			else
+					{
+					Print(EPeError, "Out of memory.\n");
+					return EFalse;
+					}
+			}
+	}
+
+void ELFFile::ELFDllData::DllRec::AddSymbol(ELFFile::ELFDllData::DllSymbol * s)
+	{
+	nImports++;
+    iTail->iNext = s;
+    iTail = s;
+    }
+
+static unsigned long elf_hash(const unsigned char* name)
+    {
+    unsigned long h, g;
+    for (h = 0; *name != 0; ++name)
+	        {
+			h = (h << 4) + *name;
+			g = h & 0xf0000000;
+			if (g != 0) h ^= g >> 24;
+			h &= ~g;
+			}
+	return h;
+    }
+
+Elf32_Word ELFFile::ELFDllData::FindSymbolIndex(const char* s)
+    {
+	TUint h = elf_hash((const unsigned char*)s);
+	TUint nb = iHashTable[0].nBuckets;
+	TUint probe = h%nb;
+	Elf32_Sword * bucket = ELFADDR(Elf32_Sword, iHashTable, sizeof(Elf32_HashTable));
+	Elf32_Sword * chain = ELFADDR(Elf32_Sword, bucket, nb * sizeof(Elf32_Sword));
+	Elf32_Sword idx = bucket[probe];
+
+	do 	
+			{
+			if (!strcmp(ELFADDR(char, iDynStrTab, iDynSymTab[idx].st_name), s)) return idx;
+			idx = chain[idx];
+			} while (idx > 0);
+	if (idx == 0) idx = -1;
+	return idx;
+	}
+
+TBool ELFFile::ELFDllData::InitExportInfo()
+	{
+	memset(&iSymInfoHdr, 0, sizeof(iSymInfoHdr)); 
+	if ((iExportTableSymIdx = FindSymbolIndex(EXPORTTABLENAME)) != (Elf32_Word)-1)
+			{ 
+			iExportTableSizeSymIdx = FindSymbolIndex(EXPORTTABLESIZENAME);
+			//TUint offset = iDynSymTab[iExportTableSizeSymIdx].st_value - (TUint)code;
+			Elf32_Word * pNumberOfExports = iElfFile->CodePtrFromAddr(iDynSymTab[iExportTableSizeSymIdx].st_value);
+			iNumberOfExports = * pNumberOfExports;
+			iImageIsDll = ETrue;
+			return ETrue;
+			}
+	else iImageIsDll = EFalse;
+	return EFalse;
+	}
+
+TInt ELFFile::ELFDllData::NumberOfImports(void)
+    {
+	return iNumberOfImports;
+	}
+
+TInt ELFFile::ELFDllData::NumberOfExports(void)
+    {
+	return iNumberOfExports;
+	}
+
+TInt ELFFile::ELFDllData::NumberOfImportDlls(void)
+    {
+	return iNumberOfImportDlls;
+	}
+
+TInt ELFFile::ELFDllData::NumberOfRelocs()
+	{
+	return iNumberOfRelocs;
+	}
+
+char * ELFFile::ELFDllData::CreateImportSection(TInt &aSize)
+	{
+	if (!iNumberOfImports)
+			{
+			aSize = 0;
+			return 0;
+			}
+
+	TInt byteSize = sizeof(E32ImportSection) + 
+	                (sizeof(E32ImportBlock) * iNumberOfImportDlls) +
+					(sizeof(TUint) * iNumberOfImports) +
+					iStringTableSize;
+	if(iNamedLookupEnabled)
+	{
+		// 0th ordinal of each DLL imported from.
+		byteSize += (sizeof(TUint) * iNumberOfImportDlls);
+	}
+	char * newSection = new char[byteSize];
+
+	if (!newSection)
+	       {
+	       Print(EPeError, "Failed to allocate new import section.\n");
+	       aSize = 0;
+	       return 0;
+	       }
+
+	((E32ImportSection *)newSection)->iSize = byteSize;
+
+	// used to point to current ImportBlock
+	E32ImportBlock * bp = ELFADDR(E32ImportBlock, newSection, sizeof(E32ImportSection));
+	// used to point to current import relocation entry
+	TUint * rp;
+	// used to point to current location in string table
+	char * sp = ELFADDR(char, newSection, (byteSize - iStringTableSize));
+	OrdZeroRecord *aDep = iDepRecords;
+
+	for (DllRec * dll = iDllHead; dll != NULL ; dll = dll->iNext, bp = (E32ImportBlock *)rp )
+	        {
+			// set up the offset from E32ImportBlock.iOffsetOfDllName to the
+			// corresponding  string table location
+			bp->iOffsetOfDllName = (sp - (char *)newSection);
+			bp->iNumberOfImports = dll->nImports;
+			if(iNamedLookupEnabled)
+			{
+				bp->iNumberOfImports++;
+			}
+
+			// copy the DLL name to the string table
+			memcpy(sp , dll->iName, dll->iLen);
+			sp[dll->iLen] = 0;
+			sp = sp + dll->iLen + 1;
+
+			// sort out the import 'relocs'
+			rp = ELFADDR(TUint, bp, sizeof(E32ImportBlock));
+		
+			for (DllSymbol * sym = dll->iHead; sym != NULL; sym = sym->iNext, rp++)
+				    {
+					Elf32_Phdr * segment = sym->iSegment;
+					Elf32_Addr segBase = segment->p_vaddr;
+
+					// sanity check: segment should be the code segment
+					if (!iElfFile->CodeSegmentP(segment))
+							{
+							Print(EPeError, "Import relocation does not refer to code segment.\n");
+							Print(EPeError, "Dll: %s\n", sym->iDll);
+							Print(EPeError, "Ordinal: %d\n", sym->iOrd);
+							Print(EPeError, "DLL name: %s\n", dll->iName);
+							aSize = 0;
+							return 0;
+							}
+
+					// This field is misnamed because it is actually given as a virtual address in 
+					// dynamic relocations
+					Elf32_Addr dynOffset = sym->iRel->r_offset;
+					//So this is the 'real' offset of the reloc in  the segment in which it occurs
+					Elf32_Addr segOffset = dynOffset - segBase;
+					TUint * relocAddr = ELFADDR(TUint, iElfFile->ELFFileBase(), (segment->p_offset + segOffset));
+					// The only non-zero reloc vals we expect are for vtables.
+					// We store there reloc offset in the top 16 bits of the 'reloc info'.
+					// NB the ELF reloc values should only ever be multiples of 4. So we could optimize here,
+					// but we won't.
+					TUint relocVal = *relocAddr;
+					TUint importOrdinal = sym->iOrd;
+					if (relocVal > 0xFFFF) {
+							Print(EPeError, "ELF relocation exceeds E32Image limit of 64K.\n");
+							Print(EPeError, "Dll: %s\n", sym->iDll);
+							Print(EPeError, "Ordinal: %d\n", sym->iOrd);
+							Print(EPeError, "DLL name: %s\n", dll->iName);
+					}
+					if (importOrdinal > 0xFFFF) {
+							Print(EPeError, "Import ordinal exceeds E32Image limit of 64K.\n");
+							Print(EPeError, "Dll: %s\n", sym->iDll);
+							Print(EPeError, "Ordinal: %d\n", sym->iOrd);
+							Print(EPeError, "DLL name: %s\n", dll->iName);
+					}   
+   					*rp = segOffset;
+   			
+   					// eek !! surgery on the code segment....
+					*relocAddr = (relocVal<<16) | importOrdinal;
+					}
+			
+				if(iNamedLookupEnabled)
+				{
+					aDep = FindDependency(dll->iName, dll->iLen);
+					if( aDep )
+					{
+						*rp = aDep->iOffset;
+						rp++;
+					}
+				}
+			}
+	
+	aSize = byteSize;
+	return newSection;
+	}
+
+TUint ELFFile::ELFDllData::GetExportTableOffset(void)
+    {
+	Elf32_Sym * et = &iDynSymTab[iExportTableSymIdx];
+	Elf32_Phdr * segment = iElfFile->GetSegment(et->st_shndx - 1);
+	
+	return et->st_value - segment->p_vaddr;
+	}
+
+TBool ELFFile::ELFDllData::GetRelocs(Elf32_Rel **aCodeRelocs, Elf32_Rel **aDataRelocs)
+	//	
+	// load the relocs from the reloc section into relocation and relocsection arrays
+	//
+	{
+	TInt nrelocs = iRelSz/iRelEnt;
+
+	TInt SrcSegIdx = -1;
+	
+	TInt idx = 0;
+	TInt cidx = 0;
+	TInt didx = 0;
+
+	for (idx = 0, cidx = 0, didx = 0; idx < nrelocs; idx++)
+	        {
+			Elf32_Rel * rel = &iRel[idx];
+
+			if (ELF32_R_TYPE(rel->r_info) == R_ARM_RABS32)
+					{
+					if (iElfFile->CodeSegmentP(SrcSegIdx))
+							aCodeRelocs[cidx++]=rel;
+					else if (iElfFile->DataSegmentP(SrcSegIdx))
+							aDataRelocs[didx++]=rel;
+					}
+			else if (ELF32_R_TYPE(rel->r_info) == R_ARM_RBASE)
+					{
+					SrcSegIdx = ELF32_R_SYM(rel->r_info);
+					if (!(iElfFile->CodeSegmentP(SrcSegIdx-1) || iElfFile->DataSegmentP(SrcSegIdx-1)))
+							{
+							Print(EPeError, "Source segment for relocations is neither Code or Data.\n");
+							return EFalse;
+							}
+					SrcSegIdx--;
+					}
+			}
+
+	if(!iNamedLookupEnabled)
+		return ETrue;
+
+	// Add the 0th ordinal of this binary - The relocation info is already setup.
+	aCodeRelocs[cidx++] = &iOrdZeroRec->iReloc;
+
+	// add relocation entries for each of the symbols
+	NamedExportSymbol *aSym = iNamedExportSymbolHead;
+	while(aSym)
+	{
+		// The symbol name info is part of the code section hence all relocations
+		// are collected as part of Code relocations.
+		aCodeRelocs[cidx++] = &aSym->iReloc;
+		aSym = aSym->Next();
+	}
+
+	// Since we have added a few relocations, lets make sure
+	// they are still sorted on addresses they refer to.
+	
+	//Sorting the code relocs
+	TInt aIdx1, aIdx2;
+	Elf32_Rel *aTmp;
+	for (aIdx1 = 0; aIdx1 < cidx; aIdx1++) {
+		for (aIdx2 = aIdx1; aIdx2 < cidx; aIdx2++) {
+			if(aCodeRelocs[aIdx1]->r_offset > aCodeRelocs[aIdx2]->r_offset) {
+				aTmp = aCodeRelocs[aIdx2];
+				aCodeRelocs[aIdx2] = aCodeRelocs[aIdx1];
+				aCodeRelocs[aIdx1] = aTmp;
+			}
+		}
+	}
+	
+	//Sorting the data relocs
+	for (aIdx1 = 0; aIdx1 < didx; aIdx1++) {
+		for (aIdx2 = aIdx1; aIdx2 < didx; aIdx2++) {
+			if(aDataRelocs[aIdx1]->r_offset > aDataRelocs[aIdx2]->r_offset) {
+				aTmp = aDataRelocs[aIdx2];
+				aDataRelocs[aIdx2] = aDataRelocs[aIdx1];
+				aDataRelocs[aIdx1] = aTmp;
+			}
+		}
+	}
+
+	return ETrue;
+	}
+
+NamedExportSymbol::NamedExportSymbol(char* aName, Elf32_Addr aValue) : \
+	iSymbolName(aName), iValue(aValue), iNext(NULL)
+{
+}
+
+TBool ELFFile::ELFDllData::CreateSymLookupTable()
+{
+	if( !SetupSymbolValues() )
+		return FALSE;
+
+	if( !SetupSymbolNames() )
+		return FALSE;
+
+	return TRUE;
+}
+
+TBool ELFFile::ELFDllData::SetupSymbolValues()
+{
+	NamedExportSymbol *aSym, *aPrevSym;
+
+	if( iExportTableSymIdx == (Elf32_Word)-1 || iExportTableSizeSymIdx == (Elf32_Word)-1)
+		return FALSE;
+
+	// Fetch the 'export table' symbol from the dynamic symbol table.
+	Elf32_Sym *aElfExpTbl = &iDynSymTab[iExportTableSymIdx];
+
+	// Fetch the 'export table size' symbol from the dynamic symbol table.
+	Elf32_Sym *aElfExpTblSz = &iDynSymTab[iExportTableSizeSymIdx];
+
+	if((aElfExpTbl->st_value - aElfExpTblSz->st_value) != 4)
+	{
+		// Check that the word prior to the export table is not the export table size
+		// This is to make sure that there is space for the 0th ordinal and
+		// we dont overwrite the 'export table size' entry.
+		iNamedLookupEnabled = 1;
+	}
+	else 
+		return FALSE;
+
+	// Fetch the export table contents
+	Elf32_Word * aExpEntries = iElfFile->CodePtrFromAddr(aElfExpTbl->st_value);
+
+	if(!aExpEntries)
+		return FALSE;
+
+	aSym = aPrevSym = NULL;
+	TInt idx;
+	// Create symbols corresponding to export table entries.
+	for(idx = 0;  idx < iNumberOfExports; idx++)
+	{
+		//Symbols marked Absent are ignored.
+		if( aExpEntries[idx] == iElfFile->iEntryPoint)
+			continue;
+
+		aSym = new NamedExportSymbol(0, aExpEntries[idx]);
+		iNamedExportCount++;
+		if(aPrevSym)
+		{
+			aPrevSym->Next(aSym);
+		}
+		else
+		{
+			iNamedExportSymbolHead = aSym;
+		}
+
+		aPrevSym = aSym;
+	}
+
+	return TRUE;
+}
+
+TBool ELFFile::ELFDllData::SetupSymbolNames()
+{
+	char *aSymName = NULL;
+	NamedExportSymbol *aSym;
+	TUint aDynSymbolTblCount = iHashTable->nChains;
+	TInt aCount = 0;
+	TInt aCodeSegIdx = iElfFile->CodeSegmentIndex() + 1;
+	TInt aDataSegIdx = iElfFile->DataSegmentIndex() + 1;
+
+	// Traverse the dynamic symbol table
+	for(TUint idx = 0; idx < aDynSymbolTblCount; idx++)
+	{
+		//Consider only the the defined symbols
+		if( ELF32_ST_TYPE(iDynSymTab[idx].st_info) == STT_OBJECT || 
+			ELF32_ST_TYPE(iDynSymTab[idx].st_info) == STT_FUNC )
+		{
+			aSym = iNamedExportSymbolHead;
+			while(aSym)
+			{
+				// Name already set
+				if(aSym->Name())
+				{
+					aSym = aSym->Next();
+					continue;
+				}
+				Elf32_Addr aAddr = aSym->Value();
+
+				// If the exported symbol and the dynamic symbol table entry have the 
+				// same values, setup the name
+				if(iDynSymTab[idx].st_value == aAddr)
+				{
+					aSymName = ELFADDR(char, iDynStrTab, iDynSymTab[idx].st_name);
+					aSym->Name(aSymName);
+					
+					if(iElfFile->CodeSegmentP (iElfFile->GetSegmentFromAddr(aAddr)) ) {
+						aSym->iReloc.r_info = aCodeSegIdx << 8 | R_ARM_RABS32;
+						aSym->iSymRelocType = KTextRelocType;
+					}
+					else {
+						aSym->iReloc.r_info = aDataSegIdx << 8 | R_ARM_RABS32;
+						aSym->iSymRelocType = KDataRelocType;
+					}
+					
+					iNumberOfCodeRelocs++;
+					iNumberOfRelocs++;
+
+					// The offset to the name is always 4 byte aligned.
+					iStringNameOffset = iSymStringTableSize >> 2;
+					aSym->NameOffset( iSymStringTableSize );
+					// These are NULL-terminated strings
+					iSymStringTableSize += (strlen(aSymName) + 1);
+					iSymStringTableSize = ALIGN4(iSymStringTableSize);
+
+					aCount++;
+					break;
+				}
+				aSym = aSym->Next();
+			}
+		}
+	}
+
+	if(aCount != iNamedExportCount)
+		return FALSE;
+
+	// Sort symbols on their names...
+	if(iNamedExportCount > 1)
+	{
+		NamedExportSymbol **aTmpStart = &iNamedExportSymbolHead;
+		Sort(aTmpStart, iNamedExportSymbolHead);
+	}
+
+	return TRUE;
+}
+
+void ELFFile::ELFDllData::SetLookupTblBase(TInt aBaseOffset)
+{
+	Elf32_Addr	aBaseAddr = iElfFile->iLinkedBase + iElfFile->GetCodeSize();
+
+	Elf32_Addr	aAddr;
+
+	// setup relocations of each of the exported symbols.
+	aAddr = aBaseAddr + iSymInfoHdr.iSymbolTblOffset;
+	NamedExportSymbol *aSym = iNamedExportSymbolHead;
+	while(aSym)
+	{
+		aSym->iReloc.r_offset = aAddr;
+		aAddr += sizeof(Elf32_Addr);
+		aSym = aSym->Next();
+	}
+
+	// setup relocations for the 0th ordinal of this binary. 
+
+	iOrdZeroRec = new OrdZeroRecord(0);
+	Elf32_Sym * et = &iDynSymTab[iExportTableSymIdx];
+	iOrdZeroRec->iReloc.r_offset = et->st_value - 4; // The word prior ro the first entry
+											// of the export table is the 0th ordinal entry.
+
+	//At the 0th ordinal, write the address of the start of symbol info	
+	TUint32 aZeroOrdOff = et->st_value - 4 - iElfFile->iLinkedBase;
+	aZeroOrdOff += (iElfFile->GetSegment(et->st_shndx - 1))->p_offset;
+	TUint32 *aZeroOrdLocation = ELFADDR(TUint32, iElfFile->ELFFileBase(), aZeroOrdOff);
+	*aZeroOrdLocation = aBaseAddr;
+
+	iOrdZeroRec->iReloc.r_info = ELF32_R_INFO(et->st_shndx, R_ARM_RABS32);
+	iNumberOfCodeRelocs++;
+	iNumberOfRelocs++;
+
+	TInt aOffset = aBaseOffset + iSymInfoHdr.iDepDllZeroOrdTableOffset;
+
+	OrdZeroRecord *aDepRecord = iDepRecords;
+
+	while( aDepRecord )
+	{
+		// Setup the offset - This offset (relative code segment) is filled in the 
+		// import table to point to this dependency record.
+		aDepRecord->iOffset = aOffset;
+
+		aOffset += 4;
+		aDepRecord = aDepRecord->iNext;
+	}
+}
+
+TBool ELFFile::ELFDllData::AddToDependency(TUint aOff)
+{
+	// Add the name found in DT_NEEDED into a list.
+	// The dynamic string table might not have been found in dynamic table yet.
+	// So store the offset (wrt base of dynamic string table) for now.
+	NeededDLLsList *aNeeded = new NeededDLLsList(aOff);
+	if(!aNeeded)
+		return FALSE;
+
+	if ( iNeededDllNames ) {
+	 iNeededDllNamesTail->iNext= aNeeded;
+	 iNeededDllNamesTail = aNeeded; 
+	}
+	else {
+		iNeededDllNames = iNeededDllNamesTail = aNeeded;
+	}
+	
+	return TRUE;
+}
+
+TBool ELFFile::ELFDllData::CreateDependency()
+{
+	OrdZeroRecord *aDep;
+	NeededDLLsList *aNeeded = iNeededDllNames;
+	char *aDllName = NULL;
+	DllRec *aRec;
+	TInt aNeededFound;
+
+	for(aNeededFound = 0; (aNeededFound < iNumberOfImportDlls) && aNeeded;)
+	{
+		aRec = 0;
+		while(aNeeded) {
+			aDllName = iDynStrTab + aNeeded->iOffset;
+			// aNeeded is just a guess that this binary might be dependent on aDllName
+			// Search through the import table to find if the guess was correct.
+			aRec = SearchImports(aDllName);
+			if(aRec && FindDependency(aRec->iName, aRec->iLen) == NULL) {
+				// Check if aDllName is listed in import table and it
+				// not added already in the depedency records.
+				aNeededFound++;
+				break;
+			}
+			// Bad guess...go to the next aNeeded
+			aNeeded = aNeeded->iNext;
+		}
+
+		if( !aRec )
+			return FALSE;
+
+		aDep = new OrdZeroRecord(aDllName);
+		if(!iDepRecords)
+		{
+			iDepRecords = iDepRecordsTail = aDep;
+		}
+		else
+		{
+			iDepRecordsTail->iNext = aDep;
+			iDepRecordsTail = aDep;
+		}
+		aNeeded = aNeeded->iNext;
+	}
+
+	return (aNeededFound == iNumberOfImportDlls);
+}
+
+ELFFile::ELFDllData::DllRec* ELFFile::ELFDllData::SearchImports(char *aName)
+{
+	DllRec *aRec = iDllHead;
+	while (aRec)
+	{
+		if(strncmp(aRec->iName, aName, aRec->iLen) == 0)
+			return aRec;
+		aRec = aRec->iNext;
+	}
+	return NULL;
+}
+
+OrdZeroRecord* ELFFile::ELFDllData::FindDependency(char* aName, TUint aLen)
+{
+	OrdZeroRecord* aDep = iDepRecords;
+	while(aDep)
+	{
+		if(strncmp(aName, aDep->iName, aLen) == 0)
+			return aDep;
+		aDep = aDep->iNext;
+	}
+	return NULL;
+}
+
+void ELFFile::ELFDllData::GetExportSymInfoHeader(E32EpocExpSymInfoHdr& aSymInfoHdr)
+{
+	memcpy(&aSymInfoHdr, &iSymInfoHdr, sizeof(E32EpocExpSymInfoHdr));
+}
+
+void ELFFile::ELFDllData::SetExportSymInfo()
+{
+	iSymInfoHdr.iSymCount = (TUint16)iNamedExportCount;
+	iSymInfoHdr.iSymbolTblOffset = sizeof(E32EpocExpSymInfoHdr);
+	iSymInfoHdr.iStringTableSz = iSymStringTableSize;
+	TInt aSymTabSz;
+	if( iStringNameOffset > 0xffff){
+		iSymInfoHdr.iFlags = KNameLookupOffsetFlag32;  // Flag indicating 32 bit offsets 
+													   // for symbol names
+		aSymTabSz = iNamedExportCount* sizeof(TUint32);// symbol addresses
+		aSymTabSz += iNamedExportCount* sizeof(TUint32);// symbol name 32-bit offsets
+	}
+	else
+	{
+		iSymInfoHdr.iFlags &= ~KNameLookupOffsetFlag32;// Flag indicating 16-bit offsets 
+													   // for symbol names
+		aSymTabSz = iNamedExportCount* sizeof(TUint32);	// symbol addresses
+		aSymTabSz += iNamedExportCount* sizeof(TUint16);// symbol name 16-bit offsets
+		aSymTabSz = ALIGN4(aSymTabSz);
+	}
+	iSymInfoHdr.iStringTableOffset = iSymInfoHdr.iSymbolTblOffset + aSymTabSz;
+	iSymInfoHdr.iDllCount = iNumberOfImportDlls;
+	iSymInfoHdr.iDepDllZeroOrdTableOffset = iSymInfoHdr.iStringTableOffset + \
+								iSymInfoHdr.iStringTableSz;
+
+	iSymInfoHdr.iSize = iSymInfoHdr.iDepDllZeroOrdTableOffset + \
+						iSymInfoHdr.iDllCount * sizeof(Elf32_Addr);
+}
+
+TUint ELFFile::ELFDllData::GetSymLookupSection(char* aBuff)
+{
+	if( !iNamedLookupEnabled)
+		return 0;
+
+	memcpy(aBuff, &iSymInfoHdr, sizeof(iSymInfoHdr));
+	
+	// Name offsets start after the end of symbol addresses.
+	TUint32 aNameOffsetStart = iSymInfoHdr.iSymbolTblOffset + \
+								iNamedExportCount* sizeof(TUint32);
+																
+	TUint32 *aAddrPtr = (TUint32*)(aBuff + iSymInfoHdr.iSymbolTblOffset);
+	TUint32 aStringTabOff = 0;
+	char *aStringTab = aBuff + iSymInfoHdr.iStringTableOffset;//Start of the string table.
+	NamedExportSymbol *aSym = iNamedExportSymbolHead;
+	while(aSym)
+	{
+		*aAddrPtr = aSym->Value();
+		aStringTabOff = aSym->NameOffset(); // Get the offset of symbol name (which is wrt 
+											// string table base).
+		if( iSymInfoHdr.iFlags & KNameLookupOffsetFlag32 )
+		{
+			TUint32 *aNameOffPtr = (TUint32*)(aBuff + aNameOffsetStart);
+			*aNameOffPtr = (aStringTabOff >> 2);//write the offset of the name
+			strcpy(aStringTab + aStringTabOff, aSym->Name());//write the symbol name
+			aNameOffsetStart +=4;
+		}
+		else
+		{
+			TUint16 *aNameOffPtr = (TUint16*)(aBuff + aNameOffsetStart);
+			*aNameOffPtr = (TUint16)(aStringTabOff >> 2);//write the offset of the name
+			strcpy(aStringTab + aStringTabOff, aSym->Name());//write the symbol name
+			aNameOffsetStart +=2;
+		}
+		aAddrPtr++;
+		aSym = aSym->Next();
+	}
+
+	OrdZeroRecord *aRec = iDepRecords;
+	TUint32* aDepsTable = (TUint32*)(aBuff + iSymInfoHdr.iDepDllZeroOrdTableOffset);
+	while(aRec)
+	{
+		*aDepsTable++ = 0;
+		aRec = aRec->iNext;
+	}
+	return iSymInfoHdr.iSize;
+}
+
+void ELFFile::ELFDllData::Sort(NamedExportSymbol** aDstList, NamedExportSymbol* aSrcList)
+{
+	NamedExportSymbol *aSym = aSrcList;
+	NamedExportSymbol **aSymbols = new NamedExportSymbol*[iNamedExportCount];
+	
+	TInt pos;
+	for (pos = 0; pos < iNamedExportCount; pos++) {
+		aSymbols[pos] = aSym;
+		aSym = aSym->Next();
+	}
+	
+	NamedExportSymbol **aResult = new NamedExportSymbol*[iNamedExportCount];
+	MergeSort(aResult, aSymbols);
+	iNamedExportSymbolHead = aResult[0];
+	for (pos = 0; pos < iNamedExportCount; pos++) {
+		aSym = aResult[pos];
+		if( pos == iNamedExportCount-1)
+			aSym->Next(NULL);
+		else
+			aSym->Next(aResult[pos+1]);
+	}
+	*aDstList = aResult[0];
+	delete [] aResult;
+	delete [] aSymbols;
+}
+
+void ELFFile::ELFDllData::MergeSort(NamedExportSymbol** aDstList, NamedExportSymbol** aSrcList)
+{
+	MergeSort(aDstList, aSrcList, 0, iNamedExportCount);
+}
+
+void ELFFile::ELFDllData::MergeSort(NamedExportSymbol** aDstList, NamedExportSymbol** aSrcList, \
+									TUint aLeft, TUint aRight)
+{
+	if( (aRight - aLeft) <= 1)
+		return;
+
+	TUint aSize = aRight - aLeft;
+	TUint aCenter = aLeft + aSize/2;
+
+	MergeSort(aDstList, aSrcList, aLeft, aCenter);
+	MergeSort(aDstList, aSrcList, aCenter, aRight);
+
+	TUint aLPos, aRPos, aCnt;
+	aLPos = aLeft;
+	aRPos = aCenter;
+	for(aCnt = 0; aCnt < aSize; aCnt++)
+	{
+		if( (aLPos < aCenter) &&
+			(aRPos == aRight || (strcmp(aSrcList[aLPos]->Name(), aSrcList[aRPos]->Name()) < 0) )
+		  )
+		{
+			// Compare the left half with the right and add the lesser one.
+			// The comparision is done on the topmost element on each half.
+			// if aRPos is past the last element of the right half, the left element has 
+			// nothing to compare with. Just add it to the result list.
+			aDstList[aCnt] = aSrcList[aLPos];
+			aLPos++;
+		}
+		else
+		{
+			// Add the greater one into the list.
+			// if aLPos is past the element at the center, it anyway belongs to the
+			// right half. Add it to the result list.
+			aDstList[aCnt] = aSrcList[aRPos];
+			aRPos++;
+		}
+	}
+
+	// Once the sublist is sorted, put it back to the source list
+	// so that the parent has its left and right sublists are sorted.
+	for(aCnt = 0; aCnt < aSize; aCnt++)
+	{
+		aSrcList[aLeft+aCnt] = aDstList[aCnt];
+	}
+}
+