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<string> MapFileNames
+ {
+ get
+ {
+ List<string> ret = new List<string>();
+ 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
+ }
+}