diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbolLib/Engines/ROFS/ROFSEngine.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbolLib/Engines/ROFS/ROFSEngine.cs Thu Feb 11 15:50:58 2010 +0200 @@ -0,0 +1,473 @@ +/* +* 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.IO; +using System.Collections; +using System.Collections.Generic; +using SymbolLib.CodeSegDef; +using SymbolLib.Engines.Common; +using SymbolLib.Sources.Map.Engine; +using SymbolLib.Sources.Map.Parser; +using SymbolLib.Sources.Map.File; +using SymbolLib.Sources.Symbol.Engine; +using SymbolLib.Sources.Symbol.Collection; +using SymbolLib.Sources.Symbol.File; +using SymbolLib.Generics; +using SymbianUtils; +using SymbianUtils.Range; +using SymbianUtils.Tracer; + +namespace SymbolLib.Engines.ROFS +{ + public class ROFSEngine : SymbolEngineBase + { + #region Constructors + internal ROFSEngine( ITracer aTracer ) + : base( aTracer ) + { + iEngineMap = new MapFileEngineCollection( this ); + iEngineMap.Observer += new SymbianUtils.AsyncReaderBase.Observer( MapEngine_Observer ); + + iEngineSymbol = new SymbolFileEngineCollection( this, SymbolFileEngine.TActivationType.EOnDemand, true ); + iEngineSymbol.Observer += new SymbianUtils.AsyncReaderBase.Observer( SymbolEngine_Observer ); + } + #endregion + + #region API + public static TFileType IsSupported( string aFileName ) + { + TFileType ret = TFileType.EFileNotSupported; + // + try + { + string extension = Path.GetExtension( aFileName ).ToLower(); + if ( extension == ".symbol" ) + { + bool sawSomeValidContent = false; + // + SymbolFileEngine tempEngine = new SymbolFileEngine(null, SymbolFileEngine.TActivationType.EOnDemand, true ); + SymbolsForBinary symbols = tempEngine.ReadFirstCollection( aFileName, out sawSomeValidContent ); + + // For a valid ROFS symbol file, the first symbol should have an address of zero. + bool valid = ( symbols != null && symbols.Count > 0 && symbols[ 0 ].Address == 0 ); + if ( valid ) + { + ret = TFileType.EFileRofsSymbol; + } + else if ( sawSomeValidContent ) + { + // Probably just a file containing data files rather than code, but that's okay. + ret = TFileType.EFileRofsSymbol; + } + } + else if ( extension == ".map" ) + { + ret = MapFileEngineCollection.IsSupported( aFileName ); + } + } + catch(Exception) + { + } + // + return ret; + } + #endregion + + #region Properties + public CodeSegDefinitionParser DefinitionParser + { + get { return iEngineMap.CodeSegParser; } + } + + public CodeSegResolver DefinitionResolver + { + get { return iEngineMap.CodeSegResolver; } + } + + public SymbolFileEngineCollection SymbolFiles + { + get { return iEngineSymbol; } + } + + public string[] SymbolFileNames + { + get + { + string[] ret = iEngineSymbol.SymbolFileNames; + return ret; + } + } + + public string[] SymbolFileCollectionFileNames + { + get + { + string[] ret = iEngineSymbol.BinaryFileNames; + return ret; + } + } + + public List MapFileNames + { + get + { + List ret = new List(); + lock ( iEngineMap ) + { + ret.AddRange( iEngineMap.MapFileNames ); + } + return ret; + } + } + #endregion + + #region From SymbolEngineBase + public override bool AddressInRange( long aAddress ) + { + // Try map files first, then symbols (should be + // quicker this way). + bool ret = false; + lock ( iEngineMap ) + { + ret = iEngineMap.Range.Contains( aAddress ); + } + if ( ret == false ) + { + lock ( iEngineSymbol ) + { + ret = iEngineSymbol.Range.Contains( aAddress ); + } + } + // + return ret; + } + + public override int FileNameCount + { + get + { + int count = 0; + // + lock ( iEngineSymbol ) + { + count += iEngineSymbol.SymbolFileCount; + } + lock ( iEngineMap ) + { + count += iEngineMap.NumberOfCollections; + } + // + return count; + } + } + + public override string FileName( int aIndex ) + { + string ret = string.Empty; + // + lock ( iEngineMap ) + { + lock ( iEngineSymbol ) + { + int countSymbolFiles = iEngineSymbol.SymbolFileCount; + int countMapFiles = iEngineMap.NumberOfCollections; + // + if ( aIndex < countSymbolFiles ) + { + ret = iEngineSymbol.SymbolFileName( aIndex ); + } + else + { + // Must be a map index + aIndex -= countSymbolFiles; + // + if ( aIndex >= 0 && aIndex < iEngineMap.NumberOfCollections ) + { + ret = iEngineMap.MapFileName( aIndex ); + } + } + } + } + // + return ret; + } + + public override void LoadFromFile( string aFileName, TSynchronicity aSynchronicity ) + { + if ( SymbolFileEngine.IsSymbolFile( aFileName ) ) + { + iEngineSymbol.LoadFromFile( aFileName, aSynchronicity ); + } + else if ( MapFileEngine.IsMapFile( aFileName ) ) + { + iEngineMap.LoadFromFile( aFileName, aSynchronicity ); + } + else + { + throw new NotSupportedException(); + } + } + + public override bool LoadFromDefinition( CodeSegDefinition aDefinition, TSynchronicity aSynchronicity ) + { + // Try Symbol file first + bool wasActivated = false; + + lock ( this ) + { + wasActivated = iEngineSymbol.Load( aDefinition ); + if ( wasActivated == false ) + { + wasActivated = iEngineMap.Load( aDefinition, aSynchronicity ); + } + } + + return wasActivated; + } + + public override void UnloadAll() + { + lock ( iEngineMap ) + { + iEngineMap.UnloadAll(); + } + lock ( iEngineSymbol ) + { + iEngineSymbol.UnloadAll(); + } + } + + public override bool Unload( CodeSegDefinition aDefinition ) + { + bool ret = false; + lock ( this ) + { + ret = iEngineMap.Unload( aDefinition ); + + // Try with the Symbol engine if it wasn't a loaded map codeseg + if ( ret == false ) + { + ret = iEngineSymbol.Unload( aDefinition ); + } + } + + return ret; + } + + public override bool IsLoaded( CodeSegDefinition aDefinition ) + { + bool ret = false; + lock ( iEngineMap ) + { + ret = iEngineMap.IsLoaded( aDefinition ); + } + if ( ret == false ) + { + // Try with the Symbol engine if it wasn't a loaded map codeseg + lock( iEngineSymbol ) + { + ret = iEngineSymbol.IsLoaded( aDefinition ); + } + } + + return ret; + } + #endregion + + #region From GenericSymbolEngine + public override bool IsReady + { + get + { + bool mapReady = false; + lock( iEngineMap ) + { + mapReady = iEngineMap.IsReady; + } + // + bool symbolReady = false; + lock ( iEngineSymbol ) + { + symbolReady = iEngineSymbol.IsReady; + } + // + bool ret = ( mapReady && symbolReady ); + return ret; + } + } + + public override void Reset() + { + lock ( iEngineMap ) + { + iEngineMap.Reset(); + } + lock( iEngineSymbol ) + { + iEngineSymbol.Reset(); + } + } + + public override bool IsLoaded( string aFileName ) + { + bool loaded = false; + lock ( iEngineMap ) + { + loaded = iEngineMap.IsLoaded( aFileName ); + } + if ( loaded == false ) + { + lock ( iEngineSymbol ) + { + loaded = iEngineSymbol.IsLoaded( aFileName ); + } + } + // + return loaded; + } + + public override GenericSymbolCollection this[ int aIndex ] + { + get + { + GenericSymbolCollection ret = null; + // + lock ( iEngineMap ) + { + lock ( iEngineSymbol ) + { + int mapCount = iEngineMap.NumberOfCollections; + if ( aIndex >= 0 && aIndex < mapCount ) + { + ret = iEngineMap[ aIndex ]; + } + else + { + int symbolBaseIndex = ( aIndex - mapCount ); + int symbolCount = iEngineSymbol.NumberOfCollections; + if ( symbolBaseIndex >= 0 && symbolBaseIndex < symbolCount ) + { + ret = iEngineSymbol[ symbolBaseIndex ]; + } + } + } + } + // + return ret; + } + } + + public override AddressRange Range + { + get + { + AddressRange ret = new AddressRange(); + // + lock ( iEngineMap ) + { + ret.Update( iEngineMap.Range ); + } + lock ( iEngineSymbol ) + { + ret.Update( iEngineSymbol.Range ); + } + // + return ret; + } + } + + internal override void UnloadUntagged() + { + + } + #endregion + + #region From IGenericSymbolCollectionStatisticsInterface + public override int NumberOfCollections + { + get + { + int count = 0; + // + lock ( iEngineMap ) + { + count += iEngineMap.NumberOfCollections; + } + lock ( iEngineSymbol ) + { + count += iEngineSymbol.NumberOfCollections; + } + // + return count; + } + } + #endregion + + #region Event handlers + private void MapEngine_Observer( SymbianUtils.AsyncReaderBase.TEvent aEvent, SymbianUtils.AsyncReaderBase aSender ) + { + System.Diagnostics.Debug.Assert( aSender.Tag is MapFileEngine ); + MapFileEngine engine = (MapFileEngine) aSender.Tag; + // + switch( aEvent ) + { + case SymbianUtils.AsyncReaderBase.TEvent.EReadingStarted: + OnParsingStarted( engine.MapFileName ); + break; + case SymbianUtils.AsyncReaderBase.TEvent.EReadingProgress: + OnParsingProgress( engine.MapFileName, aSender.Progress ); + break; + case SymbianUtils.AsyncReaderBase.TEvent.EReadingComplete: + OnParsingCompleted( engine.MapFileName ); + break; + } + } + + private void MapEngine_MapLoaded( CodeSegDefinition aLoadedEntry, MapFile aMapFile ) + { + OnCollectionCreated( aMapFile ); + } + + private void SymbolEngine_Observer( SymbianUtils.AsyncReaderBase.TEvent aEvent, SymbianUtils.AsyncReaderBase aSender ) + { + System.Diagnostics.Debug.Assert( aSender.Tag is SymbolFileEngine ); + SymbolFileEngine engine = (SymbolFileEngine) aSender.Tag; + // + switch( aEvent ) + { + case SymbianUtils.AsyncReaderBase.TEvent.EReadingStarted: + OnParsingStarted( engine.SymbolFileName ); + break; + case SymbianUtils.AsyncReaderBase.TEvent.EReadingProgress: + OnParsingProgress( engine.SymbolFileName, aSender.Progress ); + break; + case SymbianUtils.AsyncReaderBase.TEvent.EReadingComplete: + OnParsingCompleted( engine.SymbolFileName ); + break; + } + } + #endregion + + #region Internal methods + #endregion + + #region Data members + private readonly MapFileEngineCollection iEngineMap; + private readonly SymbolFileEngineCollection iEngineSymbol; + #endregion + } +}