memspy/Engine/Source/Helpers/MemSpyEngineHelperCodeSegment.cpp
changeset 0 a03f92240627
--- /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 <memspy/engine/memspyenginehelpercodesegment.h>
+
+// System includes
+#include <e32capability.h>
+#include <f32file.h>
+#include <babitflags.h>
+
+// Driver includes
+#include <memspy/driver/memspydriverclient.h>
+
+// User includes
+#include <memspy/engine/memspyengine.h>
+#include <memspy/engine/memspyengineutils.h>
+#include <memspy/engine/memspyengineoutputsink.h>
+#include <memspy/engine/memspyengineobjectthread.h>
+#include <memspy/engine/memspyengineobjectprocess.h>
+
+// 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<KMaxFileName> path;
+        	TMemSpyDriverCodeSegInfo info;
+        	for (TInt i=0; i<c; i++)
+        		{
+        		r = iEngine.Driver().GetCodeSegInfo(handles[i], aPid, info);
+                //
+        		if  ( r == KErrNone )
+        			{
+        			path.Copy( info.iCreateInfo.iFileName );
+        			aLine.Format(KFmtMod, &aPrefix, info.iMemoryInfo.iCodeBase,info.iMemoryInfo.iCodeBase + info.iMemoryInfo.iCodeSize, &path);
+        			iEngine.Sink().OutputLineL( aLine );
+        			}
+        		}
+            }
+        }
+   }
+
+
+EXPORT_C CMemSpyEngineCodeSegList* CMemSpyEngineHelperCodeSegment::CodeSegmentListL()
+    {
+    RArray<TAny*> 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<TAny*> 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<TAny*> 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<TAny*>& 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<TAny*>& aHandles ) const
+    {
+    CMemSpyEngineCodeSegList* list = CMemSpyEngineCodeSegList::NewLC( iEngine );
+    //
+    TMemSpyDriverCodeSegInfo info;
+    const TInt count = aHandles.Count();
+    //
+    for (TInt i=0; i<count; i++)
+        {
+        TAny* handle = aHandles[ i ];
+        const TInt err = iEngine.Driver().GetCodeSegInfo( handle, 0, info );
+        //
+        if  ( err == KErrNone )
+        	{
+            // Create item
+            CMemSpyEngineCodeSegEntry* entry = CMemSpyEngineCodeSegEntry::NewLC( handle, info.iSize, info.iCreateInfo, info.iMemoryInfo );
+            list->AddItemL( 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<CMemSpyEngineCodeSegEntry>( 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<count; i++)
+        {
+        const CMemSpyEngineCodeSegEntry& entry = At( i );
+        if  ( entry.Handle() == aHandle )
+            {
+            index = i;
+            break;
+            }
+        }
+    //
+    return index;
+    }
+
+
+EXPORT_C void CMemSpyEngineCodeSegList::SortByFileNameL()
+    {
+    TLinearOrder< CMemSpyEngineCodeSegEntry > 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<count; i++)
+        {
+        const CMemSpyEngineCodeSegEntry& entry = At( i );
+        if  ( entry.FileName().FindF( aName ) >= 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<KMaxFullName + 128> 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<KMaxCheckedUid; i++ )
+        {
+        _LIT(KItem1, "\tUid #%d\t\t0x%08x");
+        const TUid uidValue( uids[ i ] );
+        //
+        item.Format( KItem1, i+1, uidValue.iUid );
+        AppendL( item );
+        }
+    //
+    if  ( iCreateInfo.iModuleVersion == KModuleVersionWild )
+        {
+        _LIT(KItem12, "\tModule Version\t\t[Wild]");
+        AppendL( KItem12 );
+        }
+    else if ( iCreateInfo.iModuleVersion == KModuleVersionNull )
+        {
+        _LIT(KItem12, "\tModule Version\t\t[Null]");
+        AppendL( KItem12 );
+        }
+    else
+        {
+        _LIT(KItem12, "\tModule Version\t\t0x%08x");
+        item.Format( KItem12, iCreateInfo.iModuleVersion );
+        AppendL( item );
+        }
+
+    //
+    _LIT(KItem13, "\tSID\t\t0x%08x");
+    item.Format( KItem13, iCreateInfo.iS.iSecureId );
+    AppendL( item );
+
+    //
+    _LIT(KItem14, "\tVID\t\t0x%08x");
+    item.Format( KItem14, iCreateInfo.iS.iVendorId );
+    AppendL( item );
+
+    //
+    if  ( iCreateInfo.iCodeSize > 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; i<SCapabilitySet::ENCapW && !hasCap; i++ )
+        {
+        const TUint32 capsRawValue = iCreateInfo.iS.iCaps[i];
+        const TBitFlags flags( capsRawValue );
+        //
+        hasCap = flags.IsSet( aCapability );
+        }
+    //
+    return hasCap;
+    }
+
+
+EXPORT_C void CMemSpyEngineCodeSegEntry::OutputDataL( CMemSpyEngineHelperCodeSegment& aHelper ) const
+    {
+    _LIT(KHexFormat, "0x%08x");
+
+    HBufC* columns = HBufC::NewLC( 4096 );
+    TPtr pColumns( columns->Des() );
+
+    // 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<KMaxCheckedUid; i++ )
+        {
+        const TUid uidValue( uids[ i ] );
+        //
+        pColumns.AppendFormat( KHexFormat, uidValue.iUid );
+        pColumns.Append( KMemSpyEngineCodeSegListOutputComma );
+        }
+
+    // Module version
+    if  ( iCreateInfo.iModuleVersion == KModuleVersionWild )
+        {
+        _LIT( KCaption, "Wild");
+        pColumns.Append( KCaption );
+        }
+    else if ( iCreateInfo.iModuleVersion == KModuleVersionNull )
+        {
+        _LIT( KCaption, "Null");
+        pColumns.Append( KCaption );
+        }
+    else
+        {
+        pColumns.AppendFormat( KHexFormat, iCreateInfo.iModuleVersion );
+        }
+    pColumns.Append( KMemSpyEngineCodeSegListOutputComma );
+
+    // SID
+    pColumns.AppendFormat( KHexFormat, iCreateInfo.iS.iSecureId );
+    pColumns.Append( KMemSpyEngineCodeSegListOutputComma );
+
+    // VID
+    pColumns.AppendFormat( KHexFormat, iCreateInfo.iS.iVendorId );
+    pColumns.Append( KMemSpyEngineCodeSegListOutputComma );
+
+    // Code size
+    if  ( iCreateInfo.iCodeSize > 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<count; j++ )
+        {
+        const TPtrC capabilityName( (*capabilities)[ j ] );
+        //
+        pColumns.Append( capabilityName );
+        if  ( j < count-1 )
+            {
+            pColumns.Append( KMemSpyEngineCodeSegListOutputComma );
+            }
+        }
+    //
+    CleanupStack::PopAndDestroy( capabilities );
+
+    aHelper.Engine().Sink().OutputLineL( pColumns );
+
+    CleanupStack::PopAndDestroy( columns );
+    }
+
+
+void CMemSpyEngineCodeSegEntry::AddCapabilityItemsL()
+    {
+    _LIT(KCapFormat, "\tCapability #%3d\t\t%S");
+    TBuf<128> item;
+    //
+    CDesCArray* capabilities = CapabilityStringsLC();
+    const TInt count = capabilities->Count();
+    //
+    for( TInt i=0; i<count; i++ )
+        {
+        const TPtrC capabilityName( (*capabilities)[ i ] );
+        item.Format( KCapFormat, i+1, &capabilityName );
+        AppendL( item );
+        }
+    //
+    CleanupStack::PopAndDestroy( capabilities );
+    }
+
+
+CDesCArray* CMemSpyEngineCodeSegEntry::CapabilityStringsLC() const
+    {
+    CDesCArrayFlat* array = new(ELeave) CDesCArrayFlat( ECapability_Limit );
+    CleanupStack::PushL( array );
+    //
+    const TInt KCapabilityCountPer32Bits = 32;
+    //
+    for( TInt i=0; i<SCapabilitySet::ENCapW; i++ )
+        {
+        const TUint32 caps = iCreateInfo.iS.iCaps[i];
+        //
+        AddCapabilitiesL( caps, i * KCapabilityCountPer32Bits, *array );
+        }
+    //
+    return array;
+    }
+
+
+void CMemSpyEngineCodeSegEntry::AddCapabilitiesL( TUint32 aCaps, TInt aCapCount, CDesCArray& aArray ) const
+    {
+    TBitFlags flags( aCaps );
+    TBuf<128> capabilityName;
+    //
+    for( TInt i=aCapCount; i<aCapCount + 32 && i<ECapability_Limit; i++ )
+        {
+        const TBool isSet = flags.IsSet( i );
+        //
+        if  ( isSet )
+            {
+            // Get capability name
+            const TCapability capability = static_cast< TCapability >( i );
+            MemSpyEngineUtils::GetCapabilityName( capabilityName, capability );
+
+            // Make a capability entry for this item
+            aArray.AppendL( capabilityName );
+            }
+        }
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+