crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbolLib/Sources/Map/Parser/MapFileParser.cs
author Matti Laitinen <matti.t.laitinen@nokia.com>
Thu, 11 Feb 2010 15:50:58 +0200
changeset 0 818e61de6cd1
permissions -rw-r--r--
Add initial version of Crash Analyser cmdline under EPL

/*
* 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.Collections;
using System.IO;
using SymbianUtils;
using SymbianUtils.Tracer;
using SymbolLib.Generics;
using SymbolLib.Sources.Map.File;
using SymbolLib.Sources.Map.Symbol;
using SymbolLib.Sources.Map.Engine;

namespace SymbolLib.Sources.Map.Parser
{
    #region SymbolEntryCreator interface
    internal interface SymbolEntryCreator
    {
        MapSymbol CreateSymbol();
    }
    #endregion

    internal class MapFileParser : AsyncTextFileReader
	{
        #region Delegates & events
        public delegate void SymbolCreatedHandler( MapSymbol aSymbol );
        public event SymbolCreatedHandler SymbolCreated;

        public delegate void MapFileBaseAddressHandler( uint aBaseAddress );
        public event MapFileBaseAddressHandler BaseAddressHandler;
        #endregion

        #region Constructors & destructor
        public MapFileParser( SymbolEntryCreator aEntryCreator, string aMapFileName, ITracer aTracer )
        :   base( aMapFileName, aTracer )
		{
            iEntryCreator = aEntryCreator;
		}
		#endregion

        #region API
        public void Read( TSynchronicity aSynchronicity )
        {
            base.StartRead( aSynchronicity );
        }
        #endregion

        #region Properties
		#endregion

		#region From AsyncTextReaderBase
		protected override void HandleFilteredLine( string aLine )
		{
			if	( aLine == "Global Symbols" )
			{
				iState = TState.EInGlobalRegion;
			}
			else if ( aLine == "Local Symbols" )
			{
				iState = TState.EInLocalRegion;
			}
			else
			{
				switch( iState )
				{
				case TState.EInUnknownRegion:
					break;
				case TState.EInLocalRegion:
					ParseLineRegionLocal( aLine );
					break;
				case TState.EInGlobalRegion:
					ParseLineRegionGlobal( aLine );
					break;
				case TState.EComplete:
					System.Diagnostics.Debug.Assert(false);
					break;
				}
			}
		}
		#endregion

		#region Local & global (high level) line handlers
		private void ParseLineRegionLocal( string aLine )
		{
		}

		private void ParseLineRegionGlobal( string aLine )
		{
			switch( iStateGlobal )
			{
			case TGlobalState.EWaitingForImage_ER_RO_Base:
                ParseGlobalBaseAddress( aLine );
				break;
			case TGlobalState.EProcessingSymbols:
				ParseGlobalSymbol( aLine );
				break;
			default:
				break;
			}
		}
		#endregion

		#region Global section line parse methods
		private void ParseGlobalBaseAddress( string aLine )
		{
			try
			{
				// Image$$ER_RO$$Base                       0x00008000   Number         0  anon$$obj.o(linker$$defined$$symbols)
                MapSymbol baseOffsetEntry = iEntryCreator.CreateSymbol();

                // Keep trying to parse until we are successful. First time we succeed
                // we use the symbol address as the global offset address within the map
                // file (typically 0x8000)
                bool parsedOkay = baseOffsetEntry.Parse( aLine );
                if ( parsedOkay && baseOffsetEntry.Address > 0 && BaseAddressHandler != null )
                {
                    BaseAddressHandler( (uint) baseOffsetEntry.Address );
                    iStateGlobal = TGlobalState.EProcessingSymbols;
                }
			}
			catch(GenericSymbolicCreationException)
			{
			}
		}

		private void ParseGlobalSymbol( string aLine )
		{
			try
			{
				// Image$$ER_RO$$Base                       0x00008000   Number         0  anon$$obj.o(linker$$defined$$symbols)
                MapSymbol symbol = iEntryCreator.CreateSymbol();
				bool parsedOkay = symbol.Parse( aLine );
                if ( parsedOkay && SymbolCreated != null )
				{
                    SymbolCreated( symbol );
				}
			}
			catch(GenericSymbolicCreationException)
			{
			}
		}
		#endregion

		#region Internal enumerations
		private enum TState
		{
			EInUnknownRegion = 0,
			EInLocalRegion,
			EInGlobalRegion,
			EComplete
		}

		private enum TGlobalState
		{
			EWaitingForImage_ER_RO_Base = 0,
			EProcessingSymbols
		}
		#endregion

		#region Data members
		private readonly SymbolEntryCreator iEntryCreator;
		private TState iState = TState.EInUnknownRegion;
		private TGlobalState iStateGlobal = TGlobalState.EWaitingForImage_ER_RO_Base;
		#endregion
	}
}