diff -r 7fdc9a71d314 -r 8ad140f3dd41 memspy/Driver/Kernel/Source/MemSpyDriverHeap.cpp --- 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 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") ); + } + + + + +