memspy/Driver/Kernel/Source/MemSpyDriverOSAdaption.cpp
branchRCL_3
changeset 59 8ad140f3dd41
parent 49 7fdc9a71d314
equal deleted inserted replaced
49:7fdc9a71d314 59:8ad140f3dd41
    20 #include <kern_priv.h>
    20 #include <kern_priv.h>
    21 #include <nkern.h>
    21 #include <nkern.h>
    22 #include <nk_plat.h>
    22 #include <nk_plat.h>
    23 
    23 
    24 #ifdef __MARM__
    24 #ifdef __MARM__
       
    25 
    25 #include <arm.h>
    26 #include <arm.h>
       
    27 // Necessary when accessing data members by steam via offsets in order
       
    28 // to prevent potential unaligned data aborts
       
    29 
       
    30 #ifdef __CC_ARM
       
    31 #define UNALIGNED_DATA_MEMBER __packed
       
    32 #endif /* __CC_ARM */
       
    33 
       
    34 #endif /* __MARM__ */
       
    35 
       
    36 #ifndef UNALIGNED_DATA_MEMBER
       
    37 #define UNALIGNED_DATA_MEMBER
    26 #endif
    38 #endif
    27 
       
    28 // I've removed UNALIGNED_DATA_MEMBER in preference for just using memcpy to get round the potential unaligned access. -TomS
       
    29 
    39 
    30 // User includes
    40 // User includes
    31 #include "MemSpyDriverLog.h"
    41 #include "MemSpyDriverLog.h"
    32 #include "MemSpyDriverPAndS.h"
    42 #include "MemSpyDriverPAndS.h"
    33 #include "MemSpyDriverDevice.h"
    43 #include "MemSpyDriverDevice.h"
    34 
    44 
    35 // Internal constants
    45 // Internal constants
    36 const TInt KMemSpyLocalThreadDataSizeEstimate = 0x80; // The amount of user stack that MemSpy attempts to scan for the RHeap vTable
    46 const TInt KMemSpyLocalThreadDataSizeEstimate = 0x80; // The amount of user stack that MemSpy attempts to scan for the RHeaep vTable
    37 
    47 
    38 
    48 
    39 
    49 
    40 DMemSpyDriverOSAdaptionDObject::DMemSpyDriverOSAdaptionDObject( DMemSpyDriverOSAdaption& aOSAdaption )
    50 DMemSpyDriverOSAdaptionDObject::DMemSpyDriverOSAdaptionDObject( DMemSpyDriverOSAdaption& aOSAdaption )
    41 :   iOSAdaption( aOSAdaption )
    51 :   iOSAdaption( aOSAdaption )
   152 
   162 
   153 TExitType DMemSpyDriverOSAdaptionDThread::GetExitType( DThread& aObject ) const
   163 TExitType DMemSpyDriverOSAdaptionDThread::GetExitType( DThread& aObject ) const
   154     {
   164     {
   155     DThread* dThread = &aObject;
   165     DThread* dThread = &aObject;
   156     TUint32 pTarget = reinterpret_cast<TUint32>( dThread ) + iOffset_ExitType;
   166     TUint32 pTarget = reinterpret_cast<TUint32>( dThread ) + iOffset_ExitType;
   157 	TUint8 exitType = *reinterpret_cast<TUint8*>(pTarget);
   167     UNALIGNED_DATA_MEMBER TExitType* pRet = reinterpret_cast< TExitType* >( pTarget );
   158     TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetExitType() - aObject: 0x%08x, ret: %d", &aObject, (TInt)exitType ) );
   168     TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetExitType() - aObject: 0x%08x, ret: 0x%08x", &aObject, pRet ) );
   159     return (TExitType)exitType;
   169     TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetExitType() - value: %d", *pRet ) );
       
   170     return *pRet;
   160     }
   171     }
   161 
   172 
   162 
   173 
   163 TUint32 DMemSpyDriverOSAdaptionDThread::GetSupervisorStackBase( DThread& aObject ) const
   174 TUint32 DMemSpyDriverOSAdaptionDThread::GetSupervisorStackBase( DThread& aObject ) const
   164     {
   175     {
   165     DThread* dThread = &aObject;
   176     DThread* dThread = &aObject;
   166     TUint32 pTarget = reinterpret_cast<TUint32>( dThread ) + iOffset_SupervisorStackBase;
   177     TUint32 pTarget = reinterpret_cast<TUint32>( dThread ) + iOffset_SupervisorStackBase;
   167 
   178     UNALIGNED_DATA_MEMBER TUint32* pRet = reinterpret_cast< TUint32* >( pTarget );
   168 	TUint32 ret;
   179     TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackBase() - aObject: 0x%08x, ret: 0x%08x", &aObject, pRet ) );
   169 	memcpy(&ret, (const TAny*)pTarget, sizeof(TUint32));
   180     TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackBase() - 0x%08x: %d", *pRet ) );
   170     TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackBase() - aObject: 0x%08x, ret: 0x%08x", &aObject, ret ) );
   181     return *pRet;
   171     return ret;
       
   172     }
   182     }
   173 
   183 
   174 
   184 
   175 TInt DMemSpyDriverOSAdaptionDThread::GetSupervisorStackSize( DThread& aObject ) const
   185 TInt DMemSpyDriverOSAdaptionDThread::GetSupervisorStackSize( DThread& aObject ) const
   176     {
   186     {
   177     DThread* dThread = &aObject;
   187     DThread* dThread = &aObject;
   178     TUint32 pTarget = reinterpret_cast<TUint32>( dThread ) + iOffset_SupervisorStackSize;
   188     TUint32 pTarget = reinterpret_cast<TUint32>( dThread ) + iOffset_SupervisorStackSize;
   179 	
   189     UNALIGNED_DATA_MEMBER TInt* pRet = reinterpret_cast< TInt* >( pTarget );
   180 	TInt ret;
   190     TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackSize() - aObject: 0x%08x, ret: 0x%08x", &aObject, pRet ) );
   181 	memcpy(&ret, (const TAny*)pTarget, sizeof(TInt));
   191     TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackSize() - value: %d", *pRet ) );
   182     TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetSupervisorStackSize() - aObject: 0x%08x, ret: %d", &aObject, ret ) );
   192     return *pRet;
   183     return ret;
       
   184     }
   193     }
   185 
   194 
   186 
   195 
   187 RAllocator* DMemSpyDriverOSAdaptionDThread::GetAllocator( DThread& aObject ) const
   196 RAllocator* DMemSpyDriverOSAdaptionDThread::GetAllocator( DThread& aObject ) const
   188     {
   197     {
   200     TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocator() - END - ret: 0x%08x", ret ) );
   209     TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocator() - END - ret: 0x%08x", ret ) );
   201     return ret;
   210     return ret;
   202     }
   211     }
   203 
   212 
   204 
   213 
   205 // TODO try to rework this without inspecting the stack!
       
   206 CActiveScheduler* DMemSpyDriverOSAdaptionDThread::GetActiveScheduler( DThread& aObject ) const
   214 CActiveScheduler* DMemSpyDriverOSAdaptionDThread::GetActiveScheduler( DThread& aObject ) const
   207     {
   215     {
   208     TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetActiveScheduler() - START" ) );
   216     TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetActiveScheduler() - START" ) );
   209     CActiveScheduler* ret = aObject.iScheduler;
   217     CActiveScheduler* ret = aObject.iScheduler;
   210     //
   218     //
   324         {
   332         {
   325         aObject.iOwningProcess->FullName( aName );
   333         aObject.iOwningProcess->FullName( aName );
   326         }
   334         }
   327     }
   335     }
   328 
   336 
   329 // TODO re-work this without inspecting the stack.
   337 
   330 // In particular we can get the allocator from the DThread object's iAllocator object
   338 RAllocator* DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress( DThread& aObject, TUint32& aStackAddress ) const
   331 RAllocator* DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress( DThread& aThread, TUint32& aStackAddress ) const
   339     {
   332     {
   340     TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - START" ) );
   333     TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - START for aThread 0x%08x with ID %d", &aThread, aThread.iId ) );
       
   334     //
   341     //
   335     aStackAddress = 0;
   342     aStackAddress = 0;
   336     RAllocator* ret = NULL;
   343     RAllocator* ret = NULL;
   337 
   344 
   338     // We will assume the thread is running and that the user-side stack has been set up
   345     // We will assume the thread is running and that the user-side stack has been set up
   339     // accordingly.
   346     // accordingly.
   340     const TUint32 base = GetUserStackBase( aThread );
   347     const TUint32 base = GetUserStackBase( aObject );
   341     const TInt size = GetUserStackSize( aThread );
   348     const TInt size = GetUserStackSize( aObject );
   342     TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - base: 0x%08x, size: %d, KMemSpyLocalThreadDataSizeEstimate: %d", base, size, KMemSpyLocalThreadDataSizeEstimate ) );
   349     TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - base: 0x%08x, size: %d, KMemSpyLocalThreadDataSizeEstimate: %d", base, size, KMemSpyLocalThreadDataSizeEstimate ) );
   343     const TUint32 top = base + size;
   350     const TUint32 top = base + size;
   344 
   351 
   345     // This is the RHeap vtable we are looking for
   352     // This is the RHeap vtable we are looking for
   346     const TUint32 rHeapVTable = OSAdaption().Device().RHeapVTable();
   353     const TUint32 rHeapVTable = OSAdaption().Device().RHeapVTable();
   354         TUint32 value = 0;
   361         TUint32 value = 0;
   355         TUint32 possibleVTable = 0;
   362         TUint32 possibleVTable = 0;
   356         //
   363         //
   357         TUint32* ptr = reinterpret_cast< TUint32* >( addr );
   364         TUint32* ptr = reinterpret_cast< TUint32* >( addr );
   358         //
   365         //
   359         r = Kern::ThreadRawRead( &aThread, ptr, &value, sizeof( value ) );
   366         r = Kern::ThreadRawRead( &aObject, ptr, &value, sizeof( value ) );
   360         if  ( r == KErrNone )
   367         if  ( r == KErrNone )
   361             {
   368             {
   362             r = Kern::ThreadRawRead( &aThread, reinterpret_cast< const TAny* >( value ), &possibleVTable, sizeof( possibleVTable ) );
   369             Kern::ThreadRawRead( &aObject, reinterpret_cast< const TAny* >( value ), &possibleVTable, sizeof( possibleVTable ) );
   363             }
   370             }
   364 
   371         TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - stack[0x%08x] 0x%08x, vTable: 0x%08x (offset: %04d)", addr, value, possibleVTable, top - addr ) );
   365         if ( r == KErrNone )
       
   366             {
       
   367             TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - stack[0x%08x] 0x%08x, vTable: 0x%08x (offset: %04d)", addr, value, possibleVTable, top - addr ) );
       
   368             }
       
   369         else
       
   370             {
       
   371             TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - stack[0x%08x] 0x%08x, (offset: %04d) read failed: %d", addr, value, top - addr, r ) );
       
   372             }
       
   373         }
   372         }
   374 #endif
   373 #endif
   375 
   374 
   376     for( TUint32 addr = top - 4; addr >= top - KMemSpyLocalThreadDataSizeEstimate; addr -= 4 )
   375     for( TUint32 addr = top - 4; addr >= top - KMemSpyLocalThreadDataSizeEstimate; addr -= 4 )
   377         {
   376         {
   378         TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - addr to read from: 0x%08x", addr ) );
   377         TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - addr to read from: 0x%08x", addr ) );
   379         TUint32 value = 0;
   378         TUint32 value = 0;
   380         //
   379         //
   381         TUint32* ptr = reinterpret_cast< TUint32* >( addr );
   380         TUint32* ptr = reinterpret_cast< TUint32* >( addr );
   382         //
   381         //
   383         r = Kern::ThreadRawRead( &aThread, ptr, &value, sizeof( value ) );
   382         r = Kern::ThreadRawRead( &aObject, ptr, &value, sizeof( value ) );
   384         TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - read from: 0x%08x, result: %d, value: 0x%08x", addr, r, value ) );
   383         TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - read from: 0x%08x, result: %d, value: 0x%08x", addr, r, value ) );
   385         //
   384         //
   386         if  ( r == KErrNone )
   385         if  ( r == KErrNone )
   387             {
   386             {
   388             // Try and read from the address which is now stored within 'value'. We must do this because 
   387             // Try and read from the address which is now stored within 'value'. We must do this because 
   389             // the TLD class holds an RAllocator* and we need to ascertain the vTable of the RAllocator* matches the
   388             // the TLD class holds an RAllocator* and we need to ascertain the vTable of the RAllocator* matches the
   390             // only supported vTable that MemSpy understands (RHeap*).
   389             // only supported vTable that MemSpy understands (RHeap*).
   391             TUint32 possibleVTable = 0;
   390             TUint32 possibleVTable = 0;
   392             r = Kern::ThreadRawRead( &aThread, reinterpret_cast< const TAny* >( value ), &possibleVTable, sizeof( possibleVTable ) );
   391             r = Kern::ThreadRawRead( &aObject, reinterpret_cast< const TAny* >( value ), &possibleVTable, sizeof( possibleVTable ) );
   393             TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - possible vtable read from: 0x%08x, result: %d, possibleVTable: 0x%08x", value, r, possibleVTable ) );
   392             TRACE( Kern::Printf( "DMemSpyDriverOSAdaptionDThread::GetAllocatorAndStackAddress() - possible vtable read from: 0x%08x, result: %d, possibleVTable: 0x%08x", value, r, possibleVTable ) );
   394             if  ( r == KErrNone && possibleVTable == rHeapVTable )
   393             if  ( r == KErrNone && possibleVTable == rHeapVTable )
   395                 {
   394                 {
   396                 aStackAddress = addr;
   395                 aStackAddress = addr;
   397                 ret = reinterpret_cast< RAllocator* >( value );
   396                 ret = reinterpret_cast< RAllocator* >( value );
   447     {
   446     {
   448     return static_cast< TExitType >( aObject.iExitType );
   447     return static_cast< TExitType >( aObject.iExitType );
   449     }
   448     }
   450 
   449 
   451 
   450 
   452 DThread* DMemSpyDriverOSAdaptionDProcess::OpenFirstThread( DProcess& aProcess ) const
   451 DThread* DMemSpyDriverOSAdaptionDProcess::GetFirstThread( DProcess& aObject ) const
   453     {
   452     {
   454 	// It appears that the system lock needs to be held while manipulating the iThreadQ
   453     return aObject.FirstThread();
   455 	DThread* result = NULL;
       
   456 	NKern::LockSystem();
       
   457 	// 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
       
   458 	SDblQueLink* threadLink = aProcess.iThreadQ.First();
       
   459 	if (threadLink != NULL && threadLink != &aProcess.iThreadQ.iA)
       
   460 		{
       
   461 		result = _LOFF(threadLink,DThread,iProcessLink);
       
   462 		if (result->Open() != KErrNone)
       
   463 			{
       
   464 			result = NULL;
       
   465 			}
       
   466 		}
       
   467 	NKern::UnlockSystem();
       
   468     return result;
       
   469     }
   454     }
   470 
   455 
   471 
   456 
   472 TUint32 DMemSpyDriverOSAdaptionDProcess::GetSID( DProcess& aObject ) const
   457 TUint32 DMemSpyDriverOSAdaptionDProcess::GetSID( DProcess& aObject ) const
   473     {
   458     {
   558 TUint8* DMemSpyDriverOSAdaptionDProcess::GetAddressOfDataBssStackChunk( DProcess& aObject ) const
   543 TUint8* DMemSpyDriverOSAdaptionDProcess::GetAddressOfDataBssStackChunk( DProcess& aObject ) const
   559     {
   544     {
   560     return (TUint8*)aObject.iDataBssStackChunk;
   545     return (TUint8*)aObject.iDataBssStackChunk;
   561     }
   546     }
   562 
   547 
   563 TBool DMemSpyDriverOSAdaptionDProcess::IsKernProcess(DProcess& aProcess) const
       
   564 	{
       
   565 	// The kernel process always has pid 1
       
   566 	return GetId(aProcess) == 1;
       
   567 	}
       
   568 
   548 
   569 
   549 
   570 
   550 
   571 DMemSpyDriverOSAdaptionDChunk::DMemSpyDriverOSAdaptionDChunk( DMemSpyDriverOSAdaption& aOSAdaption )
   551 DMemSpyDriverOSAdaptionDChunk::DMemSpyDriverOSAdaptionDChunk( DMemSpyDriverOSAdaption& aOSAdaption )
   572 :   DMemSpyDriverOSAdaptionDObject( aOSAdaption )
   552 :   DMemSpyDriverOSAdaptionDObject( aOSAdaption )
   584     {
   564     {
   585     return aObject.MaxSize();
   565     return aObject.MaxSize();
   586     }
   566     }
   587 
   567 
   588 
   568 
   589 TUint8* DMemSpyDriverOSAdaptionDChunk::GetBase( DChunk& aChunk ) const
   569 TUint8* DMemSpyDriverOSAdaptionDChunk::GetBase( DChunk& aObject ) const
   590     {
   570     {
   591     TUint8* base = aChunk.Base();
   571     return aObject.Base();
   592 	if (base == 0)
       
   593 		{
       
   594 		// Under flexible memory model, DChunk::Base() will return NULL (for non-fixed chunks anyway, and that means most of them)
       
   595 		// A more useful thing to return is the base address in the owning process
       
   596 		DProcess* proc = GetOwningProcess(aChunk);
       
   597 		NKern::ThreadEnterCS();
       
   598 		if (proc && proc->Open() == KErrNone)
       
   599 			{
       
   600 			// Probably shouldn't call ChunkUserBase for a non-user-owned chunk
       
   601 			if (!OSAdaption().DProcess().IsKernProcess(*proc))
       
   602 				{
       
   603 				DThread* firstThread = OSAdaption().DProcess().OpenFirstThread(*proc);
       
   604 				if (firstThread)
       
   605 					{
       
   606 					base = Kern::ChunkUserBase(&aChunk, firstThread);
       
   607 					firstThread->Close(NULL);
       
   608 					}
       
   609 				}
       
   610 			proc->Close(NULL);
       
   611 			}
       
   612 		NKern::ThreadLeaveCS();
       
   613 		}
       
   614 	return base; 
       
   615     }
   572     }
   616 
   573 
   617 
   574 
   618 DProcess* DMemSpyDriverOSAdaptionDChunk::GetOwningProcess( DChunk& aObject ) const
   575 DProcess* DMemSpyDriverOSAdaptionDChunk::GetOwningProcess( DChunk& aObject ) const
   619     {
   576     {