imgtools/romtools/rombuild/r_areaset.cpp
changeset 590 360bd6b35136
parent 0 044383f39525
child 617 3a747a240983
--- a/imgtools/romtools/rombuild/r_areaset.cpp	Wed Jun 16 16:51:40 2010 +0300
+++ b/imgtools/romtools/rombuild/r_areaset.cpp	Wed Jun 23 16:56:47 2010 +0800
@@ -1,554 +1,504 @@
-/*
-* 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: 
-* Area-related classes implementation
-*
-*/
-
-
-#include "r_areaset.h"
-#include "r_global.h"
-#include "r_rom.h"
-
-extern TBool gGenDepGraph;
-extern char* gDepInfoFile;
-
-using namespace std;
-
-////////////////////////////////////////////////////////////////////////
-
-Area::Area(const char* aName, TLinAddr aDestBaseAddr, TUint aMaxSize, Area* aNext)
-	: iFirstPagedCode(0),
-	  iName(strdup(aName)),
-	  iDestBaseAddr(aDestBaseAddr),
-	  iSrcBaseAddr(0),
-	  iSrcLimitAddr(0),
-	  iMaxSize(aMaxSize),
-	  iIsDefault(strcmp(aName, AreaSet::KDefaultAreaName) == 0),
-	  iFiles(0),
-	  iNextFilePtrPtr(&iFiles),
-	  iNextArea(aNext)
-	  
-	{
-	}
-
-
-Area::~Area()
-	{
-	ReleaseAllFiles();
-	free(const_cast<char*>(iName));	// allocated with strdup()
-	}
-
-
-/**
- Increase the size of the area.
-
- The reallocation must not exceed the area maximum size.
-
- @param aSrcLimitAddr New source top address
-
- @param aOverflow Number of overflow bytes if failure.
-
- @return success indication
-*/
-
-TBool Area::ExtendSrcLimitAddr(TLinAddr aSrcLimitAddr, TUint& aOverflow)
-	{
-	// must have been set before
-	assert(iSrcBaseAddr != 0);
-	// can only allocate more
-	assert(aSrcLimitAddr > iSrcBaseAddr);
-
-	if (aSrcLimitAddr-iSrcBaseAddr > iMaxSize)
-		{
-		aOverflow = aSrcLimitAddr-iSrcBaseAddr-iMaxSize;
-		return EFalse;
-		}
-
-	iSrcLimitAddr = aSrcLimitAddr;
-	return ETrue;
-	}
-
-
-/**
- Add a file at end of the list of files contained in this area.
-
- @param aFile File to add.  Must be allocated on the heap.  Ownership
- is transfered from the caller to the callee.
-*/
-
-void Area::AddFile(TRomBuilderEntry* aFile)
-	{
-	assert(aFile != 0);
-
-	*iNextFilePtrPtr = aFile;
-	iNextFilePtrPtr = &(aFile->iNextInArea);
-	}
-
-
-void Area::ReleaseAllFiles()
-	{
-	for (TRomBuilderEntry *next = 0, *current = iFiles;
-		 current != 0;
-		 current = next)
-		{
-		next = current->iNextInArea;
-		delete current;
-		}
-
-	iFiles = 0;
-	iNextFilePtrPtr = &iFiles;
-	}
-
-////////////////////////////////////////////////////////////////////////
-
-void FilesInAreaIterator::GoToNext()
-	{
-	assert(iCurrentFile!=0);
-	iCurrentFile = iCurrentFile->iNextInArea;
-	}
-
-////////////////////////////////////////////////////////////////////////
-
-const char AreaSet::KDefaultAreaName[] = "DEFAULT AREA";
-
-AreaSet::AreaSet()
-	: iNonDefaultAreas(0),
-	  iDefaultArea(0),
-	  iAreaCount(0)
-	{
-	}
-
-
-AreaSet::~AreaSet()
-	{
-	ReleaseAllAreas();
-	}
-
-
-inline TBool IsInRange(TLinAddr aAddr, TLinAddr aDestBaseAddr, TLinAddr aEndAddr)
-	{
-	return aDestBaseAddr <= aAddr && aAddr <= aEndAddr;
-	}
-
-
-/**
- Add a new area.
-
- Areas must have unique name, not overlap one another and not overflow
- the 32-bit address range.  
-
- @param aOverlappingArea On return ptr to name of overlapping area if
- any, 0 otherwise.
-
- @return EAdded if success, an error code otherwise.  
-*/
-
-AreaSet::TAddResult AreaSet::AddArea(const char* aNewName,
-									 TLinAddr aNewDestBaseAddr,
-									 TUint aNewMaxSize,
-									 const char*& aOverlappingArea)
-	{
-	assert(aNewName != 0 && strlen(aNewName) > 0);
-	assert(aNewMaxSize > 0);
-
-	aOverlappingArea = 0;
-
-	//
-	// Checking new area validity
-	//
-
-	if (aNewDestBaseAddr+aNewMaxSize <= aNewDestBaseAddr)
-		return EOverflow;
-
-	TLinAddr newEndAddr = aNewDestBaseAddr+aNewMaxSize-1;
-
-	// iterate non default areas first, then the default one if any
-	Area* area=iNonDefaultAreas; 
-	while (area != 0)
-		{
-		if (strcmp(area->Name(), aNewName) == 0)
-			return EDuplicateName;
-
-		TLinAddr curDestBaseAddr = area->DestBaseAddr();
-		TLinAddr curEndAddr = area->DestBaseAddr()+area->MaxSize()-1;
-
-		if (IsInRange(newEndAddr, curDestBaseAddr, curEndAddr) ||
-			IsInRange(aNewDestBaseAddr, curDestBaseAddr, curEndAddr) ||
-			IsInRange(curDestBaseAddr, aNewDestBaseAddr, newEndAddr))
-			{
-			aOverlappingArea = area->Name();
-			return EOverlap;
-			}
-
-		if (area->iNextArea == 0 && area != iDefaultArea)
-			area = iDefaultArea;
-		else
-			area = area->iNextArea;
-		}
-	
-	//
-	// Adding new area
-	//
-
-	if (strcmp(KDefaultAreaName, aNewName) == 0)
-		iDefaultArea = new Area(aNewName, aNewDestBaseAddr, aNewMaxSize);
-	else
-		iNonDefaultAreas = new Area(aNewName, aNewDestBaseAddr, aNewMaxSize, iNonDefaultAreas);
-	++iAreaCount;
-
-	return EAdded;
-	}
-
-
-/**
- Remove every area added to the set.
-
- As a side-effect every file added to the areas is deleted.
-*/
-
-void AreaSet::ReleaseAllAreas()
-	{
-	for (Area *next = 0, *current = iNonDefaultAreas; current != 0; current = next)
-		{
-		next = current->iNextArea;
-		delete current;
-		}
-
-	iNonDefaultAreas = 0;
-
-	delete iDefaultArea;
-	iDefaultArea = 0;
-	}
-
-
-/**
- Find an area from its name.
-
- @return A pointer to the area or 0 if the name is unknown.  The
- returned pointer becomes invalid when "this" is destructed.
-*/
-
-Area* AreaSet::FindByName(const char* aName) const
-	{
-	assert(aName != 0 && strlen(aName) > 0);
-
-	if (iDefaultArea && strcmp(iDefaultArea->Name(), aName) == 0)
-		return iDefaultArea;
-
-	for (Area* area=iNonDefaultAreas; area != 0; area = area->iNextArea)
-		{
-		if (strcmp(area->Name(), aName) == 0)
-			return area;
-		}
-
-	return 0;
-	}
-
-
-////////////////////////////////////////////////////////////////////////
-
-void NonDefaultAreasIterator::GoToNext()
-	{
-	assert(iCurrentArea!=0);
-	iCurrentArea = iCurrentArea->iNextArea;
-	}
-
-TInt Area::SortFilesForPagedRom()
-	{
-	Print(ELog,"Sorting files to paged/unpaged.\n");
-	TRomBuilderEntry* extention[2] = {0,0};
-	TRomBuilderEntry* unpaged[2] = {0,0};
-	TRomBuilderEntry* normal[2] = {0,0};
-	TRomBuilderEntry* current = iFiles;
-	while(current)
-		{
-		TRomBuilderEntry** list;
-		if((current->iRomImageFlags & (KRomImageFlagPrimary|KRomImageFlagVariant|KRomImageFlagExtension|KRomImageFlagDevice)) ||
-			current->HCRDataFile())
-			list = extention;
-		else if(current->iRomImageFlags&(KRomImageFlagCodeUnpaged))
-			list = unpaged;
-		else if(current->iResource && (current->iOverrideFlags&KOverrideCodeUnpaged) && gPagedRom)
-			list = unpaged;
-		else
-			list = normal;
-
-		if(list!=normal)
-			{
-			Print(ELog, "Unpaged file %s\n",current->iRomNode->BareName());
-			}
-
-		if(!list[0])
-			list[0] = current;
-		else
-			list[1]->iNextInArea = current;
-		list[1] = current;
-
-		current = current->iNext;
-		}
-
-	if(extention[1])
-		{
-		if(unpaged[0])
-			{
-			extention[1]->iNextInArea = unpaged[0];
-			unpaged[1]->iNextInArea = normal[0];
-			}
-		else
-			extention[1]->iNextInArea = normal[0];
-
-		if (normal[1])
-			normal[1]->iNextInArea = 0;
-
-		iFiles = extention[0];
-		}
-	else{
-		Print(EError,"No primary files.\n");
-		return KErrGeneral;
-	}
-
-	iFirstPagedCode = normal[0];
-	Print(ELog,"\n");
-	if(gGenDepGraph)
-		WriteDependenceGraph();
-	return KErrNone;
-	}
-
-
-void Area::WriteDependenceGraph()
-{
-	TDepInfoList::iterator infoIt;
-	TStringList::iterator strIt;
-	TDepInfoList myDepInfoList;
-	TRomBuilderEntry* e = iFirstPagedCode;
-	char buffer[255];
-	TInt count = 0;
-	TStringList nameList;
-	while(e)
-	{
-		DepInfo tmpDepInfo;
-		TRomNode* rn = e->iRomNode;
-		TInt ll = rn->FullNameLength();
-		char* mm = (char*) malloc(ll+1);
-		rn->GetFullName(mm);
-		sprintf(buffer, "f%d", count);
-		tmpDepInfo.portName = buffer;
-		tmpDepInfo.index = count;
-		myDepInfoList[mm] = tmpDepInfo;
-		nameList.push_back(mm);
-		free(mm);
-		e = e->iNextInArea;
-		count++;
-	}
-	e = iFirstPagedCode;
-	count = 0;
-	while(e)
-	{
-		TRomNode* rn = e->iRomNode;
-		TRomFile* rf = rn->iRomFile;
-		TInt j;
-		TStringList depFiles;
-		for(j=0; j < rf->iNumDeps; ++j)
-		{
-			TRomFile* f=rf->iDeps[j];
-			TRomBuilderEntry* start = iFiles;
-			while(start && start->iRomNode->iRomFile != f)
-				start = start->iNextInArea;
-			if(start && (start->iRomNode->iRomFile == f))
-			{
-				TRomNode* target = start->iRomNode;
-				TInt l = target->FullNameLength();
-				char* fname = (char *) malloc(l+1);
-				target->GetFullName(fname);
-				if(myDepInfoList.find(fname) != myDepInfoList.end())
-				{
-					depFiles.push_back(fname);
-					myDepInfoList[fname].beenDepended = ETrue;
-				}
-				free(fname);
-			}
-		}
-		if(depFiles.size() > 0)
-		{
-			myDepInfoList[nameList[count]].depFilesList=depFiles;
-			myDepInfoList[nameList[count]].dependOthers = ETrue;
-		}
-		count++;
-		e=e->iNextInArea;
-	}
-	ofstream os;
-	string filename(gDepInfoFile, strlen(gDepInfoFile) - 3);
-	filename = filename + "dot";
-	os.open(filename.c_str());
-	os << "digraph ROM {\n";
-	os << "rankdir = LR;\n";
-	os << "fontsize = 10;\n";
-	os << "fontname = \"Courier New\";\n";
-	os << "label = \"ROM DEPENDENCE GRAPH DOT FILE\";\n";
-	os << "node[shape = plaintext];\n";
-	os << "dependence[label=<<FONT FACE=\"Courier new\" POINT-SIZE=\"10pt\">\n";
-	os << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">\n";
-	//for(infoIt = myDepInfoList.begin(); infoIt != myDepInfoList.end(); infoIt++)
-	for(strIt = nameList.begin(); strIt != nameList.end(); strIt++)
-	{
-		string tmp = *strIt;
-		string::iterator charIt;
-		for(charIt=tmp.begin(); charIt != tmp.end(); charIt++)
-		{
-			if(*charIt == '\\')
-				*charIt = '/';
-		}
-		if(myDepInfoList[*strIt].beenDepended && myDepInfoList[*strIt].dependOthers)
-		{
-			os << "\t<TR><TD PORT=\"" << myDepInfoList[*strIt].portName << "\" ALIGN=\"LEFT\" BGCOLOR=\"yellow\">\n";
-			os << "\t<FONT COLOR=\"red\">" << tmp << "</FONT>\n";
-			os << "\t</TD></TR>\n";
-		}
-		else if(myDepInfoList[*strIt].beenDepended)
-		{
-			os << "\t<TR><TD PORT=\"" << myDepInfoList[*strIt].portName << "\" ALIGN=\"LEFT\" BGCOLOR=\"gray\">\n";
-			os << "\t<FONT COLOR=\"red\">" << tmp << "</FONT>\n";
-			os << "\t</TD></TR>\n";
-		}
-		else if(myDepInfoList[*strIt].dependOthers)
-		{
-			os << "\t<TR><TD PORT=\"" << myDepInfoList[*strIt].portName << "\" ALIGN=\"LEFT\" BGCOLOR=\"cyan\">\n";
-			os << "\t<FONT COLOR=\"blue\">" << tmp << "</FONT>\n";
-			os << "\t</TD></TR>\n";
-		}
-		else
-		{
-			os << "\t<TR><TD PORT=\"" << myDepInfoList[*strIt].portName << "\" ALIGN=\"LEFT\">";
-			os << tmp;
-			os << "</TD></TR>\n";
-		}
-	}
-	os << "</TABLE>\n";
-	os << "</FONT>>]\n";
-	TBool lastEdge = ETrue;
-	TBool first = ETrue;
-	for(infoIt = myDepInfoList.begin(); infoIt != myDepInfoList.end(); infoIt++)
-	{
-		if(!infoIt->second.dependOthers)
-		{
-			continue;
-		}
-		for(strIt = infoIt->second.depFilesList.begin(); strIt != infoIt->second.depFilesList.end(); strIt++)
-		{
-			TBool tmpEdge = ETrue;
-			if(infoIt->second.index < myDepInfoList[*strIt].index)
-			{	
-				tmpEdge = EFalse;
-			}
-			if(first)
-			{
-				lastEdge = tmpEdge;
-				first = EFalse;
-				if(lastEdge)
-				{
-					os << "edge[color=forestgreen];\n";
-				}
-				else
-				{
-					os << "edge[color=red];\n";
-				}
-			}
-			else
-			{
-				if(lastEdge != tmpEdge)
-				{
-					lastEdge = tmpEdge;
-					if(lastEdge)
-					{
-						os << "edge[color=forestgreen];\n";
-					}
-					else
-					{
-						os << "edge[color=red];\n";
-					}
-				}
-			}
-			os << "dependence: " << infoIt->second.portName << " -> dependence: " << myDepInfoList[*strIt].portName << ";\n";
-		}
-	}
-	os << "}\n";
-	os.close();
-	filename = filename.substr(0, filename.size()-4);
-	filename = filename + ".backwarddep.dot";
-	os.open(filename.c_str());
-	os << "digraph ROM {\n";
-	os << "rankdir = LR;\n";
-	os << "fontsize = 10;\n";
-	os << "fontname = \"Courier New\";\n";
-	os << "label = \"ROM FORWARD DEPENDENCE GRAPH DOT FILE\";\n";
-	os << "node[shape = plaintext];\n";
-	os << "dependence[label=<<FONT FACE=\"Courier new\" POINT-SIZE=\"10pt\">\n";
-	os << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">\n";
-	//for(infoIt = myDepInfoList.begin(); infoIt != myDepInfoList.end(); infoIt++)
-	for(strIt = nameList.begin(); strIt != nameList.end(); strIt++)
-	{
-		string tmp = *strIt;
-		string::iterator charIt;
-		for(charIt=tmp.begin(); charIt != tmp.end(); charIt++)
-		{
-			if(*charIt == '\\')
-				*charIt = '/';
-		}
-		if(myDepInfoList[*strIt].beenDepended && myDepInfoList[*strIt].dependOthers)
-		{
-			os << "\t<TR><TD PORT=\"" << myDepInfoList[*strIt].portName << "\" ALIGN=\"LEFT\" BGCOLOR=\"yellow\">\n";
-			os << "\t<FONT COLOR=\"red\">" << tmp << "</FONT>\n";
-			os << "\t</TD></TR>\n";
-		}
-		else if(myDepInfoList[*strIt].beenDepended)
-		{
-			os << "\t<TR><TD PORT=\"" << myDepInfoList[*strIt].portName << "\" ALIGN=\"LEFT\" BGCOLOR=\"gray\">\n";
-			os << "\t<FONT COLOR=\"red\">" << tmp << "</FONT>\n";
-			os << "\t</TD></TR>\n";
-		}
-		else if(myDepInfoList[*strIt].dependOthers)
-		{
-			os << "\t<TR><TD PORT=\"" << myDepInfoList[*strIt].portName << "\" ALIGN=\"LEFT\" BGCOLOR=\"cyan\">\n";
-			os << "\t<FONT COLOR=\"blue\">" << tmp << "</FONT>\n";
-			os << "\t</TD></TR>\n";
-		}
-		else
-		{
-			os << "\t<TR><TD PORT=\"" << myDepInfoList[*strIt].portName << "\" ALIGN=\"LEFT\">";
-			os << tmp;
-			os << "</TD></TR>\n";
-		}
-	}
-	os << "</TABLE>\n";
-	os << "</FONT>>]\n";
-	os << "edge[color=red];\n";
-	for(infoIt = myDepInfoList.begin(); infoIt != myDepInfoList.end(); infoIt++)
-	{
-		if(!infoIt->second.dependOthers)
-		{
-			continue;
-		}
-		for(strIt = infoIt->second.depFilesList.begin(); strIt != infoIt->second.depFilesList.end(); strIt++)
-		{
-			if(infoIt->second.index < myDepInfoList[*strIt].index)
-			{	
-				os << "dependence: " << infoIt->second.portName << " -> dependence: " << myDepInfoList[*strIt].portName << ";\n";
-			}
-		}
-	}
-	os << "}\n";
-	os.close();
-}
-
+/*
+* 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: 
+* Area-related classes implementation
+*
+*/
+
+
+#include "r_areaset.h"
+#include "r_global.h"
+#include "r_rom.h"
+
+extern TBool gGenDepGraph;
+extern string gDepInfoFile;
+
+using namespace std;
+
+////////////////////////////////////////////////////////////////////////
+
+Area::Area(const char* aName, TLinAddr aDestBaseAddr, TUint aMaxSize, Area* aNext)
+: iFirstPagedCode(0),
+iName(0),
+iDestBaseAddr(aDestBaseAddr),
+iSrcBaseAddr(0),
+iSrcLimitAddr(0),
+iMaxSize(aMaxSize),
+iIsDefault(strcmp(aName, AreaSet::KDefaultAreaName) == 0),
+iFiles(0),
+iNextFilePtrPtr(&iFiles),
+iNextArea(aNext)	   
+{
+	size_t len = strlen(aName) + 1;
+	iName = new char[len];
+	memcpy(iName,aName,len);
+
+}
+
+
+Area::~Area() {
+	ReleaseAllFiles();
+	if(iName)
+		delete []iName;
+}
+
+
+/**
+Increase the size of the area.
+
+The reallocation must not exceed the area maximum size.
+
+@param aSrcLimitAddr New source top address
+
+@param aOverflow Number of overflow bytes if failure.
+
+@return success indication
+*/
+
+TBool Area::ExtendSrcLimitAddr(TLinAddr aSrcLimitAddr, TUint& aOverflow) {
+	// must have been set before
+	assert(iSrcBaseAddr != 0);
+	// can only allocate more
+	assert(aSrcLimitAddr > iSrcBaseAddr);
+
+	if (aSrcLimitAddr-iSrcBaseAddr > iMaxSize) {
+		aOverflow = aSrcLimitAddr-iSrcBaseAddr-iMaxSize;
+		return EFalse;
+	}
+
+	iSrcLimitAddr = aSrcLimitAddr;
+	return ETrue;
+}
+
+
+/**
+Add a file at end of the list of files contained in this area.
+
+@param aFile File to add.  Must be allocated on the heap.  Ownership
+is transfered from the caller to the callee.
+*/
+
+void Area::AddFile(TRomBuilderEntry* aFile) {
+	assert(aFile != 0);
+
+	*iNextFilePtrPtr = aFile; 
+	iNextFilePtrPtr = &(aFile->iNextInArea);
+}
+
+
+void Area::ReleaseAllFiles() {
+	for (TRomBuilderEntry *next = 0, *current = iFiles;
+		current != 0;
+		current = next) {
+		next = current->iNextInArea; 
+		delete current;
+	}
+
+	iFiles = 0;
+	iNextFilePtrPtr = &iFiles;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void FilesInAreaIterator::GoToNext() {
+	assert(iCurrentFile!=0);
+	iCurrentFile = iCurrentFile->iNextInArea;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+const char AreaSet::KDefaultAreaName[] = "DEFAULT AREA";
+
+AreaSet::AreaSet()
+: iNonDefaultAreas(0),
+iDefaultArea(0),
+iAreaCount(0) {
+}
+
+
+AreaSet::~AreaSet() {
+	ReleaseAllAreas();
+}
+
+
+inline TBool IsInRange(TLinAddr aAddr, TLinAddr aDestBaseAddr, TLinAddr aEndAddr) {
+	return aDestBaseAddr <= aAddr && aAddr <= aEndAddr;
+}
+
+
+/**
+Add a new area.
+
+Areas must have unique name, not overlap one another and not overflow
+the 32-bit address range.  
+
+@param aOverlappingArea On return ptr to name of overlapping area if
+any, 0 otherwise.
+
+@return EAdded if success, an error code otherwise.  
+*/
+
+AreaSet::TAddResult AreaSet::AddArea(const char* aNewName,
+									 TLinAddr aNewDestBaseAddr,
+									 TUint aNewMaxSize,
+									 const char*& aOverlappingArea) {
+	assert(aNewName != 0 && strlen(aNewName) > 0);
+	assert(aNewMaxSize > 0);
+
+	aOverlappingArea = 0;
+
+	//
+	// Checking new area validity
+	//
+
+	if (aNewDestBaseAddr+aNewMaxSize <= aNewDestBaseAddr)
+		return EOverflow;
+
+	TLinAddr newEndAddr = aNewDestBaseAddr+aNewMaxSize-1;
+
+	// iterate non default areas first, then the default one if any
+	Area* area=iNonDefaultAreas; 
+	while (area != 0) {
+		if (strcmp(area->Name(), aNewName) == 0)
+			return EDuplicateName;
+
+		TLinAddr curDestBaseAddr = area->DestBaseAddr();
+		TLinAddr curEndAddr = area->DestBaseAddr()+area->MaxSize()-1;
+
+		if (IsInRange(newEndAddr, curDestBaseAddr, curEndAddr) ||
+			IsInRange(aNewDestBaseAddr, curDestBaseAddr, curEndAddr) ||
+			IsInRange(curDestBaseAddr, aNewDestBaseAddr, newEndAddr)) {
+			aOverlappingArea = area->Name();
+			return EOverlap;
+		}
+
+		if (area->iNextArea == 0 && area != iDefaultArea)
+			area = iDefaultArea;
+		else
+			area = area->iNextArea;
+	}
+
+	//
+	// Adding new area
+	//
+
+	if (strcmp(KDefaultAreaName, aNewName) == 0)
+		iDefaultArea = new Area(aNewName, aNewDestBaseAddr, aNewMaxSize);
+	else
+		iNonDefaultAreas = new Area(aNewName, aNewDestBaseAddr, aNewMaxSize, iNonDefaultAreas);
+	++iAreaCount;
+
+	return EAdded;
+}
+
+
+/**
+Remove every area added to the set.
+
+As a side-effect every file added to the areas is deleted.
+*/
+
+void AreaSet::ReleaseAllAreas() {
+	for (Area *next = 0, *current = iNonDefaultAreas; current != 0; current = next) {
+		next = current->iNextArea;
+		delete current;
+	}
+
+	iNonDefaultAreas = 0;
+	if(iDefaultArea){
+		delete iDefaultArea;
+		iDefaultArea = 0;
+	}
+}
+
+
+/**
+Find an area from its name.
+
+@return A pointer to the area or 0 if the name is unknown.  The
+returned pointer becomes invalid when "this" is destructed.
+*/
+
+Area* AreaSet::FindByName(const char* aName) const {
+	assert(aName != 0 && strlen(aName) > 0);
+
+	if (iDefaultArea && strcmp(iDefaultArea->Name(), aName) == 0)
+		return iDefaultArea;
+
+	for (Area* area=iNonDefaultAreas; area != 0; area = area->iNextArea) {
+		if (strcmp(area->Name(), aName) == 0)
+			return area;
+	}
+
+	return 0;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+
+void NonDefaultAreasIterator::GoToNext() {
+	assert(iCurrentArea!=0);
+	iCurrentArea = iCurrentArea->iNextArea;
+}
+
+TInt Area::SortFilesForPagedRom() {
+	Print(ELog,"Sorting files to paged/unpaged.\n");
+	TRomBuilderEntry* extention[2] = {0,0};
+	TRomBuilderEntry* unpaged[2] = {0,0};
+	TRomBuilderEntry* normal[2] = {0,0};
+	TRomBuilderEntry* current = iFiles;
+	while(current) {
+		TRomBuilderEntry** list;
+		if((current->iRomImageFlags & (KRomImageFlagPrimary|KRomImageFlagVariant|KRomImageFlagExtension|KRomImageFlagDevice)) ||
+			current->HCRDataFile())
+			list = extention;
+		else if(current->iRomImageFlags&(KRomImageFlagCodeUnpaged))
+			list = unpaged;
+		else if(current->iResource && (current->iOverrideFlags&KOverrideCodeUnpaged) && gPagedRom)
+			list = unpaged;
+		else
+			list = normal;
+
+		if(list!=normal) {
+			Print(ELog, "Unpaged file %s\n",current->iRomNode->BareName());
+		}
+
+		if(!list[0])
+			list[0] = current;
+		else
+			list[1]->iNextInArea = current;
+		list[1] = current;
+
+		current = current->iNext;
+	}
+
+	if(extention[1]) {
+		if(unpaged[0]) {
+			extention[1]->iNextInArea = unpaged[0];
+			unpaged[1]->iNextInArea = normal[0];
+		}
+		else
+			extention[1]->iNextInArea = normal[0];
+
+		if (normal[1])
+			normal[1]->iNextInArea = 0;
+
+		iFiles = extention[0];
+	}
+	else{
+		Print(EError,"No primary files.\n");
+		return KErrGeneral;
+	}
+
+	iFirstPagedCode = normal[0];
+	Print(ELog,"\n");
+	if(gGenDepGraph)
+		WriteDependenceGraph();
+	return KErrNone;
+}
+
+
+void Area::WriteDependenceGraph() {
+	TDepInfoList::iterator infoIt;
+	TStringList::iterator strIt;
+	TDepInfoList myDepInfoList;
+	TRomBuilderEntry* e = iFirstPagedCode;
+	char buffer[255];
+	TInt count = 0;
+	TStringList nameList;
+	while(e) {
+		DepInfo tmpDepInfo;
+		TRomNode* rn = e->iRomNode;
+		TInt ll = rn->FullNameLength();
+		char* mm = new char[ll+1];
+		rn->GetFullName(mm);
+		sprintf(buffer, "f%d", count);
+		tmpDepInfo.portName = buffer;
+		tmpDepInfo.index = count;
+		myDepInfoList[mm] = tmpDepInfo;
+		nameList.push_back(mm);
+		delete []mm;
+		e = e->iNextInArea;
+		count++;
+	}
+	e = iFirstPagedCode;
+	count = 0;
+	while(e) {
+		TRomNode* rn = e->iRomNode;
+		TRomFile* rf = rn->iRomFile;
+		TInt j;
+		TStringList depFiles;
+		for(j=0; j < rf->iNumDeps; ++j) {
+			TRomFile* f=rf->iDeps[j];
+			TRomBuilderEntry* start = iFiles;
+			while(start && start->iRomNode->iRomFile != f)
+				start = start->iNextInArea;
+			if(start && (start->iRomNode->iRomFile == f)) {
+				TRomNode* target = start->iRomNode;
+				TInt l = target->FullNameLength();
+				char* fname = new char[l+1];
+				target->GetFullName(fname);
+				if(myDepInfoList.find(fname) != myDepInfoList.end()) {
+					depFiles.push_back(fname);
+					myDepInfoList[fname].beenDepended = ETrue;
+				}
+				delete []fname;
+			}
+		}
+		if(depFiles.size() > 0) {
+			myDepInfoList[nameList[count]].depFilesList=depFiles;
+			myDepInfoList[nameList[count]].dependOthers = ETrue;
+		}
+		count++;
+		e=e->iNextInArea;
+	}
+	ofstream os;
+	string filename(gDepInfoFile.c_str(), gDepInfoFile.length() - 3);
+	filename = filename + "dot";
+	os.open(filename.c_str());
+	os << "digraph ROM {\n";
+	os << "rankdir = LR;\n";
+	os << "fontsize = 10;\n";
+	os << "fontname = \"Courier New\";\n";
+	os << "label = \"ROM DEPENDENCE GRAPH DOT FILE\";\n";
+	os << "node[shape = plaintext];\n";
+	os << "dependence[label=<<FONT FACE=\"Courier new\" POINT-SIZE=\"10pt\">\n";
+	os << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">\n";
+	//for(infoIt = myDepInfoList.begin(); infoIt != myDepInfoList.end(); infoIt++)
+	for(strIt = nameList.begin(); strIt != nameList.end(); strIt++) {
+		string tmp = *strIt;
+		string::iterator charIt;
+		for(charIt=tmp.begin(); charIt != tmp.end(); charIt++) {
+			if(*charIt == '\\')
+				*charIt = '/';
+		}
+		if(myDepInfoList[*strIt].beenDepended && myDepInfoList[*strIt].dependOthers) {
+			os << "\t<TR><TD PORT=\"" << myDepInfoList[*strIt].portName << "\" ALIGN=\"LEFT\" BGCOLOR=\"yellow\">\n";
+			os << "\t<FONT COLOR=\"red\">" << tmp << "</FONT>\n";
+			os << "\t</TD></TR>\n";
+		}
+		else if(myDepInfoList[*strIt].beenDepended) {
+			os << "\t<TR><TD PORT=\"" << myDepInfoList[*strIt].portName << "\" ALIGN=\"LEFT\" BGCOLOR=\"gray\">\n";
+			os << "\t<FONT COLOR=\"red\">" << tmp << "</FONT>\n";
+			os << "\t</TD></TR>\n";
+		}
+		else if(myDepInfoList[*strIt].dependOthers) {
+			os << "\t<TR><TD PORT=\"" << myDepInfoList[*strIt].portName << "\" ALIGN=\"LEFT\" BGCOLOR=\"cyan\">\n";
+			os << "\t<FONT COLOR=\"blue\">" << tmp << "</FONT>\n";
+			os << "\t</TD></TR>\n";
+		}
+		else {
+			os << "\t<TR><TD PORT=\"" << myDepInfoList[*strIt].portName << "\" ALIGN=\"LEFT\">";
+			os << tmp;
+			os << "</TD></TR>\n";
+		}
+	}
+	os << "</TABLE>\n";
+	os << "</FONT>>]\n";
+	TBool lastEdge = ETrue;
+	TBool first = ETrue;
+	for(infoIt = myDepInfoList.begin(); infoIt != myDepInfoList.end(); infoIt++) {
+		if(!infoIt->second.dependOthers) {
+			continue;
+		}
+		for(strIt = infoIt->second.depFilesList.begin(); strIt != infoIt->second.depFilesList.end(); strIt++) {
+			TBool tmpEdge = ETrue;
+			if(infoIt->second.index < myDepInfoList[*strIt].index)
+			{	
+				tmpEdge = EFalse;
+			}
+			if(first) {
+				lastEdge = tmpEdge;
+				first = EFalse;
+				if(lastEdge) {
+					os << "edge[color=forestgreen];\n";
+				}
+				else {
+					os << "edge[color=red];\n";
+				}
+			}
+			else {
+				if(lastEdge != tmpEdge) {
+					lastEdge = tmpEdge;
+					if(lastEdge) {
+						os << "edge[color=forestgreen];\n";
+					}
+					else {
+						os << "edge[color=red];\n";
+					}
+				}
+			}
+			os << "dependence: " << infoIt->second.portName << " -> dependence: " << myDepInfoList[*strIt].portName << ";\n";
+		}
+	}
+	os << "}\n";
+	os.close();
+	filename = filename.substr(0, filename.size()-4);
+	filename = filename + ".backwarddep.dot";
+	os.open(filename.c_str());
+	os << "digraph ROM {\n";
+	os << "rankdir = LR;\n";
+	os << "fontsize = 10;\n";
+	os << "fontname = \"Courier New\";\n";
+	os << "label = \"ROM FORWARD DEPENDENCE GRAPH DOT FILE\";\n";
+	os << "node[shape = plaintext];\n";
+	os << "dependence[label=<<FONT FACE=\"Courier new\" POINT-SIZE=\"10pt\">\n";
+	os << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">\n";
+	//for(infoIt = myDepInfoList.begin(); infoIt != myDepInfoList.end(); infoIt++)
+	for(strIt = nameList.begin(); strIt != nameList.end(); strIt++) {
+		string tmp = *strIt;
+		string::iterator charIt;
+		for(charIt=tmp.begin(); charIt != tmp.end(); charIt++) {
+			if(*charIt == '\\')
+				*charIt = '/';
+		}
+		if(myDepInfoList[*strIt].beenDepended && myDepInfoList[*strIt].dependOthers) {
+			os << "\t<TR><TD PORT=\"" << myDepInfoList[*strIt].portName << "\" ALIGN=\"LEFT\" BGCOLOR=\"yellow\">\n";
+			os << "\t<FONT COLOR=\"red\">" << tmp << "</FONT>\n";
+			os << "\t</TD></TR>\n";
+		}
+		else if(myDepInfoList[*strIt].beenDepended) {
+			os << "\t<TR><TD PORT=\"" << myDepInfoList[*strIt].portName << "\" ALIGN=\"LEFT\" BGCOLOR=\"gray\">\n";
+			os << "\t<FONT COLOR=\"red\">" << tmp << "</FONT>\n";
+			os << "\t</TD></TR>\n";
+		}
+		else if(myDepInfoList[*strIt].dependOthers) {
+			os << "\t<TR><TD PORT=\"" << myDepInfoList[*strIt].portName << "\" ALIGN=\"LEFT\" BGCOLOR=\"cyan\">\n";
+			os << "\t<FONT COLOR=\"blue\">" << tmp << "</FONT>\n";
+			os << "\t</TD></TR>\n";
+		}
+		else {
+			os << "\t<TR><TD PORT=\"" << myDepInfoList[*strIt].portName << "\" ALIGN=\"LEFT\">";
+			os << tmp;
+			os << "</TD></TR>\n";
+		}
+	}
+	os << "</TABLE>\n";
+	os << "</FONT>>]\n";
+	os << "edge[color=red];\n";
+	for(infoIt = myDepInfoList.begin(); infoIt != myDepInfoList.end(); infoIt++) {
+		if(!infoIt->second.dependOthers) {
+			continue;
+		}
+		for(strIt = infoIt->second.depFilesList.begin(); strIt != infoIt->second.depFilesList.end(); strIt++) {
+			if(infoIt->second.index < myDepInfoList[*strIt].index)
+			{	
+				os << "dependence: " << infoIt->second.portName << " -> dependence: " << myDepInfoList[*strIt].portName << ";\n";
+			}
+		}
+	}
+	os << "}\n";
+	os.close();
+}
+