memspy/Driver/Kernel/Source/MemSpyDriverOSAdaption.cpp
branchRCL_3
changeset 21 52e343bb8f80
parent 20 ca8a1b6995f6
equal deleted inserted replaced
20:ca8a1b6995f6 21:52e343bb8f80
    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"
   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     {
   437     {
   446     {
   438     return static_cast< TExitType >( aObject.iExitType );
   447     return static_cast< TExitType >( aObject.iExitType );
   439     }
   448     }
   440 
   449 
   441 
   450 
   442 DThread* DMemSpyDriverOSAdaptionDProcess::OpenFirstThread( DProcess& aProcess ) const
   451 DThread* DMemSpyDriverOSAdaptionDProcess::GetFirstThread( DProcess& aObject ) const
   443     {
   452     {
   444 	// It appears that the system lock needs to be held while manipulating the iThreadQ
   453     return aObject.FirstThread();
   445 	DThread* result = NULL;
       
   446 	NKern::LockSystem();
       
   447 	// 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
       
   448 	SDblQueLink* threadLink = aProcess.iThreadQ.First();
       
   449 	if (threadLink != NULL && threadLink != &aProcess.iThreadQ.iA)
       
   450 		{
       
   451 		result = _LOFF(threadLink,DThread,iProcessLink);
       
   452 		if (result->Open() != KErrNone)
       
   453 			{
       
   454 			result = NULL;
       
   455 			}
       
   456 		}
       
   457 	NKern::UnlockSystem();
       
   458     return result;
       
   459     }
   454     }
   460 
   455 
   461 
   456 
   462 TUint32 DMemSpyDriverOSAdaptionDProcess::GetSID( DProcess& aObject ) const
   457 TUint32 DMemSpyDriverOSAdaptionDProcess::GetSID( DProcess& aObject ) const
   463     {
   458     {
   548 TUint8* DMemSpyDriverOSAdaptionDProcess::GetAddressOfDataBssStackChunk( DProcess& aObject ) const
   543 TUint8* DMemSpyDriverOSAdaptionDProcess::GetAddressOfDataBssStackChunk( DProcess& aObject ) const
   549     {
   544     {
   550     return (TUint8*)aObject.iDataBssStackChunk;
   545     return (TUint8*)aObject.iDataBssStackChunk;
   551     }
   546     }
   552 
   547 
   553 TBool DMemSpyDriverOSAdaptionDProcess::IsKernProcess(DProcess& aProcess) const
       
   554 	{
       
   555 	// The kernel process always has pid 1
       
   556 	return GetId(aProcess) == 1;
       
   557 	}
       
   558 
   548 
   559 
   549 
   560 
   550 
   561 DMemSpyDriverOSAdaptionDChunk::DMemSpyDriverOSAdaptionDChunk( DMemSpyDriverOSAdaption& aOSAdaption )
   551 DMemSpyDriverOSAdaptionDChunk::DMemSpyDriverOSAdaptionDChunk( DMemSpyDriverOSAdaption& aOSAdaption )
   562 :   DMemSpyDriverOSAdaptionDObject( aOSAdaption )
   552 :   DMemSpyDriverOSAdaptionDObject( aOSAdaption )
   574     {
   564     {
   575     return aObject.MaxSize();
   565     return aObject.MaxSize();
   576     }
   566     }
   577 
   567 
   578 
   568 
   579 TUint8* DMemSpyDriverOSAdaptionDChunk::GetBase( DChunk& aChunk ) const
   569 TUint8* DMemSpyDriverOSAdaptionDChunk::GetBase( DChunk& aObject ) const
   580     {
   570     {
   581     TUint8* base = aChunk.Base();
   571     return aObject.Base();
   582 	if (base == 0)
       
   583 		{
       
   584 		// Under flexible memory model, DChunk::Base() will return NULL (for non-fixed chunks anyway, and that means most of them)
       
   585 		// A more useful thing to return is the base address in the owning process
       
   586 		DProcess* proc = GetOwningProcess(aChunk);
       
   587 		NKern::ThreadEnterCS();
       
   588 		if (proc && proc->Open() == KErrNone)
       
   589 			{
       
   590 			// Probably shouldn't call ChunkUserBase for a non-user-owned chunk
       
   591 			if (!OSAdaption().DProcess().IsKernProcess(*proc))
       
   592 				{
       
   593 				DThread* firstThread = OSAdaption().DProcess().OpenFirstThread(*proc);
       
   594 				if (firstThread)
       
   595 					{
       
   596 					base = Kern::ChunkUserBase(&aChunk, firstThread);
       
   597 					firstThread->Close(NULL);
       
   598 					}
       
   599 				}
       
   600 			proc->Close(NULL);
       
   601 			}
       
   602 		NKern::ThreadLeaveCS();
       
   603 		}
       
   604 	return base; 
       
   605     }
   572     }
   606 
   573 
   607 
   574 
   608 DProcess* DMemSpyDriverOSAdaptionDChunk::GetOwningProcess( DChunk& aObject ) const
   575 DProcess* DMemSpyDriverOSAdaptionDChunk::GetOwningProcess( DChunk& aObject ) const
   609     {
   576     {