crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianETMLib/Common/State/Data/ETMStateData.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianETMLib/Common/State/Data/ETMStateData.cs Thu Feb 11 15:50:58 2010 +0200
@@ -0,0 +1,319 @@
+/*
+* 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.Generic;
+using System.Text;
+using SymbianUtils.Tracer;
+using SymbianUtils.BasicTypes;
+using SymbianStructuresLib.Arm;
+using SymbianStructuresLib.Arm.Exceptions;
+using SymbianStructuresLib.Arm.SecurityMode;
+using SymbianStructuresLib.Arm.Instructions;
+using SymbianStructuresLib.Debug.Code;
+using SymbianDebugLib.PluginAPI.Types;
+using SymbianDebugLib.PluginAPI.Types.Code;
+using SymbianETMLib.Common.Types;
+using SymbianETMLib.Common.Buffer;
+using SymbianETMLib.Common.Engine;
+using SymbianETMLib.Common.Config;
+using SymbianETMLib.Common.Utilities;
+
+namespace SymbianETMLib.Common.State
+{
+ public class ETMStateData : ITracer
+ {
+ #region Constructors
+ internal ETMStateData( ETEngineBase aEngine )
+ {
+ iEngine = aEngine;
+ iCurrentState = new ETMDecodeStateUnsynchronized( this );
+ }
+ #endregion
+
+ #region API
+ internal void PushBack( SymByte aByte )
+ {
+ Buffer.PushBack( aByte );
+ iCurrentRawByte = iLastRawByte;
+ --iPacketNumber;
+ }
+
+ internal void PrepareToHandleByte( SymByte aByte )
+ {
+ iLastRawByte = iCurrentRawByte;
+ iCurrentRawByte = aByte;
+ //
+ iCurrentState = iCurrentState.PrepareToHandleByte( aByte );
+ System.Diagnostics.Debug.Assert( iCurrentState != null );
+ //
+ ++iPacketNumber;
+ }
+
+ internal void IncrementProcessedInstructionCounter()
+ {
+ ++iNumberOfProcessedInstructions;
+ }
+
+ internal uint IncrementPC()
+ {
+ if ( !iLastBranch.IsUnknown )
+ {
+ uint instructionSize = (uint) CurrentInstructionSet;
+ iPC.Address += instructionSize;
+ }
+
+ // Increment the instruction counter irrespective of whether or not we
+ // know the program counter address
+ IncrementProcessedInstructionCounter();
+ return iPC;
+ }
+
+ internal ETMInstruction FetchInstruction( uint aAddress )
+ {
+ ETMInstruction ret = new ETMInstruction( aAddress );
+ //
+ bool gotCode = false;
+ if ( this.LastBranch.IsKnown && Engine.DebugEngineView != null )
+ {
+ DbgViewCode codeView = Engine.DebugEngineView.Code;
+
+ // In the case where we've been asked to fetch the code from the exception
+ // vector, then bypass the rom/rofs code entirely.
+ bool isExceptionVector = Config.IsExceptionVector( aAddress );
+ if ( isExceptionVector )
+ {
+ System.Diagnostics.Debug.Assert( this.CurrentInstructionSet == TArmInstructionSet.EARM );
+ TArmExceptionVector vector = Config.MapToExceptionVector( aAddress );
+ uint rawInstruction = Config.GetExceptionVector( vector );
+ ret.Instruction = codeView.ConvertToInstruction( aAddress, TArmInstructionSet.EARM, rawInstruction );
+ }
+ else
+ {
+ IArmInstruction[] instructions = null;
+ gotCode = codeView.GetInstructions( aAddress, CurrentInstructionSet, 1, out instructions );
+ //
+ if ( gotCode )
+ {
+ System.Diagnostics.Debug.Assert( instructions != null && instructions.Length == 1 );
+ ret.Instruction = instructions[ 0 ];
+ }
+ }
+ }
+ //
+ return ret;
+ }
+
+ internal void SetUnsynchronized()
+ {
+ iSynchronized = false;
+ }
+
+ internal void SetSynchronized()
+ {
+ if ( !iSynchronized )
+ {
+ uint pos = iPacketNumber;
+ iEngine.OnSynchronised( pos );
+ iSynchronized = true;
+ }
+ }
+
+ // <summary>
+ // Set the known address bits of the program counter. We may not know all
+ // bits until an I-sync packet is reached, or then until we see a full 5-byte
+ // branch.
+ // </summary>
+ internal void SetKnownAddressBits( uint aAddress, int aNumberOfValidBits, TETMBranchType aBranchType )
+ {
+ iLastBranch.SetKnownAddressBits( aAddress, aNumberOfValidBits );
+
+ iPC.Address = iLastBranch.Address;
+ iPC.KnownBits = iLastBranch.KnownBits;
+
+ // If we know the full branch address, then inform the engine
+ if ( iPC.IsKnown )
+ {
+ iEngine.OnBranch( iPC, iCurrentInstructionSet, iCurrentException, aBranchType );
+ }
+ }
+
+ internal void SetPC( uint aAddress )
+ {
+ SetPC( aAddress, this.CurrentInstructionSet );
+ }
+
+ internal void SetPC( uint aAddress, TArmInstructionSet aInstructionSet )
+ {
+ iPC.Address = aAddress;
+ iCurrentInstructionSet = aInstructionSet;
+
+ // If BBC mode is enabled, i.e. branches are output even when a direct branch is taken
+ // then we don't need to emit a branch event when seeing a 'Direct' branch type.
+ bool isBBCModeEnabled = Config.BBCModeEnabled;
+ if ( isBBCModeEnabled == false && iPC.IsKnown )
+ {
+ iEngine.OnBranch( iPC, iCurrentInstructionSet, iCurrentException, TETMBranchType.EBranchDirect );
+ }
+ }
+
+ internal void SetContextID( uint aValue )
+ {
+ // Tidy up the raw value.
+ uint id = ( aValue >> 2 );
+ if ( iCurrentContextId != id )
+ {
+ iCurrentContextId = id;
+ iEngine.OnContextSwitch( iCurrentContextId );
+ }
+ }
+ #endregion
+
+ #region Properties
+ public uint PacketNumber
+ {
+ get { return iPacketNumber; }
+ }
+
+ public int NumberOfProcessedInstructions
+ {
+ get { return iNumberOfProcessedInstructions; }
+ }
+
+ public SymByte CurrentByte
+ {
+ get { return iCurrentRawByte; }
+ }
+
+ public SymByte LastByte
+ {
+ get { return iLastRawByte; }
+ }
+
+ public ETMDecodeState CurrentState
+ {
+ get { return iCurrentState; }
+ }
+
+ public TArmExceptionType CurrentException
+ {
+ get { return iCurrentException; }
+ set
+ {
+ if ( iCurrentException != value )
+ {
+ iCurrentException = value;
+ Engine.OnExceptionModeChange( iCurrentException );
+ }
+ }
+ }
+
+ public TArmSecurityMode CurrentSecurityMode
+ {
+ get { return iCurrentSecurityMode; }
+ set
+ {
+ if ( iCurrentSecurityMode != value )
+ {
+ iCurrentSecurityMode = value;
+ Engine.OnExceptionModeChange( iCurrentException );
+ }
+ }
+ }
+
+ public TArmInstructionSet CurrentInstructionSet
+ {
+ get { return iCurrentInstructionSet; }
+ set
+ {
+ if ( iCurrentInstructionSet != value )
+ {
+ iCurrentInstructionSet = value;
+ }
+ }
+ }
+ #endregion
+
+ #region Internal properties
+ internal SymAddress CurrentAddress
+ {
+ get { return iPC; }
+ }
+
+ internal SymAddressWithKnownBits LastBranch
+ {
+ get { return iLastBranch; }
+ }
+
+ internal ETEngineBase Engine
+ {
+ get { return iEngine; }
+ }
+
+ internal ETMInstruction LastInstruction
+ {
+ get { return iLastInstruction; }
+ set { iLastInstruction = value; }
+ }
+
+ internal ETConfigBase Config
+ {
+ get { return iEngine.Config; }
+ }
+
+ private ETBufferBase Buffer
+ {
+ get { return iEngine.Buffer; }
+ }
+ #endregion
+
+ #region Internal constants
+ #endregion
+
+ #region From ITracer
+ public void Trace( string aText )
+ {
+ iEngine.Trace( aText );
+ }
+
+ public void Trace( string aFormat, params object[] aParams )
+ {
+ iEngine.Trace( aFormat, aParams );
+ }
+ #endregion
+
+ #region From System.Object
+ #endregion
+
+ #region Data members
+ private readonly ETEngineBase iEngine;
+ private bool iSynchronized = false;
+ private int iNumberOfProcessedInstructions = 0;
+ private uint iPacketNumber = 0;
+ private uint iCurrentContextId = uint.MaxValue;
+ private ETMInstruction iLastInstruction = new ETMInstruction();
+ private SymAddressWithKnownBits iLastBranch = new SymAddressWithKnownBits();
+ private SymAddressWithKnownBits iPC = new SymAddressWithKnownBits();
+ private SymByte iCurrentRawByte = 0;
+ private SymByte iLastRawByte = 0;
+ private ETMDecodeState iCurrentState = null;
+ private TArmExceptionType iCurrentException = TArmExceptionType.EUnknown;
+ private TArmSecurityMode iCurrentSecurityMode = TArmSecurityMode.EUnknown;
+ private TArmInstructionSet iCurrentInstructionSet = TArmInstructionSet.EARM;
+ #endregion
+ }
+}