kernel/eka/drivers/debug/rmdebug/d_list_manager.cpp
changeset 259 57b9594f5772
parent 247 d8d70de2bd36
child 260 a1a318fd91af
child 266 0008ccd16016
--- a/kernel/eka/drivers/debug/rmdebug/d_list_manager.cpp	Wed Aug 18 11:08:29 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1007 +0,0 @@
-// Copyright (c) 2007-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:
-// Provides a class to manage the generation of lists
-// 
-//
-
-#include "d_list_manager.h"
-#include "d_process_tracker.h"
-#include "debug_utils.h"
-#include "plat_priv.h"
-#include "debug_logging.h"
-#include <arm.h>
-
-// make accessing DThread's MState more intuitive
-#define iMState iWaitLink.iSpare1
-// make accessing NThread's NState more intuitive
-#define iNState iSpare3
-
-//constants to match against a rom entry's attributes,
-//these are defined in the file server (can't be included kernel side)
-//and in the ROM tools (also inaccessible) so redefined here
-const TUint KEntryAttXIP=0x0080;
-const TUint KEntryAttDir=0x0010;
-
-using namespace Debug;
-
-/**
-  Get thread listing for the specified thread, if the thread data will not fit
-  in the buffer then an error is returned.
-
-  @param aBuffer buffer to put data in
-  @param aDataSize on return will contain size of data
-  @param aTargetThreadId thread ID to return listing for
-
-  @return KErrNone on success,
-  KErrTooBig if data won't fit in aBuffer
-  or one of the other system wide error codes on failure
-  */
-TInt TListManager::GetThreadListForThread(TDes8& aBuffer, TUint32& aDataSize, const TUint64 aTargetThreadId) const
-	{
-	LOG_MSG("TListManager::GetThreadListForThread()");
-
-	// open a handle to check whether the thread actually exists
-	DThread* thread = DebugUtils::OpenThreadHandle(aTargetThreadId);
-	if(!thread)
-		{
-		return KErrArgument;
-		}
-	DProcess* process = thread->iOwningProcess;
-	if(!process)
-		{
-		return KErrArgument;
-		}
-	TUint64 processId = process->iId;
-	thread->Close(NULL);
-
-	//request a process specific list
-	return GetThreadListForProcess(aBuffer, aDataSize, processId);
-	}
-
-TInt TListManager::GetThreadListForProcess(TDes8& aBuffer, TUint32& aDataSize, const TUint64 aTargetProcessId) const
-	{
-	LOG_MSG("TListManager::GetThreadListForProcess()");
-
-	// open a handle to check whether the process actually exists
-	DProcess* process = DebugUtils::OpenProcessHandle(aTargetProcessId);
-	if(!process)
-		{
-		return KErrArgument;
-		}
-	process->Close(NULL);
-
-	//request a process specific list
-	return GetThreadList(aBuffer, aDataSize, EFalse, aTargetProcessId);
-	}
-
-/**
-  Get global thread listing
-
-  @param aBuffer buffer to put data in
-  @param aDataSize on return will contain size of data
-
-  @return KErrNone on success,
-  KErrTooBig if data won't fit in aBuffer
-  or one of the other system wide error codes on failure
-  */
-TInt TListManager::GetGlobalThreadList(TDes8& aBuffer, TUint32& aDataSize) const
-	{
-	LOG_MSG("TListManager::GetGlobalThreadList()");
-
-	//request a global list
-	return GetThreadList(aBuffer, aDataSize, ETrue, 0);
-	}
-
-/**
-  Get thread listing, if the thread data will not fit
-  in the buffer then an error is returned.
-
-  @param aBuffer buffer to put data in
-  @param aDataSize on return will contain size of data
-  @param aGlobal whether or not the listing should be global or thread specific
-  @param aTargetProcessId process ID to return listing for, relevant only if aGlobal == ETrue
-
-  @return KErrNone on success,
-  KErrTooBig if data won't fit in aBuffer
-  or one of the other system wide error codes on failure
-  */
-TInt TListManager::GetThreadList(TDes8& aBuffer, TUint32& aDataSize, TBool aGlobal, const TUint64 aTargetProcessId) const
-	{
-
-	LOG_MSG("TListManager::GetThreadList\n");
-
-	//have to read the threads in a critical section
-	NKern::ThreadEnterCS();
-
-	//get a pointer to the kernel's thread list
-	DObjectCon *threads = Kern::Containers()[EThread];
-
-	//if can't get container then exit
-	if(threads == NULL)
-		{
-		NKern::ThreadLeaveCS();
-
-		return KErrGeneral;
-		}
-
-	//stop the thread list from changing while we are processing them
-	threads->Wait();
-
-	aDataSize = 0;
-	aBuffer.SetLength(0);
-	//iterate through the threads adding them to the buffer
-	for(TInt i=0; i<threads->Count(); i++)
-		{
-		DThread* thread = (DThread*)(*threads)[i];
-
-		//skip this thread pointer is the thread is NULL
-		if(thread)
-			{
-			NThread& nThread = thread->iNThread;
-
-			// if the thread is marked as being dead then don't return information about it in the listing
-#ifndef __SMP__
-			if((NThread::EDead != nThread.iNState) && (DThread::EDead != thread->iMState))
-#else
- 			if((!nThread.IsDead()) && (DThread::EDead != thread->iMState))
-#endif
-				{
-				if( aGlobal || (aTargetProcessId == (TUint64)thread->iOwningProcess->iId))
-					{
-					//store the data in the buffer
-					AppendThreadData(aBuffer, aDataSize, thread);
-					}
-				}
-			}
-		}
-
-	//leave critical section
-	threads->Signal();
-	NKern::ThreadLeaveCS();
-
-	//return indication of whether the kernel's data was too big
-	return (aDataSize > aBuffer.Length()) ? KErrTooBig : KErrNone;
-	}
-
-/**
-  Helper function for writing thread data into a buffer
-
-  @pre call in a critical section
-  @pre call only on threads which have NThread state not equal to NThread::EDead
-
-  @param aBuffer buffer to put data in
-  @param aDataSize on return will contain size of data
-  @param aThread thread object to include information about
-
-  @return KErrNone on success, or one of the other system wide error codes
-*/
-void TListManager::AppendThreadData(TDes8& aBuffer, TUint32& aDataSize, DThread* aThread) const
-	{
-	//get aThread's name
-	TFileName fileName;
-	aThread->FullName(fileName);
-	TUint16 nameLength = fileName.Length();
-
-	//increase aDataSize by the size of this entry
-	aDataSize = Align4(aDataSize + (2*nameLength) + sizeof(TThreadListEntry) - sizeof(TUint16));
-	//if the data would not cause overflow then add it to the buffer
-	if(aDataSize <= aBuffer.MaxLength())
-		{
-		//Create a TThreadListEntry which references the buffer.
-		TThreadListEntry& entry = *(TThreadListEntry*)(aBuffer.Ptr()+aBuffer.Length());
-		//add data to entry
-		entry.iProcessId = (TUint64)aThread->iOwningProcess->iId;
-		entry.iThreadId = (TUint64)aThread->iId;
-		entry.iSupervisorStackBase = (TUint32)aThread->iSupervisorStack;
-		entry.iSupervisorStackBaseValid = ETrue;
-		entry.iSupervisorStackSize = aThread->iSupervisorStackSize;
-		entry.iSupervisorStackSizeValid = ETrue;
-		entry.iNameLength = nameLength;
-
-		//only ask for the supervisor stack pointer if aThread is suspended
-		entry.iSupervisorStackPtrValid = EInValid;
-		entry.iSupervisorStackPtr = 0;
-		if(TheDProcessTracker.CheckSuspended(aThread))
-			{
-			NThread& nThread = aThread->iNThread;
-
-			TArmRegSet regSet;
-			TUint32 flags;
-			NKern::ThreadGetSystemContext(&nThread, &regSet, flags);
-			entry.iSupervisorStackPtr = (TUint32)regSet.iR13;
-			//need to check that the stack pointer flag is valid
-			if(flags & (1<<EArmSp))
-				{
-				entry.iSupervisorStackPtrValid = EValid;
-				}
-			}
-
-		//copy name data into the buffer
-		TUint16* ptr = &(entry.iName[0]);
-		const TUint8* ptr8 = fileName.Ptr();
-		const TUint8* ptr8End = ptr8 + nameLength;
-		while(ptr8 < ptr8End)
-			{
-			*ptr++ = (TUint16)*ptr8++;
-			}
- 
-		aBuffer.SetLength(aDataSize);
-		}
-	}
-
-/**
-  Get global process listing
-
-  @param aBuffer buffer to put data in
-  @param aDataSize on return will contain size of data
-
-  @return KErrNone on success,
-  KErrTooBig if data won't fit in aBuffer
-  or one of the other system wide error codes on failure
-  */
-TInt TListManager::GetProcessList(TDes8& aBuffer, TUint32& aDataSize) const
-	{
-	LOG_MSG("TListManager::GetProcessList()");
-
-	//get a pointer to the kernel's process list
-	DObjectCon* processes = Kern::Containers()[EProcess];
-
-	if(processes == NULL)
-		{
-		//if can't get container then something is seriously wrong
-		return KErrNotFound;
-		}
-
-	//have to read the processes in a critical section
-	NKern::ThreadEnterCS();
-	processes->Wait();
-
-	aDataSize = 0;
-	//iterate through the processes adding them to the buffer
-	for(TInt i=0; i<processes->Count(); i++)
-		{
-		DProcess* process = (DProcess*)(*processes)[i];
-		if(process)
-			{
-			//get process's file name length
-			DCodeSeg* codeSeg = process->iCodeSeg;
-			TUint16 fileNameLength = (codeSeg) ? (*codeSeg->iFileName).Length() : 0;
-
-			//get process's dynamic name length and name
-			TFullName fullName;
-			process->FullName(fullName);
-			TUint16 dynamicNameLength = fullName.Length();
-
-			//increase aDataSize to reflect size of entry
-			aDataSize = Align4(aDataSize + (2*fileNameLength) + (2*dynamicNameLength) + sizeof(TProcessListEntry) - sizeof(TUint16));
-			//if the data would not cause overflow then add it to the buffer
-			if(aDataSize <= aBuffer.MaxLength())
-				{
-				//Create a TProcessListEntry which references the buffer.
-				TProcessListEntry& entry = *(TProcessListEntry*)(aBuffer.Ptr() + aBuffer.Length());
-
-				//set values
-				entry.iProcessId = (TUint64)process->iId;
-				entry.iFileNameLength = fileNameLength;
-				entry.iDynamicNameLength = dynamicNameLength;
-				entry.iUid3 = process->iUids.iUid[2].iUid;
-
-				if(codeSeg)
-					{
-					//create TPtr to where the file name should be written
-					TPtr name = TPtr((TUint8*)&(entry.iNames[0]), fileNameLength*2, fileNameLength*2);
-					//copy the file name
-					TInt err = CopyAndExpandDes(*codeSeg->iFileName, name);
-					if(err != KErrNone)
-						{
-						processes->Signal();
-						NKern::ThreadLeaveCS();
-						return KErrGeneral;
-						}
-					}
-
-				//create TPtr to where the dynamic name should be written
-				TPtr name = TPtr((TUint8*)(&(entry.iNames[0]) + fileNameLength), dynamicNameLength*2, dynamicNameLength*2);
-				//copy the dynamic name
-				TInt err = CopyAndExpandDes(fullName, name);
-				if(err != KErrNone)
-					{
-					processes->Signal();
-					NKern::ThreadLeaveCS();
-					return KErrGeneral;
-					}
-
-				//set length same as aDataSize
-				aBuffer.SetLength(aDataSize);
-				}
-			}
-		}
-
-	//leave critical section
-	processes->Signal();
-	NKern::ThreadLeaveCS();
-
-	//return indication of whether the kernel's data was too big
-	return (aDataSize > aBuffer.Length()) ? KErrTooBig : KErrNone;
-	}
-
-/**
-  Copy the descriptor aSrc to aDest and converting each byte from aSrc
-  into the two-byte equivalent. For example if aSrc contains 'XYZ' then
-  aDest will be filled with 'X\0Y\0Z\0' where \0 is the null character.
-  The length of aDest is set to twice the length of aSrc.
-
-  @param aSrc source descriptor
-  @param aDest destination descriptor to copy and expand aSrc into
-
-  @return KErrNone on success,
-  KErrArgument if the max length of aDest is less than twice the length of aSrc
-  */
-TInt TListManager::CopyAndExpandDes(const TDesC& aSrc, TDes& aDest) const
-	{
-	//check bounds
-	if(aSrc.Length() * 2 > aDest.MaxLength())
-		{
-		return KErrArgument;
-		}
-
-	//get a pointer to the start of the destination descriptor
-	TUint16* destPtr = (TUint16*)aDest.Ptr();
-
-	//get pointers to the start and end of the aSrc descriptor
-	const TUint8* srcPtr = aSrc.Ptr();
-	const TUint8* srcEnd = srcPtr + aSrc.Length();
-
-	//copy the characters from aSrc into aDest, expanding to make them 16-bit characters
-	while(srcPtr < srcEnd)
-		{
-		*destPtr = (TUint16)*srcPtr;
-		destPtr++;
-		srcPtr++;
-		}
-
-	//set aDest's length to reflect the new contents
-	aDest.SetLength(2*aSrc.Length());
-	return KErrNone;
-	}
-
-/**
-  Get global code segment listing
-
-  @param aBuffer buffer to put data in
-  @param aDataSize on return will contain size of data
-
-  @return KErrNone on success,
-  KErrTooBig if data won't fit in aBuffer,
-  or one of the other system wide error codes
-  */
-TInt TListManager::GetGlobalCodeSegList(TDes8& aBuffer, TUint32& aDataSize) const
-	{
-	LOG_MSG("TListManager::GetGlobalCodeSegList()");
-
-	// Acquire code seg lock mutex
-	NKern::ThreadEnterCS();
-	DMutex* codeMutex = Kern::CodeSegLock();
-	Kern::MutexWait(*codeMutex);
-
-	//get global code seg list
-	SDblQue* codeSegList = Kern::CodeSegList();
-
-	//create a memory info object for use in the loop
-	TModuleMemoryInfo memoryInfo;
-
-	//iterate through the list
-	aDataSize = 0;
-	for (SDblQueLink* codeSegPtr= codeSegList->First(); codeSegPtr!=(SDblQueLink*) (codeSegList); codeSegPtr=codeSegPtr->iNext)
-		{
-		DEpocCodeSeg* codeSeg = (DEpocCodeSeg*)_LOFF(codeSegPtr,DCodeSeg, iLink);
-		//the code seg shouldn't be null as we're in critical section, ignore if it is null
-		if(codeSeg)
-			{
-			//get the memory info
-			TInt err = codeSeg->GetMemoryInfo(memoryInfo, NULL);
-			if(err != KErrNone)
-				{
-				// Release the codeseglock mutex again
-				Kern::MutexSignal(*codeMutex);
-				NKern::ThreadLeaveCS();
-
-				//there's been an error so return it
-				return err;
-				}
-			//calculate data values
-			TFileName fileName(codeSeg->iFileName->Ptr());
-			TBool isXip = (TBool)(codeSeg->iXIP);
-
-			//get the code seg type, can ignore error as have already checked codeSeg is not NULL
-			TCodeSegType type = EUnknownCodeSegType;
-			err = GetCodeSegType(codeSeg, type);
-			if(err != KErrNone)
-				{
-				LOG_MSG("TListManager::GetGlobalCodeSegList() : code seg is NULL");
-				}
-
-			TUint32 uid3 = codeSeg->iUids.iUid[2].iUid;
-			//append data to buffer
-			err = AppendCodeSegData(aBuffer, aDataSize, memoryInfo, isXip, type, fileName, uid3);
-			if(err != KErrNone)
-				{
-				// Release the codeseglock mutex again
-				Kern::MutexSignal(*codeMutex);
-				NKern::ThreadLeaveCS();
-
-				return KErrGeneral;
-				}
-			}
-		}
-
-	// Release the codeseglock mutex again
-	Kern::MutexSignal(*codeMutex);
-	NKern::ThreadLeaveCS();
-
-	return (aDataSize > aBuffer.MaxLength()) ? KErrTooBig : KErrNone;
-	}
-
-/**
-  Get code segment list for a thread
-
-  @param aBuffer buffer to store data in
-  @param aDataSize size of kernel's data
-  @param thread ID to get listing for
-
-  @return KErrNone on success,
-  KErrTooBig if data won't fit in aBuffer,
-  or one of the other system wide error codes
-  */
-TInt TListManager::GetCodeSegListForThread(TDes8& aBuffer, TUint32& aDataSize, const TUint64 aTargetThreadId) const
-	{
-	LOG_MSG("TListManager::GetCodeSegListForThread()");
-
-	// open a handle to check whether the thread actually exists
-	DThread* thread = DebugUtils::OpenThreadHandle(aTargetThreadId);
-	if(!thread)
-		{
-		return KErrArgument;
-		}
-	DProcess* process = thread->iOwningProcess;
-	if(!process)
-		{
-		return KErrArgument;
-		}
-	TUint64 processId = process->iId;
-	thread->Close(NULL);
-
-	return GetCodeSegListForProcess(aBuffer, aDataSize, processId);
-	}
-/**
-  Get code segment list for a process
-
-  @param aBuffer buffer to store data in
-  @param aDataSize size of kernel's data
-  @param process ID to get listing for
-
-  @return KErrNone on success,
-  KErrTooBig if data won't fit in aBuffer,
-  or one of the other system wide error codes
-  */
-TInt TListManager::GetCodeSegListForProcess(TDes8& aBuffer, TUint32& aDataSize, const TUint64 aTargetProcessId) const
-	{
-	LOG_MSG("TListManager::GetCodeSegListForProcess()");
-
-	//get the process
-	DProcess* process = DebugUtils::OpenProcessHandle(aTargetProcessId);
-
-	if(!process)
-		{
-		return KErrArgument;
-		}
-
-	//enter thread critical section and acquire code segment mutex
-	Kern::AccessCode();
-
-	//memory info object to use in loop
-	TModuleMemoryInfo memoryInfo;
-
-	//get code seg list
-	SDblQue queue;
-	process->TraverseCodeSegs(&queue, NULL, DCodeSeg::EMarkDebug, DProcess::ETraverseFlagAdd);
-
-	//iterate through the list
-	aDataSize = 0;
-	for(SDblQueLink* codeSegPtr= queue.First(); codeSegPtr!=(SDblQueLink*) (&queue); codeSegPtr=codeSegPtr->iNext)
-		{
-		//get the code seg
-		DEpocCodeSeg* codeSeg = (DEpocCodeSeg*)_LOFF(codeSegPtr,DCodeSeg, iTempLink);
-
-		//the code seg shouldn't be null as we're in critical section, ignore if it is null
-		if(codeSeg)
-			{
-			TInt err = codeSeg->GetMemoryInfo(memoryInfo, NULL);
-			if(err != KErrNone)
-				{
-				process->Close(NULL);
-				return err;
-				}
-
-			TFileName fileName(codeSeg->iFileName->Ptr());
-			TBool isXip = (TBool)(codeSeg->iXIP);
-
-			//get the code seg type, can ignore error as have already checked codeSeg is not NULL
-			TCodeSegType type = EUnknownCodeSegType;
-			err = GetCodeSegType(codeSeg, type);
-			if(err != KErrNone)
-				{
-				LOG_MSG("TListManager::GetCodeSegListForProcess() : code seg is NULL");
-				}
-
-			TUint32 uid3 = codeSeg->iUids.iUid[2].iUid;
-			//append data to buffer
-			err = AppendCodeSegData(aBuffer, aDataSize, memoryInfo, isXip, type, fileName, uid3);
-			if(err != KErrNone)
-				{
-				process->Close(NULL);
-				return KErrGeneral;
-				}
-			}
-		}
-
-	//un mark the code segs that we've iterated over
-	DCodeSeg::EmptyQueue(queue, DCodeSeg::EMarkDebug);
-
-	//release mutex and leave CS
-	Kern::EndAccessCode();
-
-	process->Close(NULL);
-	return (aDataSize > aBuffer.MaxLength()) ? KErrTooBig : KErrNone;
-	}
-
-/**
-  Appends data to a specified buffer and puts the resulting size in aDataSize.
-  If the data won't fit then aDataSize is updated to reflect what the new length
-  would be.
-
-  @param aBuffer buffer to append data to
-  @param aDataSize will contain buffer size (or the size the buffer would be) on return
-  @param aMemoryInfo info to append to buffer
-  @param aIsXip boolean indicating whether the code segment is XIP
-  @param aFileName file name to append to buffer
-
-  @return KErrNone on success, or one of the other system wide error codes
-  */
-TInt TListManager::AppendCodeSegData(TDes8& aBuffer, TUint32& aDataSize, const TModuleMemoryInfo& aMemoryInfo, const TBool aIsXip, const TCodeSegType aCodeSegType, const TDesC8& aFileName, const TUint32 aUid3) const
-	{
-	//get some data elements to put in buffer
-	TUint16 fileNameLength = aFileName.Length();
-
-	//calculate the resultant size
-	aDataSize = Align4(aDataSize + sizeof(TCodeSegListEntry) + (2*fileNameLength) - sizeof(TUint16));
-	if(aDataSize <= aBuffer.MaxLength())
-		{
-		//Create a TCodeSegListEntry which references the buffer.
-		TCodeSegListEntry& entry = *(TCodeSegListEntry*)(aBuffer.Ptr() + aBuffer.Length());
-		entry.iCodeBase = aMemoryInfo.iCodeBase;
-		entry.iCodeSize = aMemoryInfo.iCodeSize;
-		entry.iConstDataSize = aMemoryInfo.iConstDataSize;
-		entry.iInitialisedDataBase = aMemoryInfo.iInitialisedDataBase;
-		entry.iInitialisedDataSize = aMemoryInfo.iInitialisedDataSize;
-		entry.iUninitialisedDataSize = aMemoryInfo.iUninitialisedDataSize;
-		entry.iIsXip = aIsXip;
-		entry.iCodeSegType = aCodeSegType;
-		entry.iNameLength = fileNameLength;
-		entry.iUid3 = aUid3;
-
-		//have to convert the stored name to 16 bit unicode
-		TPtr name = TPtr((TUint8*)&(entry.iName[0]), fileNameLength*2, fileNameLength*2);
-		TInt err = CopyAndExpandDes(aFileName, name);
-		if(err != KErrNone)
-			{
-			return KErrGeneral;
-			}
-
-		//increase length
-		aBuffer.SetLength(aDataSize);
-		}
-
-	return KErrNone;
-	}
-
-/**
-  Get global XIP libraries list. The ROM file system is searched for files in
-  z:\sys\bin. The files are filtered to only include library files which
-  correspond to the correct hardware variant.
-
-  In the rom, a directory is represented as a list of TRomEntrys, corresponding to
-  the files and directories in that directory. A TRomEntry corresponding to a file
-  contains a pointer to that file's location in the rom. If the TRomEntry
-  corresponds to a directory then it contains a pointer to that directory in the
-  ROM header. As such, from a pointer to the root directory of the z: drive, it is
-  possible to extract the directory contents for a particular directory (i.e. z:\sys\bin)
-  by recursively finding the subdirectories (i.e. find 'sys' in 'z:', then 'bin' in 'sys')
-  and then listing the contents of that directory.
-
-  @param aBuffer buffer to store data in
-  @param aDataSize size of kernel's data
-
-  @return KErrNone on success,
-  KErrTooBig if data won't fit in aBuffer,
-  or one of the other system wide error codes
-  */
-TInt TListManager::GetXipLibrariesList(TDes8& aBuffer, TUint32& aDataSize) const
-	{
-	LOG_MSG("TListManager::GetXipLibrariesList()");
-
-	// z:\sys\bin expressed as 16 bit unicode..
-	_LIT(KZSysBin, "z\0:\0\\\0s\0y\0s\0\\\0b\0i\0n\0\\\0");
-
-	//array to store pointers to directory entries in
-	RPointerArray<TRomEntry> entries;
-	//get the entries in KZSysBin
-	TInt err = GetDirectoryEntries(entries, KZSysBin());
-	if(KErrNone != err)
-		{
-		entries.Close();
-		return err;
-		}
-
-	aDataSize = 0;
-	for(TInt i=0; i<entries.Count(); i++)
-		{
-		//if the entry is XIP and it's not a directory then it's a candidate to add
-		if( (entries[i]->iAtt & KEntryAttXIP) && ! (entries[i]->iAtt & KEntryAttDir) )
-			{
-			//get a reference to the dll's header
-			const TRomImageHeader& header = *(const TRomImageHeader*)(entries[i]->iAddressLin);
-
-			//check that it's uid1 value corresponds to that for a library
-			if(header.iUid1 == KDynamicLibraryUidValue)
-				{
-				//get the current hardware variant
-				TSuperPage& superPage = Kern::SuperPage();
-				TUint variant = superPage.iActiveVariant;
-				TUint cpu = (variant >> 16) & 0xff;
-				TUint asic = (variant >> 24);
-
-				//check this dll is compatible with the current variant
-				if(THardwareVariant(header.iHardwareVariant).IsCompatibleWith(cpu,asic,variant))
-					{
-					const TInt fileNameLength16 = entries[i]->iNameLength;
-					const TInt fullNameLength16 = (KZSysBin().Length() / 2) + fileNameLength16;
-					aDataSize += Align4((2 * fullNameLength16) + sizeof(TXipLibraryListEntry) - sizeof(TUint16));
-
-					if(aDataSize <= aBuffer.MaxLength())
-						{
-						//Create a TXipLibraryListEntry which references the buffer.
-						TXipLibraryListEntry& libraryInfo = *(TXipLibraryListEntry*)(aBuffer.Ptr() + aBuffer.Length());
-
-						//add the data
-						libraryInfo.iCodeBase = header.iCodeAddress;
-						libraryInfo.iCodeSize = header.iTextSize;
-						libraryInfo.iConstDataSize = header.iCodeSize - header.iTextSize;
-						libraryInfo.iInitialisedDataBase = header.iDataBssLinearBase;
-						libraryInfo.iInitialisedDataSize = header.iDataSize;
-						libraryInfo.iUninitialisedDataSize = header.iBssSize;
-						libraryInfo.iNameLength = fullNameLength16;
-
-						//create a TPtr8 to contain the fully qualified name (i.e. z:\sys\bin\ prefixed)
-						TPtr8 name((TUint8*)&(libraryInfo.iName[0]), 0, 2 * fullNameLength16);
-						name.Append(KZSysBin());
-						name.Append(TPtr8((TUint8*)&(entries[i]->iName), 2 * fileNameLength16, 2 * fileNameLength16));
-
-						//increase the buffer's length to reflect the new data size
-						aBuffer.SetLength(aDataSize);
-						}
-					}
-				}
-			}
-		}
-	entries.Close();
-	return (aDataSize == aBuffer.Length()) ? KErrNone : KErrTooBig;
-	}
-
-/**
-Get the list of TRomEntry objects in the specified directory aDirectory
-
-@param aRomEntryArray array to store pointers to the TRomEntry objects in
-@param aDirectoryName directory to get contents of. The passed in string should be
-16 bit unicode and should begin with z:. Single backslashes should be used as delimiters
-rather than forward slashes and a terminating backslash is optional.
-For example: z:\sys\bin
-
-@return KErrNone on success, or one of the other system wide error codes
-*/
-TInt TListManager::GetDirectoryEntries(RPointerArray<TRomEntry>& aRomEntryArray, const TDesC& aDirectoryName) const
-	{
-	LOG_MSG("TListManager::GetDirectoryEntries()");
-
-	//definition in 16 bit unicode
-	_LIT(KForwardSlash, "/\0");
-
-	//if directory has forward slashes then exit
-	if(aDirectoryName.Find(KForwardSlash()) != KErrNotFound)
-		{
-		return KErrArgument;
-		}
-
-	//create an array to hold the folders in aDirectoryName
-	RArray<TPtr8> folders;
-
-	//split the directory up into its folders, i.e. z:\sys\bin is split into { 'z:', 'sys', 'bin' }
-	TInt err = SplitDirectoryName(aDirectoryName, folders);
-	if(KErrNone != err)
-		{
-		folders.Close();
-		return err;
-		}
-
-	if(folders.Count() == 0)
-		{
-		folders.Close();
-		//empty string passed in
-		return KErrArgument;
-		}
-
-	// z: as 16 bit unicode
-	_LIT(KZColon, "z\0:\0");
-	if(folders[0].CompareF(KZColon()) != 0)
-		{
-		//first argument must be z: otherwise not in rom
-		folders.Close();
-		return KErrArgument;
-		}
-	//remove z: from array
-	folders.Remove(0);
-	for(TInt i=0; i<folders.Count(); i++)
-		{
-		if(folders[i].Length() == 0)
-			{
-			// there were two backslashes in a row
-			folders.Close();
-			return KErrArgument;
-			}
-		}
-
-	//get a pointer to the start of the rom root directory list
-	TLinAddr romRootDirectoryList = Epoc::RomHeader().iRomRootDirectoryList;
-
-	//the first 4 bytes of the rom root directory list is a count of how many sections (rom roots) there are
-	TUint32 rootDirectoryCount = (TUint32)*(TLinAddr*)romRootDirectoryList;
-
-	//rootDirectoryPointer will be shifted through the rom root directory list and will contain pointers to the sections in the rom
-	TLinAddr rootDirectoryPointer = romRootDirectoryList;
-	for(TInt i=0; i<rootDirectoryCount; i++)
-		{
-		//the address of the section is stored in the second four bytes of the 8 byte pair reserved for each section
-		rootDirectoryPointer += 8;
-
-		//romRoot contains the address of the root of the section
-		TLinAddr romRoot = *(TLinAddr*)rootDirectoryPointer;
-
-		//append the directory entries from romRoot's z:\sys\bin subdirectory
-		TInt err = GetDirectoryEntries(aRomEntryArray, folders, romRoot);
-		if(KErrNone != err)
-			{
-			folders.Close();
-			return err;
-			}
-		}
-	folders.Close();
-	return KErrNone;
-	}
-
-/**
-  Recursively finds the subdirectories in aArray and stores references to the
-  entries in the most derived subdirectory in aRomEntryArray
-
-  @param aRomEntryArray on return will contain the entries in the directory corresponding to aArray
-  @param aArray an array containing the directory to get the entries for, i.e. { 'sys', 'bin' }
-  @param aAddress address in rom to being searching from
-
-  @param KErrNone on success, or one of the other system wide error codes
-*/
-TInt TListManager::GetDirectoryEntries(RPointerArray<TRomEntry>& aRomEntryArray, RArray<TPtr8>& aArray, TLinAddr& aAddress) const
-	{
-	LOG_MSG2("TListManager::GetDirectoryEntries() aAddress: 0x%08x", aAddress);
-
-	//find the next subdirectory and store its address in aAddress, return error if we can't find it
-	TInt err = FindDirectory(aArray[0], aAddress);
-	if(err != KErrNone)
-		{
-		return err;
-		}
-
-	//if this is the most derived sub-directory (i.e. the bin of z:\sys\bin) then get the dir contents
-	if(aArray.Count() == 1)
-		{
-		return GetDirectoryContents(aRomEntryArray, aAddress);
-		}
-	else
-		{
-		//get the next subdirectory's contents
-		aArray.Remove(0);
-		return GetDirectoryEntries(aRomEntryArray, aArray, aAddress);
-		}
-	}
-
-/**
-Return the entries of a directory in the rom
-
-@param aRomEntryArray array to store the entries in
-@param aAddress address of a directory block in the rom
-*/
-TInt TListManager::GetDirectoryContents(RPointerArray<TRomEntry>& aRomEntryArray, const TLinAddr aAddress) const
-	{
-	LOG_MSG("TListManager::GetDirectoryContents()");
-
-	TLinAddr address = aAddress;
-
-	//get the size in bytes of the block of rom to iterate over
-	const TUint32 sizeInBytes = *(TUint32*)aAddress;
-
-	//get address of first TRomEntry
-	const TLinAddr initialAddress = aAddress + sizeof(TUint32);
-
-	//get pointer to subdir count
-	address = initialAddress + sizeInBytes;
-
-	//the upper two bytes of this entry contain the number of files in this directory, and the lower two bytes
-	//contains the number of subdirectories in this directory
-	TUint32 filesAndDirectories = *(TUint32*)address;
-
-	//get number of subdirectories in this directory
-	const TUint16 subDirCount = filesAndDirectories & 0xFFFF;
-
-	//get the number of files in this dir
-	const TUint16 filesCount = filesAndDirectories >> 16;
-
-	//get total number of entries in dir
-	const TUint numDirectoryEntries = subDirCount + filesCount;
-
-	//set address to start of first entry
-	address = initialAddress;
-
-	for(TInt i=0; i<numDirectoryEntries; i++)
-		{
-		TRomEntry* romEntry = (TRomEntry*)address;
-
-		//store the entry
-		TInt err = aRomEntryArray.Append(romEntry);
-		if(KErrNone != err)
-			{
-			return err;
-			}
-
-		//length of the name of the rom entry
-		TInt nameLength = romEntry->iNameLength;
-
-		//get the size of the entry including the name
-		TUint32 romEntrySize = sizeof(TRomEntry) - sizeof(romEntry->iName) + (2 * nameLength);
-		//adjust the address to the next entry
-		address += Align4(romEntrySize);
-		}
-	return KErrNone;
-	}
-
-/**
-  Finds the subdirectory with name aDirectory in the directory at aAddress
-
-  @param aDirectory name of subdirectory to search for (i.e. 'bin')
-  @param aAddress address in rom of containing directory (i.e. address of 'sys' directory)
-
-  @param KErrNone if aDirectory could be found in aAddress, KErrNotFound if it could not be found
-  */
-TInt TListManager::FindDirectory(const TDesC& aDirectory, TLinAddr& aAddress) const
-	{
-	LOG_MSG3("TListManager::FindDirectory() aDirectory: %S, aAddress: 0x%08x", &aDirectory, aAddress);
-
-	//get the directory's contents
-	RPointerArray<TRomEntry> dirContents;
-	TInt err = GetDirectoryContents(dirContents, aAddress);
-	if(KErrNone != err)
-		{
-		dirContents.Close();
-		return err;
-		}
-	for(TInt i=0; i<dirContents.Count(); i++)
-		{
-		//create a reference to the TRomEntry in the rom to access its attributes
-		TRomEntry& romEntry = *(dirContents[i]);
-		if(romEntry.iAtt & KEntryAttDir)
-			{
-			// this entry's a directory so check if it matches aDirectory
-			const TInt nameLength = romEntry.iNameLength;
-			TPtr8 name((TUint8*)&(romEntry.iName), nameLength * 2, nameLength * 2);
-			if(0 == aDirectory.CompareF(name))
-				{
-				// names matched so get the address of this directory's contents
-				aAddress = romEntry.iAddressLin;
-				dirContents.Close();
-				return KErrNone;
-				}
-			}
-		}
-	dirContents.Close();
-	//couldn't find it so return error
-	return KErrNotFound;
-	}
-
-/**
-  Helper function to get code seg type.
-
-  @param aCodeSeg code seg to get type of
-  @param aType will contain type on return
-
-  @return KErrNone on success, KErrNotFound if aCodeSeg is NULL
-  */
-TInt TListManager::GetCodeSegType(const DCodeSeg* aCodeSeg, TCodeSegType& aType) const
-	{
-	if(!aCodeSeg)
-		{
-		return KErrNotFound;
-		}
-
-	if(aCodeSeg->IsExe())
-		{
-		aType = EExeCodeSegType;
-		return KErrNone;
-		}
-
-	if(aCodeSeg->IsDll())
-		{
-		aType = EDllCodeSegType;
-		return KErrNone;
-		}
-
-	aType = EUnknownCodeSegType;
-	return KErrNone;
-	}
-
-
-/**
-  Split a directory name into its subdirectories, using a 16-bit backslash ('\\\0') as a delimiter.
-  For example z:\sys\bin would be split into { 'z:', 'sys', 'bin' }
-
-  @param aDirectoryName directory name to split into subdirectories
-  @param aSubDirectories array to store the subdirectories in
-  */
-TInt TListManager::SplitDirectoryName(const TDesC& aDirectoryName, RArray<TPtr8>& aSubDirectories) const
-	{
-	//definition in 16 bit unicode
-	_LIT(KBackSlash, "\\\0");
-
-	//split the directory up into its folders, i.e. z:\sys\bin is split into 
-	TPtr8 string((TUint8*)aDirectoryName.Ptr(), aDirectoryName.Length(), aDirectoryName.Length());
-	while(string.Ptr() < aDirectoryName.Ptr() + aDirectoryName.Length())
-		{
-		TInt offset = string.Find(KBackSlash());
-		if(offset == KErrNotFound)
-			{
-			//reached the end of the string
-			offset = string.Length();
-			}
-		//adjustedOffset takes account of the end of the string case
-		TInt adjustedOffset = (offset == string.Length()) ? offset : offset + KBackSlash().Length();
-		//add sub-folder name
-		TInt err = aSubDirectories.Append(TPtr8((TUint8*)string.Ptr(), offset, offset));
-		if(KErrNone != err)
-			{
-			return err;
-			}
-		//remove the sub-folder name and continue
-		string.Set((TUint8*)string.Ptr() + adjustedOffset, string.Length() - adjustedOffset, string.Length() - adjustedOffset);
-		}
-	return KErrNone;
-	}
-
-
-