toolsandutils/e32tools/elf2e32/source/pl_elfexports.cpp
changeset 0 83f4b4db085c
child 1 d4b442d23379
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/toolsandutils/e32tools/elf2e32/source/pl_elfexports.cpp	Tue Feb 02 01:39:43 2010 +0200
@@ -0,0 +1,265 @@
+// 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 ElfExports for the elf2e32 tool
+// @internalComponent
+// @released
+// 
+//
+
+#include "pl_elfexports.h"
+#include "pl_elfexecutable.h"
+#include "pl_dllsymbol.h"
+
+using std::set_difference;
+
+/**
+Constructor for class ElfExports
+@internalComponent
+@released
+*/
+ElfExports::ElfExports() : iDllName(NULL), iSorted(false), iExportsFilteredP(false){
+}
+
+/**
+Destructor for class ElfExports
+@internalComponent
+@released
+*/
+ElfExports::~ElfExports()
+{
+	if(iExportList.size())
+	{
+		ExportList::iterator aItr = iExportList.begin();
+		ExportList::iterator last = iExportList.end();
+		DllSymbol *temp;
+
+		while( aItr != last)
+		{
+			temp = *aItr;
+			aItr++;
+			delete temp;
+		}
+	}
+	iExportList.clear();
+
+}
+
+/**
+This function validates exported symbols. The typeinfo name strings
+are not valid export symbols and are discarded.
+@param aExecutable - Instance of class ElfExecutable
+@param aSym	- DllSymbol
+@return True if symbol is valid, otherwise false
+@internalComponent
+@released
+*/
+bool ElfExports::ValidExportP(ElfExecutable * aExecutable, DllSymbol * aSym)
+{
+	char * aSymName = aExecutable->GetSymbolName(aSym->iSymbolIndex);
+	int result = strncmp(aSymName, "_ZTS", strlen("_ZTS"));
+	return ( result != 0);
+}
+
+/**
+This function adds export symbols into exports list.
+@param aDll - Dll name
+@param aExecutable - Instance of class ElfExecutable
+@param aSym - Dll symbol
+@return Dll Symbol if its valid, otherwise NULL
+@internalComponent
+@released
+*/
+DllSymbol* ElfExports::Add(char *aDll, ElfExecutable * aExecutable, DllSymbol *aSym)
+{
+	if (ValidExportP(aExecutable, aSym))
+	{
+		if( !iDllName )
+			iDllName = aDll;
+
+		iExportList.push_back(aSym);
+		iSorted = false;
+		return aSym;
+	}
+	return NULL;
+}
+
+/**
+Function to add elf exports
+@param aDll - Dll name
+@param aSym - Dll symbol
+@internalComponent
+@released
+*/
+void ElfExports::Add(char *aDll, DllSymbol *aSym)
+{
+	if( !iDllName )
+		iDllName = aDll;
+	iExportList.push_back(aSym);
+	iSorted = false;
+}
+
+/**
+Function to sort elf exports. Sorting may be done based on the symbol
+name or on the ordinal number depending on the usecase.
+@internalComponent
+@released
+*/
+void ElfExports::Sort() 
+{
+	if (!iSorted) {
+		if(iExportsFilteredP) {
+			std::sort(iFilteredExports.begin(), iFilteredExports.end(), PtrELFExportNameCompare());
+		}
+		else {
+			std::sort(iExportList.begin(), iExportList.end(), PtrELFExportNameCompare());
+		}
+		iSorted = true;
+	}
+}
+
+/**
+Function to get exports list.
+@param aSorted - sort before returning the exports.
+@return export list
+@internalComponent
+@released
+*/
+ElfExports::ExportList & ElfExports::GetExports(bool aSorted)
+{
+	if (aSorted) Sort();
+	
+	if(iExportsFilteredP) 
+		return iFilteredExports;
+	else
+		return iExportList;
+}
+
+/**
+Function to get exports in ordinal order
+@return export list
+@internalComponent
+@released
+*/
+ElfExports::ExportList & ElfExports::GetExportsInOrdinalOrder()
+{
+	if (iExportsFilteredP)
+	{
+		std::sort(iFilteredExports.begin(), iFilteredExports.end(), PtrELFExportOrdinalCompare());
+		return iFilteredExports;
+	}
+	else
+	{
+		std::sort(iExportList.begin(), iExportList.end(), PtrELFExportOrdinalCompare());
+		return iExportList;
+	}
+}
+
+/**
+Function to process the filtered exports
+@internalComponent
+@released
+*/
+void ElfExports::FilterExports()
+{
+	std::sort(iExportList.begin(), iExportList.end(), PtrELFExportNameCompare());
+	std::sort(iFilteredExports.begin(), iFilteredExports.end(), PtrELFExportNameCompare());
+
+	ExportList aNewList(iExportList.size());
+	ExportList::iterator aNewListBegin = aNewList.begin(); 
+
+	ExportList::iterator aNewListEnd = set_difference(iExportList.begin(), iExportList.end(), \
+		iFilteredExports.begin(), iFilteredExports.end(), aNewListBegin, PtrELFExportNameCompare());
+
+	iFilteredExports.clear();
+	while (aNewListBegin != aNewListEnd)
+	{
+		iFilteredExports.push_back(*aNewListBegin);
+		aNewListBegin++;
+	}
+}
+
+/**
+Function to get number of exports
+@return size of export list
+@internalComponent
+@released
+*/
+size_t ElfExports::GetNumExports()
+{
+	return iExportList.size();
+}
+
+/**
+Function to get Dll name
+@return Dll name
+@internalComponent
+@released
+*/
+char* ElfExports::DllName()
+{ 
+	return iDllName;
+}
+
+/**
+Overloaded operator to compare ELF export names.
+@return True if lhs symbol name < rhs symbol name, otherwise false
+@internalComponent
+@released
+*/
+bool ElfExports::PtrELFExportNameCompare::operator()(const Symbol * lhs, const Symbol * rhs) const
+{
+	return strcmp( lhs->SymbolName(), rhs->SymbolName()) < 0;
+}
+
+/**
+Overloaded operator to compare ordinal numbers of symbols.
+@return True if lhs symbol name < rhs symbol name, otherwise false
+@internalComponent
+@released
+*/
+bool ElfExports::PtrELFExportOrdinalCompare::operator()(const Symbol * lhs, const Symbol * rhs) const
+{
+	return lhs->OrdNum() < rhs->OrdNum();
+}
+
+/**
+Overloaded operator to compare update symbol attributes that are 
+being compared. The comparision is done on the symbol names.
+@return True if lhs symbol name < rhs symbol name, otherwise false
+@internalComponent
+@released
+*/
+bool ElfExports::PtrELFExportNameCompareUpdateAttributes::operator()(const Symbol * lhs, const Symbol * rhs) const
+{
+	int result = strcmp(lhs->SymbolName(), rhs->SymbolName());
+	if (!result) 
+	{
+		if (lhs->OrdNum() > 0)
+			((Symbol*)rhs)->SetOrdinal( lhs->OrdNum());
+		else if (rhs->OrdNum() > 0)
+			((Symbol*)lhs)->SetOrdinal( rhs->OrdNum());
+				
+		if( ((Symbol*)lhs)->Absent() )
+			((Symbol*)rhs)->SetAbsent(true);
+		else if ( ((Symbol*)rhs)->Absent() )
+			((Symbol*)lhs)->SetAbsent(true);
+
+		if( ((Symbol*)lhs)->SymbolSize() )
+			((Symbol*)rhs)->SetSymbolSize(((Symbol*)lhs)->SymbolSize());
+		else if( ((Symbol*)rhs)->SymbolSize() )
+			((Symbol*)lhs)->SetSymbolSize(((Symbol*)rhs)->SymbolSize());
+	}
+	return result < 0;
+}
+