diff -r 000000000000 -r a03f92240627 memspy/Engine/Source/Helpers/MemSpyEngineHelperCodeSegment.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/memspy/Engine/Source/Helpers/MemSpyEngineHelperCodeSegment.cpp Tue Feb 02 01:57:15 2010 +0200 @@ -0,0 +1,950 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include + +// System includes +#include +#include +#include + +// Driver includes +#include + +// User includes +#include +#include +#include +#include +#include + +// Constants +const TInt KMemSpyEngineMaxCodeSegmentCount = 512; + +// Literal constants +_LIT( KMemSpyEngineCodeSegListOutputComma, ", " ); + + + +CMemSpyEngineHelperCodeSegment::CMemSpyEngineHelperCodeSegment( CMemSpyEngine& aEngine ) +: iEngine( aEngine ) + { + } + + +CMemSpyEngineHelperCodeSegment::~CMemSpyEngineHelperCodeSegment() + { + } + + +void CMemSpyEngineHelperCodeSegment::ConstructL() + { + } + + +CMemSpyEngineHelperCodeSegment* CMemSpyEngineHelperCodeSegment::NewL( CMemSpyEngine& aEngine ) + { + CMemSpyEngineHelperCodeSegment* self = new(ELeave) CMemSpyEngineHelperCodeSegment( aEngine ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + +EXPORT_C void CMemSpyEngineHelperCodeSegment::OutputCodeSegmentsL( TUint aPid, TDes& aLine, const TDesC& aPrefix, TChar aSectionUnderlineCharacter, TBool aLowerCaseSectionHeading) + { + _LIT(KHeaderLC, "Code Segments"); + _LIT(KHeaderUC, "CODE SEGMENTS"); + + _LIT(KFmtOverflow, "Only first %d code segments displayed"); + _LIT(KFmtMod, "%S%08X-%08X %S"); + + const TInt KMaxCount = 256; + TAny* handles[KMaxCount]; + TInt c = KMaxCount; + + TInt r = iEngine.Driver().GetCodeSegs(aPid, handles, c); + if ( r == KErrNone ) + { + if ( c > 0 ) + { + if ( aLowerCaseSectionHeading ) + { + iEngine.Sink().OutputSectionHeadingL( KHeaderLC, aSectionUnderlineCharacter ); + } + else + { + iEngine.Sink().OutputSectionHeadingL( KHeaderUC, aSectionUnderlineCharacter ); + } + + if (c > KMaxCount) + { + c = KMaxCount; + aLine.Format(KFmtOverflow, c); + iEngine.Sink().OutputLineL( aLine ); + } + + TBuf path; + TMemSpyDriverCodeSegInfo info; + for (TInt i=0; i handles( 16 ); + CleanupClosePushL( handles ); + + // Get everything + GetCodeSegmentHandlesL( handles, NULL, EFalse ); + CMemSpyEngineCodeSegList* list = ListFromHandlesLC( handles ); + // + CleanupStack::Pop( list ); + CleanupStack::PopAndDestroy( &handles ); + // + return list; + } + + +CMemSpyEngineCodeSegList* CMemSpyEngineHelperCodeSegment::CodeSegmentListRamLoadedL() + { + RArray handles( 16 ); + CleanupClosePushL( handles ); + + // Get just RAM-loaded + GetCodeSegmentHandlesL( handles, NULL, ETrue ); + CMemSpyEngineCodeSegList* list = ListFromHandlesLC( handles ); + // + CleanupStack::Pop( list ); + CleanupStack::PopAndDestroy( &handles ); + // + return list; + } + + +EXPORT_C CMemSpyEngineCodeSegList* CMemSpyEngineHelperCodeSegment::CodeSegmentListL( TProcessId aProcess ) + { + TUint processId = aProcess; + // + RArray handles( 16 ); + CleanupClosePushL( handles ); + + // Get process-specific list + GetCodeSegmentHandlesL( handles, &processId, EFalse ); + CMemSpyEngineCodeSegList* list = ListFromHandlesLC( handles ); + // + CleanupStack::Pop( list ); + CleanupStack::PopAndDestroy( &handles ); + // + return list; + } + + +void CMemSpyEngineHelperCodeSegment::GetCodeSegmentHandlesL( RArray& aHandles, TUint* aProcessId, TBool aRamOnly ) const + { + TAny* handles[ KMemSpyEngineMaxCodeSegmentCount ]; + TInt count = KMemSpyEngineMaxCodeSegmentCount; + + TInt r = KErrNone; + + if ( aProcessId == NULL ) + { + r = iEngine.Driver().GetCodeSegs( handles, count, aRamOnly ); + } + else + { + r = iEngine.Driver().GetCodeSegs( *aProcessId, handles, count ); + } + + if ( r == KErrNone ) + { + TInt index; + TLinearOrder< TAny* > comparer( SortByAddress ); + + // Remove duplicates - since we reqested code segments for all processes, there + // might be some dupes. + count = Min( count, KMemSpyEngineMaxCodeSegmentCount ); + for( index = 0; index < count; index++ ) + { + TAny* handle = handles[ index ]; + const TInt error = aHandles.InsertInOrder( handle, comparer ); + // + if ( ! (error == KErrNone || error == KErrAlreadyExists ) ) + { + User::Leave( error ); + } + } + } + } + + +CMemSpyEngineCodeSegList* CMemSpyEngineHelperCodeSegment::ListFromHandlesLC( RArray& aHandles ) const + { + CMemSpyEngineCodeSegList* list = CMemSpyEngineCodeSegList::NewLC( iEngine ); + // + TMemSpyDriverCodeSegInfo info; + const TInt count = aHandles.Count(); + // + for (TInt i=0; iAddItemL( entry ); + CleanupStack::Pop( entry ); + } + } + // + return list; + } + + +TInt CMemSpyEngineHelperCodeSegment::SortByAddress( TAny* const& aLeft, TAny* const& aRight ) + { + TInt ret = 1; + // + if ( aLeft < aRight ) + { + ret = -1; + } + else if ( aLeft == aRight ) + { + ret = 0; + } + // + return ret; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +CMemSpyEngineCodeSegList::CMemSpyEngineCodeSegList( CMemSpyEngine& aEngine ) +: CMemSpyEngineTwiddlableItemArray( aEngine ) + { + } + + +void CMemSpyEngineCodeSegList::ConstructL() + { + } + + +CMemSpyEngineCodeSegList* CMemSpyEngineCodeSegList::NewLC( CMemSpyEngine& aEngine ) + { + CMemSpyEngineCodeSegList* self = new(ELeave) CMemSpyEngineCodeSegList( aEngine ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + + +EXPORT_C TInt CMemSpyEngineCodeSegList::IndexByHandle( TAny* aHandle ) const + { + TInt index = KErrNotFound; + // + const TInt count = Count(); + for(TInt i=0; i comparer( CompareByFileName ); + Sort( comparer ); + } + + +EXPORT_C void CMemSpyEngineCodeSegList::SortByCodeSizeL() + { + TLinearOrder< CMemSpyEngineCodeSegEntry > comparer( CompareByCodeSize ); + Sort( comparer ); + } + + +EXPORT_C void CMemSpyEngineCodeSegList::SortByDataSizeL() + { + TLinearOrder< CMemSpyEngineCodeSegEntry > comparer( CompareByDataSize ); + Sort( comparer ); + } + + +EXPORT_C void CMemSpyEngineCodeSegList::SortByUidsL() + { + TLinearOrder< CMemSpyEngineCodeSegEntry > comparer( CompareByUid ); + Sort( comparer ); + } + + +EXPORT_C void CMemSpyEngineCodeSegList::ShowOnlyEntriesWithGlobalDataL() + { + TMemSpyEngineVisibiltyFunction< CMemSpyEngineCodeSegEntry > function( VisibilityFunctionGlobalData, NULL ); + ShowL( function ); + SortByDataSizeL(); + } + + +EXPORT_C void CMemSpyEngineCodeSegList::OutputDataColumnsL( CMemSpyEngine& aEngine ) + { + HBufC* columns = HBufC::NewLC( 1500 ); + TPtr pColumns( columns->Des() ); + + // + _LIT(KCol1, "Name"); + pColumns.Append( KCol1 ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // + _LIT(KCol2, "Uid %d"); + pColumns.AppendFormat( KCol2, 1 ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + pColumns.AppendFormat( KCol2, 2 ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + pColumns.AppendFormat( KCol2, 3 ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // + _LIT(KCol3, "Module Version"); + pColumns.Append( KCol3 ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // + _LIT(KCol4, "SID"); + pColumns.Append( KCol4 ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // + _LIT(KCol5, "VID"); + pColumns.Append( KCol5 ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // + _LIT(KCol6, "Code Size"); + pColumns.Append( KCol6 ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // + _LIT(KCol7, "Text Size"); + pColumns.Append( KCol7 ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // + _LIT(KCol8, "Data Size"); + pColumns.Append( KCol8 ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // + _LIT(KCol9, "BSS Size"); + pColumns.Append( KCol9 ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // + _LIT(KCol10, "Total Data Size"); + pColumns.Append( KCol10 ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // + _LIT(KCol11, "Entrypoint Veneer"); + pColumns.Append( KCol11 ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // + _LIT(KCol12, "File Entrypoint"); + pColumns.Append( KCol12 ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // + _LIT(KCol13, "Dependency Count"); + pColumns.Append( KCol13 ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // + _LIT(KCol14, "ROM Code Load Address"); + pColumns.Append( KCol14 ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // + _LIT(KCol15, "Data Load Address"); + pColumns.Append( KCol15 ); + + // + _LIT(KCol16, "Capabilities..."); + pColumns.Append( KCol16 ); + + // + aEngine.Sink().OutputLineL( pColumns ); + CleanupStack::PopAndDestroy( columns ); + } + + +EXPORT_C TInt CMemSpyEngineCodeSegList::MdcaCount() const + { + return Count(); + } + + +EXPORT_C TPtrC CMemSpyEngineCodeSegList::MdcaPoint( TInt aIndex ) const + { + const CMemSpyEngineCodeSegEntry& item = At( aIndex ); + return TPtrC( item.Caption() ); + } + + +TInt CMemSpyEngineCodeSegList::IndexByName( const TDesC& aName ) const + { + TInt index = KErrNotFound; + // + const TInt count = Count(); + for(TInt i=0; i= 0 ) + { + index = i; + break; + } + } + // + return index; + } + + +TInt CMemSpyEngineCodeSegList::CompareByFileName( const CMemSpyEngineCodeSegEntry& aLeft, const CMemSpyEngineCodeSegEntry& aRight ) + { + const TInt ret = aLeft.FileName().CompareF( aRight.FileName() ); + return ret; + } + + +TInt CMemSpyEngineCodeSegList::CompareByCodeSize( const CMemSpyEngineCodeSegEntry& aLeft, const CMemSpyEngineCodeSegEntry& aRight ) + { + TInt ret = -1; + // + if ( aLeft.CreateInfo().iCodeSize < aRight.CreateInfo().iCodeSize ) + { + ret = 1; + } + else if ( aLeft.CreateInfo().iCodeSize == aRight.CreateInfo().iCodeSize ) + { + ret = 0; + } + // + return ret; + } + + +TInt CMemSpyEngineCodeSegList::CompareByDataSize( const CMemSpyEngineCodeSegEntry& aLeft, const CMemSpyEngineCodeSegEntry& aRight ) + { + TInt ret = -1; + // + if ( aLeft.CreateInfo().iTotalDataSize < aRight.CreateInfo().iTotalDataSize ) + { + ret = 1; + } + else if ( aLeft.CreateInfo().iTotalDataSize == aRight.CreateInfo().iTotalDataSize ) + { + ret = 0; + } + // + return ret; + } + + +TInt CMemSpyEngineCodeSegList::CompareByUid( const CMemSpyEngineCodeSegEntry& aLeft, const CMemSpyEngineCodeSegEntry& aRight ) + { + TInt ret = -1; + // + if ( aLeft.CreateInfo().iUids.MostDerived().iUid < aRight.CreateInfo().iUids.MostDerived().iUid ) + { + ret = 1; + } + else if ( aLeft.CreateInfo().iUids.MostDerived().iUid == aRight.CreateInfo().iUids.MostDerived().iUid ) + { + ret = 0; + } + // + return ret; + } + + +TBool CMemSpyEngineCodeSegList::VisibilityFunctionGlobalData( const CMemSpyEngineCodeSegEntry*& aItem, TAny* /*aRune*/ ) + { + const TBool hasGlobalData = ( aItem->CreateInfo().iTotalDataSize > 0 ); + return hasGlobalData; + } + + + + + + + + + + + + + + + + + + +CMemSpyEngineCodeSegEntry::CMemSpyEngineCodeSegEntry( TAny* aHandle, TInt aSize, const TCodeSegCreateInfo& aCreateInfo, const TProcessMemoryInfo& aMemoryInfo ) +: CDesCArrayFlat( 10 ), iHandle( aHandle ), iSize( aSize ), iCreateInfo( aCreateInfo ), iMemoryInfo( aMemoryInfo ) + { + } + + +EXPORT_C CMemSpyEngineCodeSegEntry::~CMemSpyEngineCodeSegEntry() + { + delete iCaption; + delete iFileName; + } + + +void CMemSpyEngineCodeSegEntry::ConstructL() + { + iFileName = HBufC::NewL( iCreateInfo.iFileName.Length() ); + iFileName->Des().Copy( iCreateInfo.iFileName ); + + // Make caption + TParsePtrC parser( *iFileName ); + const TPtrC pFileNameWithoutPath( parser.NameAndExt() ); + TBuf item; + // + _LIT(KCodeSegFormat, "\t%S\t\t%S code"); + const TMemSpySizeText codeSize( MemSpyEngineUtils::FormatSizeText( iCreateInfo.iCodeSize ) ); + item.Format( KCodeSegFormat, &pFileNameWithoutPath, &codeSize ); + if ( iCreateInfo.iDataSize > 0 ) + { + _LIT(KCodeSegFormatAdditionalData, ", %S data"); + const TMemSpySizeText dataSize( MemSpyEngineUtils::FormatSizeText( iCreateInfo.iTotalDataSize ) ); + item.AppendFormat( KCodeSegFormatAdditionalData, &dataSize ); + } + iCaption = item.AllocL(); + + // + _LIT(KItem0, "\tName\t\t%S"); + item.Format( KItem0, &pFileNameWithoutPath ); + AppendL( item ); + + // Uids + const TUidType uids( iCreateInfo.iUids ); + for( TInt i=0; i 0 ) + { + _LIT(KItem2, "\tCode Size\t\t%d"); + item.Format( KItem2, iCreateInfo.iCodeSize ); + AppendL( item ); + } + + // + if ( iCreateInfo.iTotalDataSize > 0 ) + { + _LIT(KItem6, "\tTotal Data Size\t\t%d"); + item.Format( KItem6, iCreateInfo.iTotalDataSize ); + AppendL( item ); + } + + // + if ( iCreateInfo.iTextSize > 0 ) + { + _LIT(KItem3, "\tText Size\t\t%d"); + item.Format( KItem3, iCreateInfo.iTextSize ); + AppendL( item ); + } + + // + if ( iCreateInfo.iDataSize > 0 ) + { + _LIT(KItem4, "\tData Size\t\t%d"); + item.Format( KItem4, iCreateInfo.iDataSize ); + AppendL( item ); + } + + // + if ( iCreateInfo.iBssSize > 0 ) + { + _LIT(KItem5, "\tBSS Size\t\t%d"); + item.Format( KItem5, iCreateInfo.iBssSize ); + AppendL( item ); + } + + // + _LIT(KItem7, "\tEntrypoint Veneer\t\t0x%08x"); + item.Format( KItem7, iCreateInfo.iEntryPtVeneer ); + AppendL( item ); + + // + _LIT(KItem8, "\tFile Entrypoint\t\t0x%08x"); + item.Format( KItem8, iCreateInfo.iFileEntryPoint ); + AppendL( item ); + + // + _LIT(KItem9, "\tDependency Count\t\t%d"); + item.Format( KItem9, iCreateInfo.iDepCount ); + AppendL( item ); + + // + if ( iCreateInfo.iCodeLoadAddress != 0 ) + { + _LIT(KItem10, "\tROM Code Load Addr.\t\t0x%08x"); + item.Format( KItem10, iCreateInfo.iCodeLoadAddress ); + AppendL( item ); + } + else + { + _LIT(KItem10, "\tROM Code Load Addr.\t\t[RAM Loaded]"); + AppendL( KItem10 ); + } + + // + if ( iCreateInfo.iDataLoadAddress != 0 ) + { + _LIT(KItem11, "\tData Load Addr.\t\t0x%08x"); + item.Format( KItem11, iCreateInfo.iDataLoadAddress ); + AppendL( item ); + } + + // + AddCapabilityItemsL(); + } + + +CMemSpyEngineCodeSegEntry* CMemSpyEngineCodeSegEntry::NewLC( TAny* aHandle, TInt aSize, const TCodeSegCreateInfo& aCreateInfo, const TProcessMemoryInfo& aMemoryInfo ) + { + CMemSpyEngineCodeSegEntry* self = new(ELeave) CMemSpyEngineCodeSegEntry( aHandle, aSize, aCreateInfo, aMemoryInfo ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + + +EXPORT_C TBool CMemSpyEngineCodeSegEntry::HasCapability( TCapability aCapability ) const + { + TBool hasCap = EFalse; + // + for( TInt i=0; iDes() ); + + // Name + TParsePtrC parser( *iFileName ); + const TPtrC pFileNameWithoutPath( parser.NameAndExt() ); + pColumns.Append( pFileNameWithoutPath ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // Uids + const TUidType uids( iCreateInfo.iUids ); + for( TInt i=0; i 0 ) + { + pColumns.AppendNum( iCreateInfo.iCodeSize, EDecimal ); + } + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // Text size + if ( iCreateInfo.iTextSize > 0 ) + { + pColumns.AppendNum( iCreateInfo.iTextSize, EDecimal ); + } + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // Data size + if ( iCreateInfo.iDataSize > 0 ) + { + pColumns.AppendNum( iCreateInfo.iDataSize, EDecimal ); + } + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // BSS + if ( iCreateInfo.iBssSize > 0 ) + { + pColumns.AppendNum( iCreateInfo.iBssSize, EDecimal ); + } + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // Total data size + if ( iCreateInfo.iTotalDataSize > 0 ) + { + pColumns.AppendNum( iCreateInfo.iTotalDataSize, EDecimal ); + } + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // Entrypoint veneer + pColumns.AppendFormat( KHexFormat, iCreateInfo.iEntryPtVeneer ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // File Entrypoint + pColumns.AppendFormat( KHexFormat, iCreateInfo.iFileEntryPoint ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // Dependency Count + pColumns.AppendNum( iCreateInfo.iDepCount, EDecimal ); + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // ROM Code Load Address + if ( iCreateInfo.iCodeLoadAddress != 0 ) + { + pColumns.AppendFormat( KHexFormat, iCreateInfo.iCodeLoadAddress ); + } + else + { + _LIT(KCaption, "N.A. - RAM Loaded"); + pColumns.Append( KCaption ); + } + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // Data Load Address + if ( iCreateInfo.iDataLoadAddress != 0 ) + { + pColumns.AppendFormat( KHexFormat, iCreateInfo.iDataLoadAddress ); + } + pColumns.Append( KMemSpyEngineCodeSegListOutputComma ); + + // Capabilities + CDesCArray* capabilities = CapabilityStringsLC(); + const TInt count = capabilities->Count(); + // + for( TInt j=0; j item; + // + CDesCArray* capabilities = CapabilityStringsLC(); + const TInt count = capabilities->Count(); + // + for( TInt i=0; i capabilityName; + // + for( TInt i=aCapCount; i( i ); + MemSpyEngineUtils::GetCapabilityName( capabilityName, capability ); + + // Make a capability entry for this item + aArray.AppendL( capabilityName ); + } + } + } + + + + + + + + + + + + + +