diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbolLib/Sources/Map/Engine/MapFileEngine.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbolLib/Sources/Map/Engine/MapFileEngine.cs Thu Feb 11 15:50:58 2010 +0200 @@ -0,0 +1,236 @@ +/* +* 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: +* +*/ +using System; +using System.Text; +using System.IO; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using SymbolLib.CodeSegDef; +using SymbolLib.Generics; +using SymbolLib.Engines; +using SymbolLib.Sources.Map.File; +using SymbolLib.Sources.Map.Parser; +using SymbolLib.Sources.Map.Symbol; +using SymbianUtils; +using SymbianUtils.Range; +using SymbianUtils.Tracer; + +namespace SymbolLib.Sources.Map.Engine +{ + internal class MapFileEngine : GenericSymbolEngine, SymbolEntryCreator + { + #region Events + public event AsyncReaderBase.Observer Observer; + #endregion + + #region Constructor & destructor + public MapFileEngine( ITracer aTracer ) + : base( aTracer ) + { + } + #endregion + + #region API + public static bool IsMapFile( string aFileName ) + { + string extension = Path.GetExtension( aFileName ).ToLower(); + return ( extension == CodeSegDefinition.KMapFileExtension ); + } + + internal bool IsLoaded( CodeSegDefinition aDefinition ) + { + bool ret = iMapFile.HostBinaryFileName == aDefinition.ImageFileNameAndPath; + return ret; + } + + internal void LoadFromFile( string aMapFileName, TSynchronicity aSynchronicity ) + { + iMapFileName = aMapFileName; + iMapFile = MapFile.NewByHostMapFileName( aMapFileName ); + // + iParser = new MapFileParser( this, aMapFileName, this ); + iParser.Tag = this; + iParser.iObserver += new SymbianUtils.AsyncReaderBase.Observer( Parser_Observer ); + iParser.SymbolCreated += new MapFileParser.SymbolCreatedHandler( Parser_SymbolCreated ); + iParser.BaseAddressHandler += new MapFileParser.MapFileBaseAddressHandler( Parser_BaseAddressHandler ); + iParser.Read( aSynchronicity ); + } + + internal void Load( CodeSegDefinition aDefinition ) + { + iMapFile.Fixup( aDefinition ); + } + + internal bool Unload( CodeSegDefinition aDefinition ) + { + return true; + } + + internal void UnloadAll() + { + } + #endregion + + #region Properties + public MapFile MapFile + { + get { return iMapFile; } + } + + public string MapFileName + { + get { return iMapFileName; } + } + #endregion + + #region From GenericSymbolEngine + public override void Reset() + { + // Do nothing - we cannot unload our only file. This is taken + // care of by parent class. + iMapFile = null; + iParser = null; + iMapFileName = string.Empty; + } + + public override bool IsReady + { + get + { + return true; + } + } + + public override bool IsLoaded( string aFileName ) + { + bool ret = MapFileName == aFileName; + return ret; + } + + public override GenericSymbolCollection this[ int aIndex ] + { + get + { + return iMapFile; + } + } + + public override AddressRange Range + { + get + { + return iMapFile.AddressRange; + } + } + + internal override void UnloadUntagged() + { + + } + #endregion + + #region From IGenericSymbolCollectionStatisticsInterface + public override int NumberOfCollections + { + get + { + return 1; + } + } + #endregion + + #region From SymbolEntryCreator + public MapSymbol CreateSymbol() + { + return MapSymbol.New( iMapFile ); + } + #endregion + + #region Map file parser observer + private void Parser_Observer( SymbianUtils.AsyncReaderBase.TEvent aEvent, SymbianUtils.AsyncReaderBase aSender ) + { + if ( Observer != null ) + { + Observer( aEvent, aSender ); + } + + if ( aEvent == SymbianUtils.AsyncReaderBase.TEvent.EReadingComplete ) + { + iMapFile.EnsureAllEntriesHaveSize(); + iMapFile.Sort(); + + int x = 0; + if ( x != 0 ) + { + iMapFile.Dump(); + } + + iParser = null; + } + } + + private void Parser_SymbolCreated( MapSymbol aSymbol ) + { + bool addItem = true; + + if ( iMapFile.Count > 0 ) + { + int lastEntryIndex = iMapFile.Count - 1; + MapSymbol lastEntry = (MapSymbol) iMapFile[ lastEntryIndex ]; + // + long lastEntrySize = lastEntry.Size; + long newEntrySize = aSymbol.Size; + // + if ( lastEntry.Address == aSymbol.Address ) + { + if ( lastEntrySize == 0 && newEntrySize > 0 ) + { + // Remove an entry with zero size to replace it with a better definition... + iMapFile.RemoveAt( lastEntryIndex ); + } + else if ( newEntrySize == 0 && lastEntrySize > 0 ) + { + // Don't replace an entry with zero size when we already + // have a good item. + addItem = false; + } + } + } + + if ( addItem ) + { + iMapFile.Add( this, aSymbol ); + } + } + + private void Parser_BaseAddressHandler( uint aBaseAddress ) + { + iMapFile.GlobalBaseAddress = aBaseAddress; + } + #endregion + + #region Internal methods + #endregion + + #region Data members + private MapFile iMapFile = null; + private MapFileParser iParser = null; + private string iMapFileName = string.Empty; + #endregion + } +}