memspy/Driver/Kernel/Source/MemSpyDriverHeap.cpp
branchRCL_3
changeset 59 8ad140f3dd41
parent 49 7fdc9a71d314
--- a/memspy/Driver/Kernel/Source/MemSpyDriverHeap.cpp	Wed Sep 15 13:53:27 2010 +0300
+++ b/memspy/Driver/Kernel/Source/MemSpyDriverHeap.cpp	Wed Oct 13 16:17:58 2010 +0300
@@ -23,62 +23,129 @@
 // User includes
 #include "MemSpyDriverOSAdaption.h"
 #include "MemSpyDriverUtils.h"
-#include "heaputils.h"
 
+// Defines
+#define __NEXT_CELL(p)				((RMemSpyDriverRHeapBase::SCell*)(((TUint8*)p)+p->len))
+#define __NEXT_CELL2(p,l)			((RMemSpyDriverRHeapBase::SCell*)(((TUint8*)p)+l))
 
 
 RMemSpyDriverRHeapBase::RMemSpyDriverRHeapBase()
-	: iHelper(NULL)
     {
     Reset();
     }
 
-LtkUtils::RAllocatorHelper* RMemSpyDriverRHeapBase::Helper()
-	{
-	return iHelper;
-	}
-
-TMemSpyHeapInfo::THeapImplementationType RMemSpyDriverRHeapBase::GetTypeFromHelper() const
-	{
-	if (iHelper)
-		{
-		LtkUtils::RAllocatorHelper::TType type = iHelper->GetType();
-		switch (type)
-			{
-			case LtkUtils::RAllocatorHelper::ETypeRHeap:
-				return TMemSpyHeapInfo::ETypeRHeap;
-			case LtkUtils::RAllocatorHelper::ETypeRHybridHeap:
-				return TMemSpyHeapInfo::ETypeRHybridHeap;
-			case LtkUtils::RAllocatorHelper::ETypeUnknown:
-			default:
-				return TMemSpyHeapInfo::ETypeUnknown;
-			}
-		}
-	return TMemSpyHeapInfo::ETypeUnknown;
-	}
 
 void RMemSpyDriverRHeapBase::Reset()
     {
-	Close();
+	iAccessCount = 0;
+	iHandleCount = 0;
+	iHandles = NULL;
+	iFlags = 0;
+	iCellCount = 0;
+	iTotalAllocSize = 0;
+    
+    iMinLength = 0;
+	iMaxLength = 0;
+	iOffset = 0;
+	iGrowBy = 0;
+	iChunkHandle = 0;
+	// iLock needs no initialisation due to default ctor
+	iBase = NULL;
+	iTop = NULL;
+	iAlign = 0;
+	iMinCell = 0;
+	iPageSize = 0;
+	iFree.len = 0;
+	iFree.next = NULL;
+	iNestingLevel = 0;
+	iAllocCount = 0;
+    iFailType = RAllocator::EReset;
+	iFailRate = 0;
+	iFailed = EFalse;
+	iFailAllocCount = 0;
+	iRand = 0;
+	iTestData = NULL;
+    }
+
+
+TBool RMemSpyDriverRHeapBase::CheckCell( TAny* aCellAddress, TInt aLength ) const
+	{
+	const TLinAddr m = TLinAddr(iAlign - 1);
+    TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CheckCell() - cell: 0x%08x, len: %8d, iAlign: %d, m: %d", aCellAddress, aLength, iAlign, m) );
+
+    TBool isValid = ETrue;
+    //
+    if ( isValid && (aLength & m) )
+        {
+    	TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CheckCell() - ERROR - length is odd: %d, iAlign: %d, m: %d", aLength, iAlign, m) );
+        isValid = EFalse;
+        }
+    if ( isValid && aLength < iMinCell )
+        {
+    	TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CheckCell() - ERROR - length: %d, is less than min cell size (%d)", aLength, iMinCell) );
+        isValid = EFalse;
+        }
+    if ( isValid && (TUint8*)aCellAddress < iBase )
+        {
+    	TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CheckCell() - ERROR - cell address: 0x%08x, is before start address: 0x%08x", (TUint8*) aCellAddress, iBase) );
+        isValid = EFalse;
+        }
+
+    if  ( isValid )
+        {
+        const TUint8* nextCell = (TUint8*)__NEXT_CELL2(aCellAddress, aLength);
+        if  ( nextCell > iTop )
+            {
+        	TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CheckCell() - ERROR - nextCell: 0x%08x is after the top of the heap: 0x%08x", nextCell, iTop) );
+            isValid = EFalse;
+            }
+        }
+    //
+    return isValid;
 	}
 
-void RMemSpyDriverRHeapBase::Close()
-	{
-	if (iHelper)
-		{
-	    NKern::ThreadEnterCS();
-		iHelper->Close();
-		delete iHelper;
-		iHelper = NULL;
-		NKern::ThreadLeaveCS();
-		}
+
+TInt RMemSpyDriverRHeapBase::AllocatedCellHeaderSize( TBool aDebugLibrary )
+    {
+    // Allocated cells are only 4 bytes in UREL, but 12 bytes in UDEB.
+    TInt size = sizeof(SCell*);
+    //
+    if  ( aDebugLibrary )
+        {
+        size = sizeof(SDebugCell);
+        }
+    //
+    return size;
     }
 
+
+TInt RMemSpyDriverRHeapBase::FreeCellHeaderSize()
+    {
+    // Free cells remain the same size in UREL and UDEB builds.
+    const TInt size = sizeof(SCell);
+    return size; 
+    }
+
+
+TInt RMemSpyDriverRHeapBase::CellHeaderSize( const TMemSpyDriverInternalWalkHeapParamsCell& aCell, TBool aDebugLibrary )
+    {
+    TInt size = 0;
+    //
+    if  ( aCell.iCellType == EMemSpyDriverGoodAllocatedCell )
+        {
+        size = AllocatedCellHeaderSize( aDebugLibrary );
+        }
+    else if ( aCell.iCellType == EMemSpyDriverGoodFreeCell ) 
+        {
+        size = FreeCellHeaderSize();
+        }
+    //
+    return size;
+    }
+
+
 void RMemSpyDriverRHeapBase::PrintInfo()
     {
-	/* TOMSCI TODO replace with tracing based on latest struct info. See DMemSpyDriverLogChanHeapBase::PrintHeapInfo
-	 * Alternatively just call DMemSpyDriverLogChanHeapBase::PrintHeapInfo() somehow?
-	 
 #if defined(TRACE_TYPE_KERNELHEAP) || defined(TRACE_TYPE_USERHEAP)
     Kern::Printf(" " );
     Kern::Printf("RMemSpyDriverRHeapBase::PrintInfo - RAllocator - iAccessCount:    0x%08x", iAccessCount );
@@ -106,11 +173,70 @@
     Kern::Printf(" " );
     Kern::Printf(" " );
 #endif
-	*/
+    }
+
+
+void RMemSpyDriverRHeapBase::CopyObjectDataTo( TMemSpyHeapObjectDataRHeap& aData )
+    {
+    TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CopyObjectDataTo() - START" ) );
+
+    TUint8* sourceAddress = reinterpret_cast< TUint8* >( this );
+    sourceAddress += KRAllocatorAndRHeapMemberDataOffset;
+    memcpy( &aData, sourceAddress, KRHeapObjectSize );
+
+    TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapBase::CopyObjectDataTo() - END") );
     }
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 RMemSpyDriverRHeapReadFromCopy::RMemSpyDriverRHeapReadFromCopy( DMemSpyDriverOSAdaption& aOSAdaption )
-:   iOSAdaption( aOSAdaption ), iChunk( NULL ), iChunkAddress( 0 ), iChunkMappingAttributes( 0 ) /*, iClientToKernelDelta( 0 )*/
+:   iOSAdaption( aOSAdaption ), iChunk( NULL ), iChunkAddress( 0 ), iChunkMappingAttributes( 0 ), iClientToKernelDelta( 0 )
     {
     }
 
@@ -122,7 +248,7 @@
     iChunk = NULL;
     iChunkAddress = 0;
     iChunkMappingAttributes = 0;
-    //iClientToKernelDelta = 0;
+    iClientToKernelDelta = 0;
     }
 
 
@@ -137,13 +263,13 @@
     // Calculate start of real heap data (skipping over embedded RHeap object)
     // Since we must operate with kernel-side addressing into our cloned heap chunk,
     // we must use aAddress (the kernel address of the chunk) rather than aChunk->iBase
-    //TOMSCI iClientToKernelDelta = ( (TUint8*) aAddress ) - ( Base() - KRHeapObjectSize );
+    iClientToKernelDelta = ( (TUint8*) aAddress ) - ( Base() - KRHeapObjectSize );
 
     TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapReadFromCopy::AssociateWithKernelChunk() - END - delta between client's user-side base address (base: 0x%08x), kernel-side base address (base: 0x%08x), and kernel-side chunk (base: 0x%08x) is: 0x%08x", Base(), aChunk->iBase, aAddress, iClientToKernelDelta) );
     }
 
 
-/*void RMemSpyDriverRHeapReadFromCopy::DisassociateWithKernelChunk()
+void RMemSpyDriverRHeapReadFromCopy::DisassociateWithKernelChunk()
     {
     TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapReadFromCopy::DisassociateWithKernelChunk() - START - iChunk: 0x%08x", iChunk ) );
 
@@ -157,7 +283,7 @@
 
     TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapReadFromCopy::DisassociateWithKernelChunk() - END") );
     }
-*/
+
 
 DChunk& RMemSpyDriverRHeapReadFromCopy::Chunk()
     {
@@ -171,7 +297,7 @@
     }
 
 
-/*TLinAddr RMemSpyDriverRHeapReadFromCopy::ChunkKernelAddress() const
+TLinAddr RMemSpyDriverRHeapReadFromCopy::ChunkKernelAddress() const
     {
     return iChunkAddress;
     }
@@ -182,49 +308,118 @@
     return iChunk != NULL;
     }
 
+
 TUint RMemSpyDriverRHeapReadFromCopy::ClientToKernelDelta() const
     {
     return iClientToKernelDelta;
     }
-*/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 
 
 
 
 RMemSpyDriverRHeapUser::RMemSpyDriverRHeapUser( DMemSpyDriverOSAdaption& aOSAdaption )
-	: RMemSpyDriverRHeapBase(), iOSAdaption(aOSAdaption)
+:   RMemSpyDriverRHeapReadFromCopy( aOSAdaption )
     {
     }
 
 
-TInt RMemSpyDriverRHeapUser::OpenUserHeap(DThread& aThread, TBool aEuserUdeb)
-	{
-	TLinAddr allocatorAddr = (TLinAddr)OSAdaption().DThread().GetAllocator(aThread);
-	NKern::ThreadEnterCS();
-	LtkUtils::RKernelSideAllocatorHelper* helper = new LtkUtils::RKernelSideAllocatorHelper;
-	if (!helper)
-		{
-		NKern::ThreadLeaveCS();
-		return KErrNoMemory;
-		}
-	TInt err = helper->OpenUserHeap(OSAdaption().DThread().GetId(aThread), allocatorAddr, aEuserUdeb);
-	if (!err)
-		{
-		iChunk = helper->OpenUnderlyingChunk();
-		if (!iChunk) err = KErrNotFound;
-		}
-	if (err)
-		{
-		delete helper;
-		}
-	else
-		{
-		iHelper = helper;
-		}
-	NKern::ThreadLeaveCS();
-	return err;
-	}
+TInt RMemSpyDriverRHeapUser::ReadFromUserAllocator( DThread& aThread )
+    {
+    TBuf8<KRHeapMemberDataSize> memberData;
+    memberData.SetMax();
+
+    NKern::ThreadEnterCS();
+    NKern::LockSystem();
+    RAllocator* allocator = OSAdaption().DThread().GetAllocator( aThread );
+    NKern::UnlockSystem();
+  	NKern::ThreadLeaveCS();
+
+    TUint8* memberDataAddress = (TUint8*) allocator + KRAllocatorAndRHeapMemberDataOffset;
+	TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapUser::ReadFromUserAllocator() - START - allocator addr: 0x%08x, therefore going to read %d bytes from address 0x%08x within client thread (0x%08x + %4d bytes)", allocator, KRHeapMemberDataSize, memberDataAddress, allocator, KRAllocatorAndRHeapMemberDataOffset ) );
+
+    const TInt error = Kern::ThreadRawRead( &aThread, memberDataAddress, (TAny*) memberData.Ptr(), KRHeapMemberDataSize );
+    TRACE_DATA( MemSpyDriverUtils::DataDump("%lS", memberData.Ptr(), KRHeapMemberDataSize, KRHeapMemberDataSize ) );
+
+    if  ( error == KErrNone )
+        {
+        TUint8* destinationAddress = reinterpret_cast< TUint8* >( this );
+
+        // Skip over our vTable too...
+        destinationAddress += KRAllocatorAndRHeapMemberDataOffset;
+
+        // Now copy data into this object
+        TPtr8 self( destinationAddress, KRHeapMemberDataSize, KRHeapMemberDataSize );
+        self.Copy( memberData );
+
+        PrintInfo();
+        }
+    else
+        {
+        }
+
+	TRACE_HEAP( Kern::Printf("RMemSpyDriverRHeapUser::ReadFromUserAllocator() - END - read error: %d", error ) );
+    return error;
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 RMemSpyDriverRHeapKernelFromCopy::RMemSpyDriverRHeapKernelFromCopy( DMemSpyDriverOSAdaption& aOSAdaption )
 :   RMemSpyDriverRHeapReadFromCopy( aOSAdaption )
@@ -253,7 +448,6 @@
     }
 
 
-/*
 void RMemSpyDriverRHeapKernelFromCopy::DisassociateWithKernelChunk()
     {
     TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelFromCopy::DisassociateWithKernelChunk() - START - iKernelHeap: 0x%08x", iKernelHeap ));
@@ -261,55 +455,93 @@
     RMemSpyDriverRHeapReadFromCopy::DisassociateWithKernelChunk();
     TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelFromCopy::DisassociateWithKernelChunk() - END") );
     }
-*/
+
 
-void RMemSpyDriverRHeapKernelFromCopy::Close()
-	{
-	//TOMSCI TODO close the chunk
-	}
+void RMemSpyDriverRHeapKernelFromCopy::GetHeapSpecificInfo( TMemSpyHeapInfo& aInfo ) const
+    {
+    TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelFromCopy::GetHeapSpecificInfo() - START - iKernelHeap: 0x%08x", iKernelHeap ));
+    //
+    if  ( iKernelHeap )
+        {
+        const TUint32* pHeap = reinterpret_cast< TUint32* >( iKernelHeap );
+        //
+        TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap();
+        TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData();
+        rHeapMetaData.SetVTable( *pHeap );
+        rHeapMetaData.SetClassSize( KRHeapObjectSize );
+        //
+        TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelFromCopy::GetHeapSpecificInfo() - RHeapK vtable is: 0x%08x", *pHeap ));
+        }
+    //
+    TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelFromCopy::GetHeapSpecificInfo() - END") );
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 RMemSpyDriverRHeapKernelInPlace::RMemSpyDriverRHeapKernelInPlace()
-	: iChunk(NULL)
+:   iKernelHeap( NULL ), iChunk( NULL )
     {
     }
 
-TInt RMemSpyDriverRHeapKernelInPlace::OpenKernelHeap()
-	{
-	NKern::ThreadEnterCS();
-	LtkUtils::RAllocatorHelper* helper = new LtkUtils::RAllocatorHelper;
-	if (!helper)
-		{
-		NKern::ThreadLeaveCS();
-		return KErrNoMemory;
-		}
-	TInt err = helper->OpenKernelHeap();
-	if (!err)
-		{
-		iChunk = helper->OpenUnderlyingChunk();
-		if (!iChunk) err = KErrNotFound;
-		}
+
+void RMemSpyDriverRHeapKernelInPlace::SetKernelHeap( RHeapK& aKernelHeap )
+    {
+    iKernelHeap = &aKernelHeap;
+    CopyMembersFromKernelHeap();
+    }
+
+
+void RMemSpyDriverRHeapKernelInPlace::FailNext()
+    {
+#ifndef __SYMBIAN_KERNEL_HYBRID_HEAP__
+    RMemSpyDriverRHeapKernelInPlace::RHeapKExtended* heap = reinterpret_cast< RMemSpyDriverRHeapKernelInPlace::RHeapKExtended* >( iKernelHeap );
+    heap->FailNext();
+#endif
+    }
+
 
-	if (err)
-		{
-		delete helper;
-		}
-	else
-		{
-		iHelper = helper;
-		}
-	NKern::ThreadLeaveCS();
-	return err;
-	}
+void RMemSpyDriverRHeapKernelInPlace::Reset()
+    {
+    RMemSpyDriverRHeapBase::Reset();
+	//
+    iChunk = NULL;
+    }
+
 
-void RMemSpyDriverRHeapKernelInPlace::Close()
+void RMemSpyDriverRHeapKernelInPlace::AssociateWithKernelChunk( DChunk* aChunk, TLinAddr /*aAddress*/, TUint32 /*aMappingAttributes*/ )
     {
-	NKern::ThreadEnterCS();
-	iChunk->Close(NULL);
-	iChunk = NULL;
-	RMemSpyDriverRHeapBase::Close();
-	NKern::ThreadLeaveCS();
+    TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::AssociateWithKernelChunk() - START - aChunk: %O, aChunk base: 0x%08x", aChunk, aChunk->iBase ) );
+    iChunk = aChunk;
     }
 
+
+void RMemSpyDriverRHeapKernelInPlace::DisassociateWithKernelChunk()
+    {
+    TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::DisassociateWithKernelChunk() - START - iChunk: 0x%08x", iChunk ));
+    iChunk = NULL;
+    iKernelHeap = NULL;
+    TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::DisassociateWithKernelChunk() - END") );
+    }
+
+
 DChunk& RMemSpyDriverRHeapKernelInPlace::Chunk()
     {
     return *iChunk;
@@ -321,3 +553,68 @@
     return *iChunk;
     }
 
+
+TLinAddr RMemSpyDriverRHeapKernelInPlace::ChunkKernelAddress() const
+    {
+    const TLinAddr ret = reinterpret_cast< TLinAddr >( iChunk->iBase );
+    return ret;
+    }
+
+
+TBool RMemSpyDriverRHeapKernelInPlace::ChunkIsInitialised() const
+    {
+    return iChunk != NULL;
+    }
+
+
+TUint RMemSpyDriverRHeapKernelInPlace::ClientToKernelDelta() const
+    {
+    // We're operating in kernel address space, there is no delta.
+    return 0;
+    }
+
+
+void RMemSpyDriverRHeapKernelInPlace::CopyMembersFromKernelHeap()
+    {
+    TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::CopyMembersFromKernelHeap() - START" ) );
+
+    // Perform a copy operation in order to populate base class with a duplicate of the kernel's heap info.
+    RHeapK* kernelHeap = iKernelHeap;
+
+    // Source address
+    TUint8* sourceAddress = (TUint8*) kernelHeap + KRAllocatorAndRHeapMemberDataOffset;
+    TUint8* destinationAddress = (TUint8*) this + KRAllocatorAndRHeapMemberDataOffset;
+
+    // Copy 
+    memcpy( destinationAddress, sourceAddress, KRHeapMemberDataSize );
+
+    // And print info in debug builds for verification...
+    PrintInfo();
+
+    TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::CopyMembersFromKernelHeap() - END" ) );
+    }
+
+
+void RMemSpyDriverRHeapKernelInPlace::GetHeapSpecificInfo( TMemSpyHeapInfo& aInfo ) const
+    {
+    TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::GetHeapSpecificInfo() - START - iKernelHeap: 0x%08x", iKernelHeap ));
+    //
+    if  ( iKernelHeap )
+        {
+        const TUint32* pHeap = reinterpret_cast< TUint32* >( iKernelHeap );
+        //
+        TMemSpyHeapInfoRHeap& rHeapInfo = aInfo.AsRHeap();
+        TMemSpyHeapMetaDataRHeap& rHeapMetaData = rHeapInfo.MetaData();
+        rHeapMetaData.SetVTable( *pHeap );
+        rHeapMetaData.SetClassSize( KRHeapObjectSize );
+        //
+        TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::GetHeapSpecificInfo() - RHeapK vtable is: 0x%08x", *pHeap ));
+        }
+    //
+    TRACE_KH( Kern::Printf("RMemSpyDriverRHeapKernelInPlace::GetHeapSpecificInfo() - END") );
+    }
+
+
+
+
+