libraries/memoryaccess/MemoryAccess.cpp
changeset 7 184a1eb85cf2
parent 0 7f656887cf89
child 76 2f382fb2036c
--- a/libraries/memoryaccess/MemoryAccess.cpp	Fri Jul 09 10:11:55 2010 +0100
+++ b/libraries/memoryaccess/MemoryAccess.cpp	Mon Jul 26 17:19:00 2010 +0100
@@ -15,6 +15,10 @@
 #include <kernel.h>
 #include <kern_priv.h>
 
+#ifdef __EPOC32__
+#include <memmodel/epoc/plat_priv.h> // For DEpocCodeSeg
+#endif
+
 #include <fshell/common.mmh>
 
 #ifdef FSHELL_DOBJECTIX_SUPPORT
@@ -119,6 +123,7 @@
 	TInt GetObjectAddresses(TObjectType aObjectType, const TDesC8& aOwningProcess, TDes8* aKernelInfoBuf);
 	TInt GetChunkAddresses(TUint aControllingProcessId, TDes8* aKernelInfoBuf);
 	TInt AcquireCodeSegMutex();
+	TInt AcquireCodeSegMutexAndFilterCodesegsForProcess(TUint aProcessId);
 	TInt ReleaseCodeSegMutex();
 	TInt GetNextCodeSegInfo(TDes8* aCodeSegInfoBuf);
 	TInt ObjectDie(TObjectKillParamsBuf& aObjectKillParamsBuf);
@@ -173,12 +178,19 @@
 private:
 	DThread* iClient;
 	TBool iLocks[ENumObjectTypes];
-	TBool iCodeSegLock;
-	DCodeSeg* iCurrentCodeSeg;
+	enum TCodesegLogStatus
+		{
+		ENotHeld,
+		EHeld,
+		EHeldAndTraversing,
+		} iCodeSegLock;
+	SDblQueLink* iCurrentCodeSegLink;
 	DThreadChangeHandler* iEventHandler;
 	DPropertyAccess* iPropertyAccess;
 	TAny* iClientBreakpointNotifyPkg;
 	TRequestStatus* iClientBreakpointNotifyStatus;
+
+	SDblQue iFilteredCodesegQue;
 	};
 
 
@@ -563,6 +575,8 @@
 		}
     case RMemoryAccess::EControlAcquireCodeSegMutex:
     	return AcquireCodeSegMutex();
+    case RMemoryAccess::EControlAcquireCodeSegMutexAndFilterCodesegsForProcess:
+		return AcquireCodeSegMutexAndFilterCodesegsForProcess((TUint)a1);
     case RMemoryAccess::EControlReleaseCodeSegMutex:
     	return ReleaseCodeSegMutex();
     case RMemoryAccess::EControlGetNextCodeSegInfo:
@@ -1201,7 +1215,7 @@
 		if (codeSegLock)
 			{
 			Kern::MutexWait(*codeSegLock);
-			iCodeSegLock = ETrue;
+			iCodeSegLock = EHeld;
 			}
 		else
 			{
@@ -1212,6 +1226,34 @@
 	return err;    	
 	}
 
+TInt DMemoryAccess::AcquireCodeSegMutexAndFilterCodesegsForProcess(TUint aProcessId)
+	{
+	TInt err = KErrNone;
+	NKern::ThreadEnterCS();
+	Kern::Containers()[EProcess]->Wait();
+	DProcess* process = Kern::ProcessFromId(aProcessId);
+	if (process == NULL || process->Open() != KErrNone)
+		{
+		err = KErrNotFound;
+		}
+	Kern::Containers()[EProcess]->Signal();
+
+	if (!err)
+		{
+		err = AcquireCodeSegMutex();
+		}
+	if (!err)
+		{
+		iCodeSegLock = EHeldAndTraversing;
+		TInt numTraversed = process->TraverseCodeSegs(&iFilteredCodesegQue, NULL, DCodeSeg::EMarkDebug, DProcess::ETraverseFlagAdd);
+		err = numTraversed;
+		}
+
+	if (process) process->Close(NULL);
+	NKern::ThreadLeaveCS();
+	return err;
+	}
+
 TInt DMemoryAccess::GetObjectAddresses(TObjectType aObjectType, const TDesC8& aOwningProcess, TDes8* aKernelInfoBuf)
 	{
 	DObjectCon* const * cons = Kern::Containers();
@@ -1325,30 +1367,20 @@
 TInt DMemoryAccess::ReleaseCodeSegMutex()
 	{
 	// Kern::Printf("[DMemoryAccess] ::ReleaseCodeSegMutex");
-	TInt err=KErrNone;
-
-	if (!iCodeSegLock)
-		{ //Check the lock on code segs is not currently held
-		Kern::ThreadKill(iClient, EExitPanic, EMemAccessMutexNotHeld, KMemAccessPanicCategory);
-		err = KErrAbort;
+	if (iCodeSegLock == ENotHeld)
+		{
+		return KErrNotReady;
 		}
 
-	DMutex* const codeSegLock = Kern::CodeSegLock();
-
-	if (!err)
+	if (iCodeSegLock == EHeldAndTraversing)
 		{
-		if (codeSegLock)
-			{
-			Kern::MutexSignal(*codeSegLock);
-			iCodeSegLock = EFalse;
-			}
-		else
-			{
-			err = KErrNotFound;
-			}
+		DCodeSeg::EmptyQueue(iFilteredCodesegQue, DCodeSeg::EMarkDebug);
 		}
+
+	Kern::MutexSignal(*Kern::CodeSegLock());
+	iCodeSegLock = ENotHeld;
 	// Kern::Printf("[DMemoryAccess] ::ReleaseCodeSegMutex returning %d", err);
-	return err;    	
+	return KErrNone;
 	}
 
 
@@ -1357,28 +1389,37 @@
 	// Kern::Printf("[DMemoryAccess] ::GetNextCodeSegInfo");
 	TInt err = KErrNone;
 	
-	SDblQue* p = Kern::CodeSegList();
-	SDblQueLink* anchor=&p->iA;
-
-	if (!iCurrentCodeSeg)
+	SDblQue* p;
+	if (iCodeSegLock == EHeldAndTraversing)
 		{
-		iCurrentCodeSeg = _LOFF(anchor->iNext, DCodeSeg, iLink);
-		}
-
-	if (iCurrentCodeSeg->iLink.iNext != anchor)
-		{
-		iCurrentCodeSeg = _LOFF(iCurrentCodeSeg->iLink.iNext, DCodeSeg, iLink);
+		p = &iFilteredCodesegQue;
 		}
 	else
 		{
-		iCurrentCodeSeg = NULL;
+		p = Kern::CodeSegList();
+		}
+	SDblQueLink* anchor=&p->iA;
+
+	if (!iCurrentCodeSegLink)
+		{
+		iCurrentCodeSegLink = anchor;
+		}
+
+	if (iCurrentCodeSegLink->iNext != anchor)
+		{
+		iCurrentCodeSegLink = iCurrentCodeSegLink->iNext;
+		}
+	else
+		{
+		iCurrentCodeSegLink = NULL;
 		err = KErrNotFound;
 		}
 		
 	if (!err)
 		{
 		//TCodeSegKernelInfoBuf* localInfoBuf = new TCodeSegKernelInfoBuf;
-		TPckgBuf<TTomsciCodeSegKernelInfo>* localInfoBuf = new TPckgBuf<TTomsciCodeSegKernelInfo>;
+		DCodeSeg* currentCodeseg = (iCodeSegLock == EHeldAndTraversing) ? _LOFF(iCurrentCodeSegLink, DCodeSeg, iTempLink) : _LOFF(iCurrentCodeSegLink, DCodeSeg, iLink);
+		TPckgBuf<TCodeSegKernelInfo>* localInfoBuf = new TPckgBuf<TCodeSegKernelInfo>;
 		if (!localInfoBuf)
 			{
 			err = KErrNoMemory;
@@ -1386,14 +1427,21 @@
 		else
 			{	
 			//Get the code seg info
-			(*localInfoBuf)().iRunAddress = iCurrentCodeSeg->iRunAddress;
-			(*localInfoBuf)().iSize = iCurrentCodeSeg->iSize;
-			(*localInfoBuf)().iFileName = iCurrentCodeSeg->iFileName->Right((*localInfoBuf)().iFileName.MaxLength());
-			(*localInfoBuf)().iAccessCount = iCurrentCodeSeg->iAccessCount;
-			(*localInfoBuf)().iAddressOfKernelObject = (TUint8*)iCurrentCodeSeg;
-			(*localInfoBuf)().iName = iCurrentCodeSeg->iRootName;
-			(*localInfoBuf)().iDepCount = iCurrentCodeSeg->iDepCount;
-
+			(*localInfoBuf)().iRunAddress = currentCodeseg->iRunAddress;
+			(*localInfoBuf)().iSize = currentCodeseg->iSize;
+			if (currentCodeseg->iFileName)
+				{
+				(*localInfoBuf)().iFileName = currentCodeseg->iFileName->Right((*localInfoBuf)().iFileName.MaxLength());
+				}
+			(*localInfoBuf)().iAccessCount = currentCodeseg->iAccessCount;
+			(*localInfoBuf)().iAddressOfKernelObject = (TUint8*)currentCodeseg;
+			(*localInfoBuf)().iName = currentCodeseg->iRootName;
+			(*localInfoBuf)().iDepCount = currentCodeseg->iDepCount;
+#ifdef __EPOC32__
+			(*localInfoBuf)().iXip = ((DEpocCodeSeg*)currentCodeseg)->iXIP;
+#else
+			(*localInfoBuf)().iXip = EFalse;
+#endif
 			//Copy the local info buffer into the client's address space
 		    err = Kern::ThreadDesWrite(iClient, aCodeSegInfoBuf, *localInfoBuf, 0, KTruncateToMaxLength, NULL);
 			delete localInfoBuf;