e32tools/elf2e32/source/pl_elfexecutable.cpp
changeset 0 044383f39525
child 684 2defe8c85348
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/e32tools/elf2e32/source/pl_elfexecutable.cpp	Tue Oct 27 16:36:35 2009 +0000
@@ -0,0 +1,1484 @@
+// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+// Implementation of the Class ElfExecutable for the elf2e32 tool
+// @internalComponent
+// @released
+// 
+//
+
+
+#include "pl_elfexecutable.h"
+#include "errorhandler.h"
+#include <stdio.h>
+#include "parameterlistinterface.h"
+#include "pl_elfimportrelocation.h"
+#include "pl_dllsymbol.h"
+#include "messagehandler.h"
+#include "pl_elflocalrelocation.h"
+
+
+/**
+Constructor for class ElfExecutable
+@param aParameterListInterface - Instance of class ParameterListInterface
+@internalComponent
+@released
+*/
+ElfExecutable::ElfExecutable(ParameterListInterface *aParameterListInterface) :\
+	iElfHeader(NULL), \
+	iEntryPoint(0),\
+	iProgHeader(NULL), \
+	iSONameOffset(0) ,\
+	iSections (NULL) , \
+	iVersionDef (NULL) , iVerDefCount(0), \
+	iVersionNeed (NULL) , iVerNeedCount(0), \
+	iVersionTbl (NULL) ,iRelSize(0),iRelEntSize(0), \
+	iNRelocs(0),
+	iRel (NULL) ,iRelaSize(0), iRelaEntSize(0), \
+	iRela(NULL), 
+	iStringTable (NULL) , \
+	iSectionHdrStrTbl(NULL), \
+	iVerInfo(NULL),	iElfDynSym (NULL), \
+	iSymTab (NULL), \
+	iStrTab (NULL), \
+	iLim (NULL), \
+	iNSymbols(0), \
+	iHashTbl (NULL) , \
+	iDynSegmentHdr (NULL) , \
+	iDataSegmentHdr (NULL) ,iDataSegment(NULL), iDataSegmentSize(0), iDataSegmentIdx(0), \
+	iCodeSegmentHdr (NULL) , iCodeSegment(NULL), iCodeSegmentSize(0), iCodeSegmentIdx(0), \
+	iExports (NULL), \
+	iParameterListInterface(aParameterListInterface),\
+	iPltGotBase(0), iPltGotLimit(0), iStrTabSz(0), iSymEntSz(0), \
+	iPltGot(NULL), iPltRel(NULL),iPltRelaSz(0), iPltRela(NULL), iPltRelSz(0)  \
+
+{
+}
+
+
+/**
+Destructor for class ElfExecutable
+@internalComponent
+@released
+*/
+ElfExecutable::~ElfExecutable()
+{
+	delete iExports;
+	delete [] iVerInfo;
+	/* 
+	all of these were getting deleted, they are not allocated by 
+	ElfExecutable, they simply refer to a linear array of images 
+	in an ElfImage, hence they shouldn't be de-allocated 
+	
+	delete iRela;
+	delete iPltRel;
+	delete iPltRela; */ 
+
+	iNeeded.clear();
+	iSymbolTable.clear();
+}
+
+
+/**
+Function to process Elf file
+@param aElfHdr - pointer to Elf header
+@return 0 if its valid ELF file
+@internalComponent
+@released
+*/
+PLUINT32  ElfExecutable::ProcessElfFile(Elf32_Ehdr *aElfHdr) {
+
+	iElfHeader = aElfHdr;
+	iEntryPoint = aElfHdr->e_entry;
+
+	ValidateElfFile();
+
+	/* A valid ELF file so far..*/
+
+	/* Get the Section base..*/
+	if(iElfHeader->e_shnum) {
+		iSections = ELF_ENTRY_PTR(Elf32_Shdr, iElfHeader, iElfHeader->e_shoff); 
+	}
+
+	/* Get the program header..*/
+	if(iElfHeader->e_phnum) {
+		iProgHeader = ELF_ENTRY_PTR(Elf32_Phdr, iElfHeader, iElfHeader->e_phoff);
+	}
+
+	/* Get the section-header-string table..*/
+	if(iElfHeader->e_shstrndx != SHN_UNDEF) {
+
+		if(iElfHeader->e_shstrndx > iElfHeader->e_shnum ) {
+			throw ELFFormatError(ELFSHSTRINDEXERROR,iParameterListInterface->ElfInput());
+		}
+
+		iSectionHdrStrTbl = ELF_ENTRY_PTR(char, iElfHeader, iSections[iElfHeader->e_shstrndx].sh_offset);
+	}
+
+	if( iProgHeader ) {
+		PLUINT32 aIdx = 0;
+
+		while( aIdx < iElfHeader->e_phnum) {
+			switch( iProgHeader[aIdx].p_type ) {
+			case PT_DYNAMIC:
+				{
+					iDynSegmentHdr = &iProgHeader[aIdx];
+				}
+				break;
+			case PT_LOAD:
+				{
+					if( (iProgHeader[aIdx].p_flags) & (PF_X | PF_ARM_ENTRY) ) {
+						iCodeSegmentHdr = &iProgHeader[aIdx];
+						iCodeSegmentIdx = aIdx;
+						iCodeSegment = ELF_ENTRY_PTR(char, iElfHeader, iCodeSegmentHdr->p_offset);
+						iCodeSegmentSize = iCodeSegmentHdr->p_filesz;
+					}
+					else if( (iProgHeader[aIdx].p_flags) & (PF_W | PF_R) ) {
+						iDataSegmentHdr = &iProgHeader[aIdx];
+						iDataSegmentIdx = aIdx;
+						iDataSegment = ELF_ENTRY_PTR(char, iElfHeader, iDataSegmentHdr->p_offset);
+						iDataSegmentSize = iDataSegmentHdr->p_filesz;
+					}
+				}
+				break;
+			default:
+				break;
+
+			}
+			aIdx++;
+		}
+
+		if( iDynSegmentHdr ) {
+			ProcessDynamicEntries();
+		}
+
+		ProcessSymbols();
+		ProcessRelocations();
+	}
+
+	return 0;
+}
+
+/**
+Function to Find the Static Symbol Table
+@internalComponent
+@released
+*/
+void ElfExecutable::FindStaticSymbolTable()
+{
+	size_t nShdrs = iElfHeader->e_shnum;
+
+	if (nShdrs)
+	{
+		// Find the static symbol table and string table
+		for (PLUINT32 i = 0; i < nShdrs; i++)
+		{
+			if (iSections[i].sh_type == SHT_SYMTAB)
+			{
+				iSymTab = ELF_ENTRY_PTR(Elf32_Sym, iElfHeader, iSections[i].sh_offset);
+				iLim = ELF_ENTRY_PTR(Elf32_Sym, iSymTab, iSections[i].sh_size);
+				if (iStrTab) break;
+			}
+			else if (iSections[i].sh_type == SHT_STRTAB)
+			{
+				char * aSectionName = iSectionHdrStrTbl + iSections[i].sh_name;
+				if (!strcmp(aSectionName, ".strtab"))
+				{
+					iStrTab = ELF_ENTRY_PTR(char, iElfHeader, iSections[i].sh_offset);
+					if (iSymTab) break;
+				}
+			}
+		}
+	}
+}
+
+/**
+Function to Find the Comment Section
+@return aComment - Pointer to Comment Section
+@internalComponent
+@released
+*/
+char* ElfExecutable::FindCommentSection()
+{
+	size_t nShdrs = iElfHeader->e_shnum;
+	char *aCommentSection = ".comment";
+	char *aComment;
+
+	if (nShdrs)
+	{
+		// find the comment section
+		for (PLUINT32 i = 0; i < nShdrs; i++)
+		{
+			if (iSections[i].sh_type == SHT_PROGBITS)
+			{
+				char * aSectionName = iSectionHdrStrTbl + iSections[i].sh_name;
+				int length = strlen(aCommentSection);
+				if (!strncmp(aSectionName, aCommentSection, length))
+				{
+					aComment = ELF_ENTRY_PTR(char, iElfHeader, iSections[i].sh_offset);
+					return aComment;
+				}
+			}
+		}
+	}
+	return NULL;
+}
+
+/**
+Function to process the ARM to Thumb veneers
+@internalComponent
+@released
+*/
+void ElfExecutable::ProcessVeneers()
+{
+	if (iSymTab && iStrTab)
+	{	
+		ElfRelocations::RelocationList & iLocalCodeRelocs = GetCodeRelocations();
+
+		Elf32_Sym *aSymTab = iSymTab;
+		int length = strlen("$Ven$AT$L$$");
+
+		// Process the symbol table to find Long ARM to Thumb Veneers
+		// i.e. symbols of the form '$Ven$AT$L$$'
+		for(; aSymTab < iLim; aSymTab++)
+		{
+			if (!aSymTab->st_name) continue;
+			char * aSymName = iStrTab + aSymTab->st_name;
+			Elf32_Sym	*aSym;
+
+			if (!strncmp(aSymName, "$Ven$AT$L$$", length))
+			{
+				aSym = aSymTab;
+				Elf32_Addr r_offset = aSym->st_value;
+				Elf32_Addr aOffset = r_offset + 4;
+				Elf32_Word	aInstruction = FindValueAtLoc(r_offset);
+				bool aRelocEntryFound = false;
+
+				ElfRelocations::RelocationList::iterator r;
+				for (r = iLocalCodeRelocs.begin(); r != iLocalCodeRelocs.end(); r++)
+				{
+					ElfLocalRelocation * aReloc = *r;
+					// Check if there is a relocation entry for the veneer symbol
+					if (aReloc->iAddr == aOffset)
+					{
+						aRelocEntryFound = true;
+						break;
+					}
+				}
+
+				Elf32_Word aPointer = FindValueAtLoc(aOffset);
+
+				/* If the symbol addresses a Thumb instruction, its value is the
+				 * address of the instruction with bit zero set (in a
+				 * relocatable object, the section offset with bit zero set).
+				 * This allows a linker to distinguish ARM and Thumb code symbols 
+				 * without having to refer to the map. An ARM symbol will always have 
+				 * an even value, while a Thumb symbol will always have an odd value.
+				 * Reference: Section 4.5.3 in Elf for the ARM Architecture Doc
+				 * aIsThumbSymbol will be 1 for a thumb symbol and 0 for ARM symbol
+				 */
+				int aIsThumbSymbol = aPointer & 0x1;
+
+				/* The relocation entry should be generated for the veneer only if
+				 * the following three conditions are satisfied:
+				 * 1) Check if the instruction at the symbol is as expected 
+				 *    i.e. has the bit pattern 0xe51ff004 == 'LDR pc,[pc,#-4]'
+				 * 2) There is no relocation entry generated for the veneer symbol
+				 * 3) The instruction in the location provided by the pointer is a thumb symbol
+				 */
+				if (aInstruction == 0xE51FF004 && !aRelocEntryFound && aIsThumbSymbol)
+				{
+					ElfLocalRelocation	*aRel;
+					PLUCHAR	aType = R_ARM_NONE;
+
+					aRel = new ElfLocalRelocation(this, aOffset, 0, 0, aType, NULL, ESegmentRO, aSym, false, true);
+					if(aRel) 
+					{
+						aRel->Add();
+					}
+				}
+			}
+		}
+	}
+}
+
+/**
+Function to find the content of the address passed in
+@param aOffset - Address
+@return aLocVal - The content of the address, like instruction or a pointer
+@internalComponent
+@released
+*/
+Elf32_Word	ElfExecutable::FindValueAtLoc(Elf32_Addr aOffset)
+{
+	Elf32_Phdr  *aHdr = Segment(aOffset);
+	PLUINT32 aLoc = aHdr->p_offset + aOffset - aHdr->p_vaddr;
+	Elf32_Word	*aLocVal = ELF_ENTRY_PTR(Elf32_Word, iElfHeader, aLoc);
+	return *aLocVal;
+}
+
+/**
+Function to process Elf symbols
+@internalComponent
+@released
+*/
+PLUINT32  ElfExecutable::ProcessSymbols(){
+	PLUINT32	aSymIdx = 0;
+	DllSymbol	*aSymbol;
+	char		*aDllName;
+	char		*aSymName, *aNewSymName;
+	SymbolType	aType;
+	
+	while( aSymIdx < iNSymbols ) {
+		
+		aSymName = ELF_ENTRY_PTR(char, iStringTable, iElfDynSym[aSymIdx].st_name );
+
+		if( ExportedSymbol( &iElfDynSym[aSymIdx] ) ){
+
+			if( FunctionSymbol( &iElfDynSym[aSymIdx] ))
+				aType = SymbolTypeCode;
+			else
+				aType = SymbolTypeData;
+
+			aSymName = ELF_ENTRY_PTR(char, iStringTable, iElfDynSym[aSymIdx].st_name );
+			aDllName = iVerInfo[iVersionTbl[aSymIdx]].iLinkAs;
+			aNewSymName = new char[strlen(aSymName)+1];
+			strcpy(aNewSymName, aSymName);
+			aSymbol = new DllSymbol( aNewSymName, aType, &iElfDynSym[aSymIdx], aSymIdx);
+			aSymbol->SetSymbolSize(iElfDynSym[aSymIdx].st_size);
+			
+			//Putting the symbols into a hash table - Used later while processing relocations
+			iSymbolTable[aSymIdx] = aSymbol ;
+			if( !AddToExports( aDllName, aSymbol ))
+			{
+				//Not a valid export... delete it..
+				delete aSymbol;
+			}
+		}
+		else if( ImportedSymbol( &iElfDynSym[aSymIdx] ) ){
+
+			if( FunctionSymbol( &iElfDynSym[aSymIdx] ))
+				aType = SymbolTypeCode;
+			else
+				aType = SymbolTypeData;
+
+			aSymName = ELF_ENTRY_PTR(char, iStringTable, iElfDynSym[aSymIdx].st_name );
+
+			/*
+			 * All imported symbols must be informed via the version needed information.
+			 */
+			if( iVerInfo[iVersionTbl[aSymIdx]].iVerCategory != VER_CAT_NEEDED ) {
+				throw UndefinedSymbolError(UNDEFINEDSYMBOLERROR, iParameterListInterface->ElfInput(), aSymName);
+			}
+			aDllName = iVerInfo[iVersionTbl[aSymIdx]].iLinkAs;
+			//aSymbol = new DllSymbol( aSymName, aType, &iElfDynSym[aSymIdx], aSymIdx);
+			
+			//Putting the symbols into a hash table
+			//iSymbolTable[aSymIdx] = aSymbol ;
+		}
+		aSymIdx++;
+	}
+
+	return 0;
+}
+
+/**
+This function Dump all the sections with their section details (i.e., the section name, type,
+size and linked section if any)
+@param aFile - ELF file name
+@internalComponent
+@released
+*/
+void ElfExecutable::DumpElfFile(char* aFile){
+	aFile = aFile;
+}
+
+
+/**
+This function adds exports into the export list
+@param aDll - Dll name
+@param aSymbol - Symbol
+@return
+@internalComponent
+@released
+*/
+DllSymbol* ElfExecutable::AddToExports(char* aDll, DllSymbol* aSymbol){
+	if( !iExports ) {
+		iExports = new ElfExports();
+	}
+	return iExports->Add( aDll, this, aSymbol );
+}
+
+
+/**
+This function adds imports into the map
+@param aReloc - Instance of class ElfImportRelocation
+@internalComponent
+@released
+*/
+void  ElfExecutable::AddToImports(ElfImportRelocation* aReloc){
+	SetVersionRecord(aReloc);
+	//char *aDll = iVerInfo[iVersionTbl[aReloc->iSymNdx]].iLinkAs;
+	char *aDll = aReloc->iVerRecord->iLinkAs;
+	iImports.Add( (const char*)aDll, aReloc );
+		
+}
+
+/**
+This function adds local relocation into a list
+@param aReloc - Instance of class ElfImportRelocation
+@internalComponent
+@released
+*/
+void ElfExecutable::AddToLocalRelocations(ElfRelocation* aReloc) {
+	iLocalRelocations.Add((ElfLocalRelocation*)aReloc);
+}
+
+/**
+This function records the version of an imported symbol
+@param aReloc - Instance of class ElfImportRelocation
+@internalComponent
+@released
+*/
+void ElfExecutable::SetVersionRecord( ElfRelocation* aReloc ) {
+	if( !aReloc )
+		return;
+	((ElfImportRelocation*)aReloc)->iVerRecord = &iVerInfo[ iVersionTbl[aReloc->iSymNdx]];
+}
+
+/**
+This function validates the ELF file
+@internalComponent
+@released
+*/
+PLUINT32  ElfExecutable::ValidateElfFile() {
+
+	/*Check if the ELF-Magic is correct*/
+	if(!(iElfHeader->e_ident[EI_MAG0] == ELFMAG0) &&
+		(iElfHeader->e_ident[EI_MAG1] == ELFMAG1) &&
+		(iElfHeader->e_ident[EI_MAG2] == ELFMAG2) &&
+		(iElfHeader->e_ident[EI_MAG3] == ELFMAG3) ) {
+			throw ELFFormatError(ELFMAGICERROR, iParameterListInterface->ElfInput());
+	}
+
+	/*32-bit ELF file*/
+	if(iElfHeader->e_ident[EI_CLASS] != ELFCLASS32) {
+		throw ELFFormatError(ELFCLASSERROR, iParameterListInterface->ElfInput());
+	}
+
+	/* Check if the ELF file is in Little endian format*/
+	if(iElfHeader->e_ident[EI_DATA] != ELFDATA2LSB) {
+		throw ELFFormatError(ELFLEERROR, iParameterListInterface->ElfInput());
+	}
+
+	/* The ELF executable must be a DLL or an EXE*/
+	if( iElfHeader->e_type != ET_EXEC && iElfHeader->e_type != ET_DYN) {
+		throw ELFFormatError(ELFEXECUTABLEERROR, iParameterListInterface->ElfInput());
+	}
+
+	return 0;
+}
+
+
+/**
+This function processes the dynamic table.
+@internalComponent
+@released
+*/
+PLUINT32  ElfExecutable::ProcessDynamicEntries(){
+
+	PLUINT32 aIdx = 0;
+	bool aSONameFound = false;
+	bool aPltRelTypeSeen = false, aJmpRelSeen = false;
+	list<PLUINT32>	aNeeded;
+	Elf32_Dyn *aDyn = ELF_ENTRY_PTR(Elf32_Dyn, iElfHeader, iDynSegmentHdr->p_offset);
+
+	while( aDyn[aIdx].d_tag != DT_NULL ) {
+		switch (aDyn[aIdx].d_tag) {
+		case DT_NEEDED:
+			aNeeded.push_back( aDyn[aIdx].d_val );
+			break;
+		case DT_HASH:
+			iHashTbl = ELF_ENTRY_PTR(Elf32_HashTable, iElfHeader, aDyn[aIdx].d_val);
+			break;
+		case DT_STRTAB:
+			iStringTable = ELF_ENTRY_PTR(char, iElfHeader, aDyn[aIdx].d_val);
+			break;
+		case DT_SYMTAB:
+			iElfDynSym = ELF_ENTRY_PTR(Elf32_Sym, iElfHeader, aDyn[aIdx].d_val);
+			break;
+		case DT_RELA:
+			iRela = ELF_ENTRY_PTR(Elf32_Rela, iElfHeader, aDyn[aIdx].d_val);
+			break;
+		case DT_RELASZ:
+			iRelaSize = aDyn[aIdx].d_val;
+			break;
+		case DT_RELAENT:
+			iRelaEntSize = aDyn[aIdx].d_val;
+			break;
+		case DT_SONAME:
+			aSONameFound = true;
+			iSONameOffset = aDyn[aIdx].d_val;
+			break;
+		case DT_REL:
+			iRel = ELF_ENTRY_PTR(Elf32_Rel, iElfHeader, aDyn[aIdx].d_val);
+			break;
+		case DT_RELSZ:
+			iRelSize = aDyn[aIdx].d_val;
+			break;
+		case DT_RELENT:
+			iRelEntSize = aDyn[aIdx].d_val;
+			break;
+		case DT_VERSYM:
+			iVersionTbl = ELF_ENTRY_PTR(Elf32_Half, iElfHeader, aDyn[aIdx].d_val);
+			break;
+		case DT_VERDEF:
+			iVersionDef = ELF_ENTRY_PTR(Elf32_Verdef, iElfHeader, aDyn[aIdx].d_val);
+			break;
+		case DT_VERDEFNUM:
+			iVerDefCount = aDyn[aIdx].d_val;
+			break;
+		case DT_VERNEED:
+			iVersionNeed = ELF_ENTRY_PTR(Elf32_Verneed, iElfHeader, aDyn[aIdx].d_val);
+			break;
+		case DT_VERNEEDNUM:
+			iVerNeedCount = aDyn[aIdx].d_val;
+			break;
+		case DT_STRSZ:
+			iStrTabSz = aDyn[aIdx].d_val;
+			break;
+		case DT_SYMENT:
+			iSymEntSz = aDyn[aIdx].d_val;
+			break;
+		case DT_PLTRELSZ:
+			iPltRelSz = aDyn[aIdx].d_val;
+			break;
+		case DT_PLTGOT:
+			iPltGot = ELF_ENTRY_PTR(Elf32_Word, iElfHeader, aDyn[aIdx].d_val);
+			break;
+		case DT_RPATH:
+			break;
+		case DT_SYMBOLIC:
+			break;
+		case DT_INIT:
+			break;
+		case DT_FINI:
+			break;
+		case DT_PLTREL:
+			aPltRelTypeSeen = true;
+			iPltRelType = aDyn[aIdx].d_val;
+			break;
+		case DT_DEBUG:
+			break;
+		case DT_TEXTREL:
+			break;
+		case DT_JMPREL:
+			aJmpRelSeen = true;
+			iJmpRelOffset = aDyn[aIdx].d_val;
+			break;
+		case DT_BIND_NOW:
+			break;
+		case DT_INIT_ARRAY:
+			break;
+		case DT_FINI_ARRAY:
+			break;
+		case DT_INIT_ARRAYSZ:
+			break;
+		case DT_FINI_ARRAYSZ:
+			break;
+		case DT_RELCOUNT:
+			break;
+		case DT_ARM_PLTGOTBASE:
+			iPltGotBase = aDyn[aIdx].d_val;
+			break;
+		case DT_ARM_PLTGOTLIMIT:
+			iPltGotLimit = aDyn[aIdx].d_val;
+			break;
+		case DT_ARM_SYMTABSZ:
+			iNSymbols = aDyn[aIdx].d_val;
+			break;
+		default:
+			//cout << "Unknown entry in dynamic table Tag=0x%x Value=0x%x",aDyn[aIdx].d_tag, aDyn[aIdx].d_val);
+			break;
+		}
+		aIdx++;
+	}
+
+	//String table is found, so get the strings...
+	if(aSONameFound) {
+		iSOName = ELF_ENTRY_PTR(char, iStringTable, iSONameOffset);
+	}
+
+	std::list<PLUINT32>::iterator aItr = aNeeded.begin();
+	char *aStr;
+	for( ; aItr != aNeeded.end();aItr++ ) {
+		aStr = ELF_ENTRY_PTR(char, iStringTable, *aItr);
+		iNeeded.push_back( aStr );
+	}
+
+	if(iVerNeedCount || iVerDefCount) {
+		ProcessVerInfo();
+	}
+
+	if(iHashTbl)
+	{
+		//The number of symbols should be same as the number of chains in hashtable
+		if (iNSymbols && (iNSymbols != iHashTbl->nChains))
+			throw ELFFormatError(SYMBOLCOUNTMISMATCHERROR,(char*)iParameterListInterface->ElfInput());
+		else
+		//The number of symbols is same as the number of chains in hashtable	
+			iNSymbols = iHashTbl->nChains;
+	}
+
+	if( aPltRelTypeSeen  && aJmpRelSeen) {
+
+		if (iPltRelType == DT_REL)
+		{
+			iPltRel = ELF_ENTRY_PTR(Elf32_Rel, iElfHeader, iJmpRelOffset);
+			// check to see if PltRels are included in iRel. If they are
+			// ignore them since we don't care about the distinction
+			if (iRel <= iPltRel && iPltRel < ELF_ENTRY_PTR(Elf32_Rel, iRel, iRelSize))
+				iPltRel = 0;
+		}
+		else
+		{
+			iPltRela = ELF_ENTRY_PTR(Elf32_Rela, iElfHeader, iJmpRelOffset);
+			// check to see if PltRels are included in iRel.  If they are
+			// ignore them since we don't care about the distinction
+			if (iRela <= iPltRela && iPltRela < ELF_ENTRY_PTR(Elf32_Rela, iRela, iRelaSize))
+				iPltRela = 0;
+		}
+	}
+
+	return 0;
+}
+
+/**
+This function processes version information
+@internalComponent
+@released
+*/
+void ElfExecutable::ProcessVerInfo() {
+	PLUINT32 aSz = iVerNeedCount + iVerDefCount + 1;
+	iVerInfo = new VersionInfo[aSz];
+
+	Elf32_Verdef	*aDef;
+	Elf32_Verdaux	*aDaux;
+	Elf32_Verneed	*aNeed;
+	Elf32_Vernaux	*aNaux;
+	char			*aSoName;
+	char			*aLinkAs;
+	
+	aDef = iVersionDef;
+	
+	while( aDef ) {
+		aDaux = ELF_ENTRY_PTR( Elf32_Verdaux, aDef, aDef->vd_aux);
+		aLinkAs = ELF_ENTRY_PTR(char, iStringTable, aDaux->vda_name );
+		aSoName = iSOName;
+		iVerInfo[aDef->vd_ndx].iLinkAs = aLinkAs;
+		iVerInfo[aDef->vd_ndx].iSOName = aSoName;
+		iVerInfo[aDef->vd_ndx].iVerCategory = VER_CAT_DEFINED;
+
+		if( !aDef->vd_next ) {
+			break;
+		}
+		aDef = ELF_ENTRY_PTR(Elf32_Verdef, aDef, aDef->vd_next);
+	}
+
+	aNeed = iVersionNeed;
+
+	while( aNeed ) {
+		aNaux = ELF_ENTRY_PTR(Elf32_Vernaux, aNeed, aNeed->vn_aux);
+		aLinkAs = ELF_ENTRY_PTR(char, iStringTable, aNaux->vna_name);
+		aSoName = ELF_ENTRY_PTR(char, iStringTable, aNeed->vn_file);
+
+		iVerInfo[aNaux->vna_other].iLinkAs = aLinkAs;
+		iVerInfo[aNaux->vna_other].iSOName = aSoName;
+		iVerInfo[aNaux->vna_other].iVerCategory = VER_CAT_NEEDED;
+
+		if( !aNeed->vn_next ) {
+			break;
+		}
+		aNeed = ELF_ENTRY_PTR(Elf32_Verneed, aNeed, aNeed->vn_next);
+	}
+}
+
+/**
+This function processes Elf relocations
+@internalComponent
+@released
+*/
+void ElfExecutable::ProcessRelocations(){
+	ProcessRelocations(iRel, iRelSize);
+	ProcessRelocations(iRela, iRelaSize);
+	ProcessRelocations(iPltRel, iPltRelSz);
+	ProcessRelocations(iPltRela, iPltRelaSz);
+}
+
+/**
+Template Function to process relocations
+@param aElfRel - relocation table
+@param aSize - relocation table size
+@internalComponent
+@released
+*/
+template <class T> 
+void ElfExecutable::ProcessRelocations(T *aElfRel, size_t aSize){
+	if( !aElfRel ) 
+		return;
+
+	T * aElfRelLimit = ELF_ENTRY_PTR(T, aElfRel, aSize);
+
+	PLUINT32		aSymIdx;
+	PLUCHAR			aType;
+	ElfRelocation	*aRel;
+	bool			aImported;
+	Elf32_Word		aAddend;
+
+	while( aElfRel < aElfRelLimit) {
+		
+		aType = ELF32_R_TYPE(aElfRel->r_info );
+		
+		if(ElfRelocation::ValidRelocEntry(aType)) {
+
+			aSymIdx = ELF32_R_SYM(aElfRel->r_info);
+			aImported = ImportedSymbol( &iElfDynSym[aSymIdx] );
+			aAddend = Addend(aElfRel);
+			aRel = ElfRelocation::NewRelocEntry(this, aElfRel->r_offset, aAddend, \
+				aSymIdx, aType, aElfRel, aImported);
+
+			if(aRel) {
+				aRel->Add();
+			}
+		}
+		aElfRel++;
+	}
+}
+
+/**
+This function finds the addend associated with a relocation entry.
+@param aRel - relocation entry
+@return location in the elf image
+@internalComponent
+@released
+*/
+Elf32_Word ElfExecutable::Addend(Elf32_Rel* aRel) {
+	PLUINT32 aOffset;
+	Elf32_Word	*aAddendPlace;
+	Elf32_Phdr  *aHdr = Segment(aRel->r_offset);
+	aOffset = aHdr->p_offset + aRel->r_offset - aHdr->p_vaddr;
+	aAddendPlace = ELF_ENTRY_PTR(Elf32_Word, iElfHeader, aOffset);
+	return *aAddendPlace;
+}
+
+/**
+This function returns the addend for a relocation entry
+@param aRel - relocation entry
+@return location in the elf image
+@internalComponent
+@released
+*/
+Elf32_Word ElfExecutable::Addend(Elf32_Rela* aRel) {
+	return aRel->r_addend;
+}
+
+/**
+This function gets the version info at an index
+@param aIndex - index into the version table
+@return version record
+@internalComponent
+@released
+*/
+VersionInfo* ElfExecutable::GetVersionInfo(PLUINT32  aIndex){
+	return &iVerInfo[ iVersionTbl[aIndex]];
+}
+
+
+/**
+This function returns the Dll name in which an imported symbol is 
+defined by looking in the version required section.
+@param aSymbolIndex - Index of symbol
+@return Dll name
+@internalComponent
+@released
+*/
+char* ElfExecutable::SymbolDefinedInDll(PLUINT32  aSymbolIndex){
+
+	VersionInfo *aVInfo = GetVersionInfo(aSymbolIndex);
+	return aVInfo ? aVInfo->iLinkAs : NULL;
+}
+
+/**
+This function returns the DSO(import library) name where the Symbol information can be found.
+This DSO is then looked up for the ordinal number of this symbol.
+@param aSymbolIndex - Index of symbol
+@return DSO name
+@internalComponent
+@released
+*/
+char* ElfExecutable::SymbolFromDSO(PLUINT32  aSymbolIndex){
+
+	VersionInfo *aVInfo = GetVersionInfo(aSymbolIndex);
+	return aVInfo ? aVInfo->iSOName : NULL;
+}
+
+/**
+This function returns the segment type
+@param aAddr - Address
+@return Segment type
+@internalComponent
+@released
+*/
+ESegmentType ElfExecutable::SegmentType(Elf32_Addr aAddr) {
+	
+	try {
+		Elf32_Phdr *aHdr = Segment(aAddr);
+		if( !aHdr )
+			return ESegmentUndefined;
+
+		if( aHdr == iCodeSegmentHdr)
+			return ESegmentRO;
+		else if(aHdr == iDataSegmentHdr)
+			return ESegmentRW;
+		else
+			return ESegmentUndefined;
+	}
+	catch(...)
+	{
+	}
+
+	return ESegmentUndefined;
+}
+
+/**
+This function returns the segment type
+@param aType
+@return Segment header
+@internalComponent
+@released
+*/
+Elf32_Phdr* ElfExecutable::Segment(ESegmentType aType) {
+	
+	switch(aType)
+	{
+	case ESegmentRO:
+		return iCodeSegmentHdr;
+	case ESegmentRW:
+		return iDataSegmentHdr;
+	default:
+		return NULL;
+	}
+}
+
+/**
+Function to get segment header
+@param aAddr - Address
+@return Segment header
+@internalComponent
+@released
+*/
+Elf32_Phdr* ElfExecutable::Segment(Elf32_Addr aAddr) {
+	
+	if(iCodeSegmentHdr) {
+		PLUINT32 aBase = iCodeSegmentHdr->p_vaddr;
+		if( aBase <= aAddr && aAddr < (aBase + iCodeSegmentHdr->p_memsz) ) {
+			return iCodeSegmentHdr;
+		}
+	}
+	if(iDataSegmentHdr) {
+		PLUINT32 aBase = iDataSegmentHdr->p_vaddr;
+		if( aBase <= aAddr && aAddr < (aBase + iDataSegmentHdr->p_memsz) ) {
+			return iDataSegmentHdr;
+		}
+	}
+
+	throw int(0);
+}
+
+/**
+Thsi function returns the segment header to which the address refers.
+@param aAddr - location
+@return Segment header.
+@internalComponent
+@released
+*/
+Elf32_Phdr* ElfExecutable::SegmentFromAbs(Elf32_Addr aAddr) {
+
+	if(iCodeSegmentHdr) {
+		PLUINT32 aBase = iCodeSegmentHdr->p_vaddr;
+		if( aBase <= aAddr && aAddr <= (aBase + iCodeSegmentHdr->p_memsz) ) {
+			return iCodeSegmentHdr;
+		}
+	}
+	if(iDataSegmentHdr) {
+		PLUINT32 aBase = iDataSegmentHdr->p_vaddr;
+		if( aBase <= aAddr && aAddr <= (aBase + iDataSegmentHdr->p_memsz) ) {
+			return iDataSegmentHdr;
+		}
+	}
+	return NULL;
+}
+
+/**
+This function says if the symbol is global.
+@param aSym - Symbol
+@return True if symbol is global, otherwise false
+@internalComponent
+@released
+*/
+bool ElfExecutable::GlobalSymbol(Elf32_Sym* aSym)
+{
+	return (ELF32_ST_BIND(aSym->st_info) == STB_GLOBAL);
+}
+
+/**
+This function says if the symbol is exported.
+@param aSym - Symbol
+@return True if symbol is exported, otherwise false
+@internalComponent
+@released
+*/
+bool ElfExecutable::ExportedSymbol(Elf32_Sym* aSym)
+{
+	PLUINT32 aIdx = aSym->st_shndx;
+
+	if(GlobalSymbol(aSym) && VisibleSymbol(aSym) && DefinedSymbol(aSym) && \
+		(aIdx != SHN_UNDEF) && (FunctionSymbol(aSym) || DataSymbol(aSym) ) && aIdx < SHN_ABS )
+		return true;
+	return false;
+}
+
+/**
+This function says if the symbol is imported.
+@param aSym - Symbol
+@return True if symbol is imported, otherwise false
+@internalComponent
+@released
+*/
+bool ElfExecutable::ImportedSymbol(Elf32_Sym* aSym)
+{
+	PLUINT32 aIdx = aSym->st_shndx;
+
+	if( (aIdx == SHN_UNDEF) && GlobalSymbol(aSym) && VisibleSymbol(aSym) && (!DefinedSymbol(aSym)) )
+		return true;
+	return false;
+}
+
+/**
+This function says if the symbol refers to code or data.
+@param aSym - Symbol
+@return True if symbol refers to code, otherwise false
+@internalComponent
+@released
+*/
+bool ElfExecutable::FunctionSymbol(Elf32_Sym* aSym)
+{
+	return (STT_FUNC == ELF32_ST_TYPE(aSym->st_info));
+}
+
+/**
+This function says if the symbol refers to code or data.
+@param aSym - Symbol
+@return True if symbol refers to data, otherwise false
+@internalComponent
+@released
+*/
+bool ElfExecutable::DataSymbol(Elf32_Sym* aSym)
+{
+	return (STT_OBJECT == ELF32_ST_TYPE(aSym->st_info));
+}
+
+/**
+This function says if the symbol is defined in the Elf executable.
+@param aSym - Symbol
+@return True if symbol is defined, otherwise false
+@internalComponent
+@released
+*/
+bool ElfExecutable::DefinedSymbol(Elf32_Sym* aSym)
+{
+	if( aSym->st_shndx == SHN_UNDEF )
+		return false;
+	ESegmentType aType = SegmentType(aSym->st_value);
+	return ((aType == ESegmentRO) || (aType == ESegmentRW));
+}
+
+/**
+This function says if the visibility of the symbol is default.
+@param aSym - Symbol
+@return True if symbol has default visibility, otherwise false
+@internalComponent
+@released
+*/
+bool ElfExecutable::VisibleSymbol(Elf32_Sym* aSym)
+{
+	return (STV_DEFAULT == ELF32_ST_VISIBILITY(aSym->st_other) || STV_PROTECTED == ELF32_ST_VISIBILITY(aSym->st_other));
+}
+
+/**
+This function finds symbol using the hash table
+@param aName - Symbol name
+@return elf symbol.
+@internalComponent
+@released
+*/
+Elf32_Sym* ElfExecutable::FindSymbol(char* aName) {
+	if(!aName )
+		return NULL;
+
+	PLULONG aHashVal = Util::elf_hash((const PLUCHAR*) aName );
+	
+	Elf32_Sword* aBuckets = ELF_ENTRY_PTR(Elf32_Sword, iHashTbl, sizeof(Elf32_HashTable) );
+	Elf32_Sword* aChains = ELF_ENTRY_PTR(Elf32_Sword, aBuckets, sizeof(Elf32_Sword)*(iHashTbl->nBuckets) );
+
+	Elf32_Sword aIdx = aHashVal % iHashTbl->nBuckets;
+	aIdx = aBuckets[aIdx];
+	
+	char	*aSymName;
+	do {
+		aSymName = ELF_ENTRY_PTR(char, iStringTable, iElfDynSym[aIdx].st_name);
+		if( !strcmp(aSymName, aName) ) {
+			return &iElfDynSym[aIdx];
+		}
+		aIdx = aChains[aIdx];
+	}while( aIdx > 0 );
+
+	return NULL;
+}
+
+/**
+Function to get symbol name
+@param aSymIdx - Index of symbol
+@return Symbol name
+@internalComponent
+@released
+*/
+char* ElfExecutable::GetSymbolName( PLUINT32 aSymIdx) {
+	return ELF_ENTRY_PTR(char, iStringTable, iElfDynSym[aSymIdx].st_name);
+}
+
+/**
+Function to get symbol ordinal
+@param aSymName - Symbol name
+@return Symbol ordinal
+@internalComponent
+@released
+*/
+PLUINT32 ElfExecutable::GetSymbolOrdinal( char* aSymName) {
+	Elf32_Sym	*aSym = FindSymbol(aSymName);
+	if( !aSym )
+		return (PLUINT32)-1;
+	return GetSymbolOrdinal( aSym );
+	
+}
+
+/**
+Function to get symbol ordinal
+@param aSym - Symbol
+@return Symbol ordinal
+@internalComponent
+@released
+*/
+PLUINT32 ElfExecutable::GetSymbolOrdinal( Elf32_Sym* aSym) {
+	PLUINT32 aOrd = (PLUINT32)-1;
+	if( aSym->st_shndx == ESegmentRO) {
+		Elf32_Word *aLocation, aOffset;
+
+		aOffset = iCodeSegmentHdr->p_offset + aSym->st_value - iCodeSegmentHdr->p_vaddr;
+		aLocation = ELF_ENTRY_PTR(Elf32_Word, iElfHeader, aOffset);
+		aOrd = *aLocation;
+	}
+	return aOrd;
+}
+
+/**
+Function to get relocation offset
+@param aReloc - Instance of class ElfRelocation
+@return offset
+@internalComponent
+@released
+*/
+Elf32_Word ElfExecutable::GetRelocationOffset(ElfRelocation * aReloc)
+{
+	Elf32_Phdr * aHdr = Segment(aReloc->iAddr);
+	unsigned int aOffset = aReloc->iAddr - aHdr->p_vaddr;
+	return aOffset;
+}
+
+/**
+Function to get relocation place address
+@param aReloc - Instance of class ElfRelocation
+@return address to place relocation
+@internalComponent
+@released
+*/
+Elf32_Word * ElfExecutable::GetRelocationPlace(ElfRelocation * aReloc)
+{
+	Elf32_Phdr * aHdr = Segment(aReloc->iAddr);
+	unsigned int aOffset = aHdr->p_offset + aReloc->iAddr - aHdr->p_vaddr;
+	Elf32_Word * aPlace = ELF_ENTRY_PTR(Elf32_Word, iElfHeader, aOffset);
+	return aPlace;
+}
+
+/**
+Function to get local relocation
+@return local relocation
+@internalComponent
+@released
+*/
+ElfRelocations& ElfExecutable::GetLocalRelocations()
+{
+	return iLocalRelocations;
+}
+
+/**
+Function to get code relocation
+@return code relocation list
+@internalComponent
+@released
+*/
+ElfRelocations::RelocationList & ElfExecutable::GetCodeRelocations()
+{
+	return GetLocalRelocations().GetCodeRelocations();
+}
+
+/**
+Function to get data relocation
+@return data relocation list
+@internalComponent
+@released
+*/
+ElfRelocations::RelocationList & ElfExecutable::GetDataRelocations()
+{
+	return GetLocalRelocations().GetDataRelocations();
+}
+
+/**
+Function to get RO base address
+@return RO base virtual address
+@internalComponent
+@released
+*/
+Elf32_Word ElfExecutable::GetROBase()
+{
+	if (iCodeSegmentHdr) return iCodeSegmentHdr->p_vaddr;
+	return 0;
+}
+
+/**
+Function to get RO segment
+@return code segment
+@internalComponent
+@released
+*/
+MemAddr ElfExecutable::GetRawROSegment()
+{
+	return iCodeSegment;
+}
+
+/**
+Function to get RW segment virtual address
+@return RW base address
+@internalComponent
+@released
+*/
+Elf32_Word ElfExecutable::GetRWBase()
+{
+	if (iDataSegmentHdr) return iDataSegmentHdr->p_vaddr;
+	return 0;
+}
+
+/**
+Function to get Raw RW segment
+@return data segment address
+@internalComponent
+@released
+*/
+MemAddr ElfExecutable::GetRawRWSegment()
+{
+	return iDataSegment;
+}
+
+/**
+Function to get RO segment size
+@return code segment size
+@internalComponent
+@released
+*/
+size_t ElfExecutable::GetROSize()
+{
+	return iCodeSegmentHdr->p_filesz;
+}
+
+/**
+Function to get RW segment size
+@return data segment size
+@internalComponent
+@released
+*/
+size_t ElfExecutable::GetRWSize()
+{
+	if (iDataSegmentHdr)
+		return iDataSegmentHdr->p_filesz;;
+	return 0;
+}
+
+/**
+Function to get Bss segment size
+@return Bss segment size, if data segment, otherwise 0
+@internalComponent
+@released
+*/
+size_t ElfExecutable::GetBssSize()
+{
+	if (iDataSegmentHdr)
+		return iDataSegmentHdr->p_memsz - iDataSegmentHdr->p_filesz;
+	return 0;
+}
+
+/**
+Function returns entry point location in Elf image.
+@return entry point offset if valid, warning if undefined, otherwise throw error
+@internalComponent
+@released
+*/
+Elf32_Word ElfExecutable::EntryPointOffset()
+{
+	if (!(iElfHeader->e_entry) && !(iCodeSegmentHdr->p_vaddr))
+	{
+		MessageHandler::GetInstance()->ReportMessage(WARNING, UNDEFINEDENTRYPOINTERROR,(char*)iParameterListInterface->ElfInput());
+		return 0;
+	}
+	else if (!(iElfHeader->e_entry))
+		throw ELFFormatError(ENTRYPOINTNOTSETERROR, (char*)iParameterListInterface->ElfInput());
+	else 
+		return iElfHeader->e_entry - iCodeSegmentHdr->p_vaddr;
+}
+
+/**
+Function to check exception is present in the Elf image.
+@return True if exception present, otherwise false
+@internalComponent
+@released
+*/
+bool ElfExecutable::ExeceptionsPresentP()
+{	
+	size_t nShdrs = iElfHeader->e_shnum;
+	if (nShdrs)
+	{
+		// Find the exception index table section
+		Elf32_Shdr * aShdr = ELF_ENTRY_PTR(Elf32_Shdr, iElfHeader, iElfHeader->e_shoff);
+		char * aShStrTab = ELF_ENTRY_PTR(char, iElfHeader, aShdr[iElfHeader->e_shstrndx].sh_offset);
+
+		for (PLUINT32 i = 0; i < nShdrs; i++)
+		{
+			if (aShdr[i].sh_type == SHT_ARM_EXIDX)
+			{
+				char * aSectionName = aShStrTab + aShdr[i].sh_name;
+				if (!strcmp(aSectionName, ".ARM.exidx"))
+				{
+					return true;
+				}
+			}
+		}
+
+	}
+	else
+		throw ELFFileError(NEEDSECTIONVIEWERROR, (char*)iParameterListInterface->ElfInput());
+	
+	return false;
+}
+
+/**
+Function to get the exports in ordinal number order.
+@return ordered exports
+@internalComponent
+@released
+*/
+ElfExports::ExportList &ElfExecutable::GetExportsInOrdinalOrder() {
+	return iExports->GetExportsInOrdinalOrder();
+}
+
+/**
+This function looks up for a symbol in the static symbol table.
+@return Elf symbol.
+@internalComponent
+@released
+*/
+Elf32_Sym * ElfExecutable::LookupStaticSymbol(char * aName) {
+	size_t nShdrs = iElfHeader->e_shnum;
+	if (nShdrs)
+	{
+		// find the static symbol table and string table
+		Elf32_Shdr * aShdr = ELF_ENTRY_PTR(Elf32_Shdr, iElfHeader, iElfHeader->e_shoff);
+		char * aShStrTab = ELF_ENTRY_PTR(char, iElfHeader, aShdr[iElfHeader->e_shstrndx].sh_offset);
+		Elf32_Sym * aSymTab = 0;
+		Elf32_Sym * aLim = 0;
+		char * aStrTab = 0;
+		for (PLUINT32 i = 0; i < nShdrs; i++)
+		{
+			if (aShdr[i].sh_type == SHT_SYMTAB)
+			{
+				aSymTab = ELF_ENTRY_PTR(Elf32_Sym, iElfHeader, aShdr[i].sh_offset);
+				aLim = ELF_ENTRY_PTR(Elf32_Sym, aSymTab, aShdr[i].sh_size);
+				if (aStrTab) break;
+			}
+			else if (aShdr[i].sh_type == SHT_STRTAB)
+			{
+				char * aSectionName = aShStrTab + aShdr[i].sh_name;
+				if (!strcmp(aSectionName, ".strtab"))
+				{
+					aStrTab = ELF_ENTRY_PTR(char, iElfHeader, aShdr[i].sh_offset);
+					if (aSymTab) break;
+				}
+			}
+		}
+
+		/*if(aHashTbl && aSymTab && aStrTab)
+		{
+			PLULONG aHashVal = Util::elf_hash((const PLUCHAR*)aName);
+			Elf32_Sword* aBuckets = ELF_ENTRY_PTR(Elf32_Sword, aHashTbl, sizeof(Elf32_HashTable) );
+			Elf32_Sword* aChains = ELF_ENTRY_PTR(Elf32_Sword, aBuckets, sizeof(Elf32_Sword)*(aHashTbl->nBuckets) );
+
+			PLUINT32 aIdx = aHashVal % aHashTbl->nBuckets;
+			aIdx = aBuckets[aIdx];
+			
+			char	*aSymName;
+			do {
+				aSymName = ELF_ENTRY_PTR(char, aStrTab, aSymTab[aIdx].st_name);
+				if( !strcmp(aSymName, aName) ) {
+					return &aSymTab[aIdx];
+				}
+				aIdx = aChains[aIdx];
+			}while( aIdx > 0 );
+
+			return NULL;
+		}
+		else */ 
+
+		if (aSymTab && aStrTab)
+		{	
+			for(; aSymTab < aLim; aSymTab++)
+			{
+				if (!aSymTab->st_name) continue;
+				char * aSymName = aStrTab + aSymTab->st_name;
+				if (!strcmp(aSymName, aName))
+					return aSymTab;
+			}
+			return 0;
+		}
+		else
+		{
+			throw ELFFileError(NOSTATICSYMBOLSERROR, (char*)iParameterListInterface->ElfInput());
+		}
+	}
+	else
+	{
+			throw ELFFileError(NOSTATICSYMBOLSERROR, (char*)iParameterListInterface->ElfInput());
+	}
+}
+
+/**
+Function to get imports
+@return imports
+@internalComponent
+@released
+*/
+ElfImports::ImportMap ElfExecutable::GetImports() {
+	return iImports.GetImports();
+}
+
+/**
+Function to get exports
+@return exports
+@internalComponent
+@released
+*/
+ElfExports* ElfExecutable::GetExports() {
+	return iExports;
+}
+
+/**
+Function to get fixup location
+@param aReloc - Instance of class ElfLocalRelocation
+@param aPlace -
+@return addres of position for relocation
+@internalComponent
+@released
+*/
+Elf32_Word* ElfExecutable::GetFixupLocation(ElfLocalRelocation* aReloc, Elf32_Addr aPlace)
+{
+	Elf32_Phdr * aPhdr = aReloc->ExportTableReloc() ? 
+		iCodeSegmentHdr :
+		Segment(aPlace);
+	Elf32_Word offset = aPhdr->p_offset + aPlace - aPhdr->p_vaddr;
+	return ELF_ENTRY_PTR(Elf32_Word, iElfHeader, offset);
+}
+
+/**
+Function to get the segment type
+@param aSym - Symbol
+@return Segment type
+@internalComponent
+@released
+*/
+ESegmentType ElfExecutable::Segment(Elf32_Sym *aSym)
+{
+	Elf32_Phdr * aHdr;
+
+	try {
+
+		bool limitSymbolFound = false;
+
+		// If Symbol is absolute then assume it came from linker and is a
+		// limit symbol.
+		if (aSym->st_shndx == SHN_ABS)
+		{
+			aHdr = SegmentFromAbs(aSym->st_value);
+		}
+		else
+		{
+			if( (iCodeSegmentHdr && aSym->st_value == (iCodeSegmentHdr->p_vaddr + iCodeSegmentHdr->p_memsz)) ||
+				(iDataSegmentHdr && aSym->st_value == (iDataSegmentHdr->p_vaddr + iDataSegmentHdr->p_memsz)) )
+			{
+				//If Symbol is a $$Limit symbol, then consider the open boundary.
+				String limitstr = iStringTable + aSym->st_name;
+				if (limitstr.rfind("$$Limit",limitstr.length()) != String::npos)
+				{
+					aHdr = SegmentFromAbs(aSym->st_value);
+					limitSymbolFound = true;
+				}
+			}
+
+			if(!limitSymbolFound )
+			{
+				aHdr = Segment(aSym->st_value);
+			}
+
+		}
+		
+		if (aHdr == iCodeSegmentHdr)
+		{
+			return ESegmentRO;
+		} 
+		else if (aHdr == iDataSegmentHdr)
+		{
+			return ESegmentRW;
+		}
+	}
+	catch(...)
+	{
+	}
+	return ESegmentUndefined;
+}
+