diff -r 000000000000 -r 818e61de6cd1 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; + } + } + + // + // 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. + // + 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 + } +}