--- 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") );
+ }
+
+
+
+
+