--- a/memspy/Driver/Kernel/Source/MemSpyDriverOSAdaption.cpp Wed Sep 15 13:53:27 2010 +0300
+++ b/memspy/Driver/Kernel/Source/MemSpyDriverOSAdaption.cpp Wed Oct 13 16:17:58 2010 +0300
@@ -22,18 +22,28 @@
#include <nk_plat.h>
#ifdef __MARM__
+
#include <arm.h>
+// Necessary when accessing data members by steam via offsets in order
+// to prevent potential unaligned data aborts
+
+#ifdef __CC_ARM
+#define UNALIGNED_DATA_MEMBER __packed
+#endif /* __CC_ARM */
+
+#endif /* __MARM__ */
+
+#ifndef UNALIGNED_DATA_MEMBER
+#define UNALIGNED_DATA_MEMBER
#endif
-// I've removed UNALIGNED_DATA_MEMBER in preference for just using memcpy to get round the potential unaligned access. -TomS
-
// User includes
#include "MemSpyDriverLog.h"
#include "MemSpyDriverPAndS.h"
#include "MemSpyDriverDevice.h"
// Internal constants
-const TInt KMemSpyLocalThreadDataSizeEstimate = 0x80; // The amount of user stack that MemSpy attempts to scan for the RHeap vTable
+const TInt KMemSpyLocalThreadDataSizeEstimate = 0x80; // The amount of user stack that MemSpy attempts to scan for the RHeaep vTable
@@ -154,9 +164,10 @@
{
DThread* dThread = &aObject;
TUint32 pTarget = reinterpret_cast<TUint32>( dThread ) + iOffset_ExitType;
- TUint8 exitType = *reinterpret_cast<TUint8*>(pTarget);
- TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetExitType() - aObject: 0x%08x, ret: %d", &aObject, (TInt)exitType ) );
- return (TExitType)exitType;
+ UNALIGNED_DATA_MEMBER TExitType* pRet = reinterpret_cast< TExitType* >( pTarget );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetExitType() - aObject: 0x%08x, ret: 0x%08x", &aObject, pRet ) );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetExitType() - value: %d", *pRet ) );
+ return *pRet;
}
@@ -164,11 +175,10 @@
{
DThread* dThread = &aObject;
TUint32 pTarget = reinterpret_cast<TUint32>( dThread ) + iOffset_SupervisorStackBase;
-
- TUint32 ret;
- memcpy(&ret, (const TAny*)pTarget, sizeof(TUint32));
- TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackBase() - aObject: 0x%08x, ret: 0x%08x", &aObject, ret ) );
- return ret;
+ UNALIGNED_DATA_MEMBER TUint32* pRet = reinterpret_cast< TUint32* >( pTarget );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackBase() - aObject: 0x%08x, ret: 0x%08x", &aObject, pRet ) );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackBase() - 0x%08x: %d", *pRet ) );
+ return *pRet;
}
@@ -176,11 +186,10 @@
{
DThread* dThread = &aObject;
TUint32 pTarget = reinterpret_cast<TUint32>( dThread ) + iOffset_SupervisorStackSize;
-
- TInt ret;
- memcpy(&ret, (const TAny*)pTarget, sizeof(TInt));
- TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackSize() - aObject: 0x%08x, ret: %d", &aObject, ret ) );
- return ret;
+ UNALIGNED_DATA_MEMBER TInt* pRet = reinterpret_cast< TInt* >( pTarget );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackSize() - aObject: 0x%08x, ret: 0x%08x", &aObject, pRet ) );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackSize() - value: %d", *pRet ) );
+ return *pRet;
}
@@ -202,7 +211,6 @@
}
-// TODO try to rework this without inspecting the stack!
CActiveScheduler* DMemSpyDriverOSAdaptionDThread::GetActiveScheduler( DThread& aObject ) const
{
TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetActiveScheduler() - START" ) );
@@ -326,19 +334,18 @@
}
}
-// TODO re-work this without inspecting the stack.
-// In particular we can get the allocator from the DThread object's iAllocator object
-RAllocator* DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress( DThread& aThread, TUint32& aStackAddress ) const
+
+RAllocator* DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress( DThread& aObject, TUint32& aStackAddress ) const
{
- TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - START for aThread 0x%08x with ID %d", &aThread, aThread.iId ) );
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - START" ) );
//
aStackAddress = 0;
RAllocator* ret = NULL;
// We will assume the thread is running and that the user-side stack has been set up
// accordingly.
- const TUint32 base = GetUserStackBase( aThread );
- const TInt size = GetUserStackSize( aThread );
+ const TUint32 base = GetUserStackBase( aObject );
+ const TInt size = GetUserStackSize( aObject );
TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - base: 0x%08x, size: %d, KMemSpyLocalThreadDataSizeEstimate: %d", base, size, KMemSpyLocalThreadDataSizeEstimate ) );
const TUint32 top = base + size;
@@ -356,20 +363,12 @@
//
TUint32* ptr = reinterpret_cast< TUint32* >( addr );
//
- r = Kern::ThreadRawRead( &aThread, ptr, &value, sizeof( value ) );
+ r = Kern::ThreadRawRead( &aObject, ptr, &value, sizeof( value ) );
if ( r == KErrNone )
{
- r = Kern::ThreadRawRead( &aThread, reinterpret_cast< const TAny* >( value ), &possibleVTable, sizeof( possibleVTable ) );
+ Kern::ThreadRawRead( &aObject, reinterpret_cast< const TAny* >( value ), &possibleVTable, sizeof( possibleVTable ) );
}
-
- if ( r == KErrNone )
- {
- TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - stack[0x%08x] 0x%08x, vTable: 0x%08x (offset: %04d)", addr, value, possibleVTable, top - addr ) );
- }
- else
- {
- TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - stack[0x%08x] 0x%08x, (offset: %04d) read failed: %d", addr, value, top - addr, r ) );
- }
+ TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - stack[0x%08x] 0x%08x, vTable: 0x%08x (offset: %04d)", addr, value, possibleVTable, top - addr ) );
}
#endif
@@ -380,7 +379,7 @@
//
TUint32* ptr = reinterpret_cast< TUint32* >( addr );
//
- r = Kern::ThreadRawRead( &aThread, ptr, &value, sizeof( value ) );
+ r = Kern::ThreadRawRead( &aObject, ptr, &value, sizeof( value ) );
TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - read from: 0x%08x, result: %d, value: 0x%08x", addr, r, value ) );
//
if ( r == KErrNone )
@@ -389,7 +388,7 @@
// the TLD class holds an RAllocator* and we need to ascertain the vTable of the RAllocator* matches the
// only supported vTable that MemSpy understands (RHeap*).
TUint32 possibleVTable = 0;
- r = Kern::ThreadRawRead( &aThread, reinterpret_cast< const TAny* >( value ), &possibleVTable, sizeof( possibleVTable ) );
+ r = Kern::ThreadRawRead( &aObject, reinterpret_cast< const TAny* >( value ), &possibleVTable, sizeof( possibleVTable ) );
TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - possible vtable read from: 0x%08x, result: %d, possibleVTable: 0x%08x", value, r, possibleVTable ) );
if ( r == KErrNone && possibleVTable == rHeapVTable )
{
@@ -449,23 +448,9 @@
}
-DThread* DMemSpyDriverOSAdaptionDProcess::OpenFirstThread( DProcess& aProcess ) const
+DThread* DMemSpyDriverOSAdaptionDProcess::GetFirstThread( DProcess& aObject ) const
{
- // It appears that the system lock needs to be held while manipulating the iThreadQ
- DThread* result = NULL;
- NKern::LockSystem();
- // We don't use DProcess::FirstThread() as that doesn't appear to do any checking of whether the list is empty, ie if there are no threads at all
- SDblQueLink* threadLink = aProcess.iThreadQ.First();
- if (threadLink != NULL && threadLink != &aProcess.iThreadQ.iA)
- {
- result = _LOFF(threadLink,DThread,iProcessLink);
- if (result->Open() != KErrNone)
- {
- result = NULL;
- }
- }
- NKern::UnlockSystem();
- return result;
+ return aObject.FirstThread();
}
@@ -560,11 +545,6 @@
return (TUint8*)aObject.iDataBssStackChunk;
}
-TBool DMemSpyDriverOSAdaptionDProcess::IsKernProcess(DProcess& aProcess) const
- {
- // The kernel process always has pid 1
- return GetId(aProcess) == 1;
- }
@@ -586,32 +566,9 @@
}
-TUint8* DMemSpyDriverOSAdaptionDChunk::GetBase( DChunk& aChunk ) const
+TUint8* DMemSpyDriverOSAdaptionDChunk::GetBase( DChunk& aObject ) const
{
- TUint8* base = aChunk.Base();
- if (base == 0)
- {
- // Under flexible memory model, DChunk::Base() will return NULL (for non-fixed chunks anyway, and that means most of them)
- // A more useful thing to return is the base address in the owning process
- DProcess* proc = GetOwningProcess(aChunk);
- NKern::ThreadEnterCS();
- if (proc && proc->Open() == KErrNone)
- {
- // Probably shouldn't call ChunkUserBase for a non-user-owned chunk
- if (!OSAdaption().DProcess().IsKernProcess(*proc))
- {
- DThread* firstThread = OSAdaption().DProcess().OpenFirstThread(*proc);
- if (firstThread)
- {
- base = Kern::ChunkUserBase(&aChunk, firstThread);
- firstThread->Close(NULL);
- }
- }
- proc->Close(NULL);
- }
- NKern::ThreadLeaveCS();
- }
- return base;
+ return aObject.Base();
}