crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianETMLib/Common/BranchDecoder/ETMBranchDecoder.cs
changeset 0 818e61de6cd1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianETMLib/Common/BranchDecoder/ETMBranchDecoder.cs	Thu Feb 11 15:50:58 2010 +0200
@@ -0,0 +1,351 @@
+/*
+* 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 SymbianETMLib.Common.Types;
+using SymbianETMLib.Common.State;
+using SymbianETMLib.Common.Config;
+
+namespace SymbianETMLib.Common.BranchDecoder
+{
+    internal abstract class ETMBranchDecoder : ITracer
+    {
+        #region Factory
+        public static ETMBranchDecoder New( ETMStateData aStateData )
+        {
+            ETMBranchDecoder ret = null;
+            //
+            switch ( aStateData.Config.BranchCompressionScheme )
+            {
+            default:
+            case TETMBranchCompressionScheme.EOriginal:
+                ret = new ETMBranchDecoderOriginal( aStateData );
+                break;
+            case TETMBranchCompressionScheme.EAlternative:
+                ret = new ETMBranchDecoderAlternative( aStateData );
+                break;
+            }
+            //
+            return ret;
+        }
+        #endregion
+
+        #region Constructors
+        protected ETMBranchDecoder( ETMStateData aStateData )
+        {
+            iStateData = aStateData;
+            iInstructionSet = aStateData.CurrentInstructionSet;
+        }
+        #endregion
+
+        #region API
+        public void FlushChanges()
+        {
+            TArmInstructionSet originalInstructionSet = iStateData.CurrentInstructionSet;
+            SymAddress originalAddress = new SymAddress( iStateData.CurrentAddress.Address );
+
+            //if ( !IsLastInstructionCancelled )
+            {
+                // Set known address
+                iStateData.SetKnownAddressBits( iBranchAddress.Address,
+                                              iBranchAddress.KnownBits,
+                                              TETMBranchType.EBranchExplicit );
+
+                // Handle a change in security mode
+                if ( iSecurityMode != TArmSecurityMode.EUnknown )
+                {
+                    iStateData.CurrentSecurityMode = iSecurityMode;
+                }
+
+                if ( iExceptionType != TArmExceptionType.EUnknown )
+                {
+                    iStateData.CurrentException = iExceptionType;
+                }
+
+                // Handle a change in instruction set
+                if ( iStateData.CurrentInstructionSet != iInstructionSet )
+                {
+                    iStateData.CurrentInstructionSet = iInstructionSet;
+                }
+            }
+
+            DbgTrace( originalAddress, originalInstructionSet );
+        }
+
+        public void DecodeBranch()
+        {
+            System.Diagnostics.Debug.Assert( IsBranchAddressAvailable );
+            System.Diagnostics.Debug.Assert( Count > 0 && Count <= 5 );
+            //
+            if ( Count == 5 )
+            {
+                DecodeFull();
+            }
+            else
+            {
+                DecodePartial();
+            }
+        }
+        #endregion
+
+        #region Framework API
+        public abstract void Offer( SymByte aByte );
+
+        public abstract void DecodeException( SymByte aByte );
+
+        protected abstract void DecodeFull();
+
+        protected abstract void DecodePartial();
+
+        public virtual bool IsPacketComplete
+        {
+            get
+            {
+                // If the 7th bit is clear, then this might be
+                // the last byte.
+                //
+                // If:
+                //
+                // a) the number of bytes forming the branch packet
+                //    is less than 5, then this is the last byte.
+                //
+                // b) the number of bytes forming the branch packet
+                //    is 5, and
+                //    i)  bit 6 is clear => normal branch, this is the last byte
+                //    ii) bit 7 is set => inline exception, but this is still the last byte.
+                //
+                bool ret = false;
+                bool bit7 = LastByte[ 7 ];
+                //
+                switch ( iBytes.Count )
+                {
+                default:
+                case 0:
+                    ret = false;
+                    break;
+                case 1:
+                case 2:
+                case 3:
+                case 4:
+                    ret = ( bit7 == false ); // (a)
+                    break;
+                case 5:
+                    if ( bit7 )
+                    {
+                        // (b), part (ii)
+                        ret = true;
+                    }
+                    else
+                    {
+                        // (b), part (i) - i.e. bit 6 and 7 are both clear => normal branch byte
+                        ret = ( LastByte[ 6 ] == false );
+                    }
+                    break;
+                }
+                return ret;
+            }
+        }
+
+        public virtual bool IsBranchAddressAvailable
+        {
+            get
+            {
+                // The branch address is only available once 
+                // bit seven is clear, or then once we've reached
+                // an entire run of 5 bytes.
+                bool ret = false;
+                //
+                if ( Count == 5 )
+                {
+                    ret = true;
+                }
+                else
+                {
+                    ret = ( LastByte[ 7 ] == false );
+                }
+                //
+                return ret;
+            }
+        }
+        #endregion
+
+        #region Internal API
+        protected void Save( SymByte aByte )
+        {
+            iBytes.Add( aByte );
+        }
+        #endregion
+
+        #region Properties
+        public int Count
+        {
+            get { return iBytes.Count; }
+        }
+
+        public bool IsLastInstructionCancelled
+        {
+            get { return iLastInstructionCancelled; }
+            protected set { iLastInstructionCancelled = value; }
+        }
+
+        public SymByte this[ int aIndex ]
+        {
+            get { return iBytes[ aIndex ]; }
+        }
+
+        public ETConfigBase Config
+        {
+            get { return iStateData.Config; }
+        }
+
+        public TArmExceptionType ExceptionType
+        {
+            get { return iExceptionType; }
+            protected set { iExceptionType = value; }
+        }
+
+        public TArmSecurityMode SecurityMode
+        {
+            get { return iSecurityMode; }
+            protected set { iSecurityMode = value; }
+        }
+
+        public TArmInstructionSet InstructionSet
+        {
+            get { return iInstructionSet; }
+            protected set { iInstructionSet = value; }
+        }
+
+        public SymAddressWithKnownBits BranchAddress
+        {
+            get { return iBranchAddress; }
+            protected set { iBranchAddress = value; }
+        }
+        #endregion
+
+        #region Internal methods
+        protected SymByte LastByte
+        {
+            get
+            {
+                SymByte ret = new SymByte( 0 );
+                //
+                int count = iBytes.Count;
+                if ( count > 0 )
+                {
+                    ret = iBytes[ count - 1 ];
+                }
+                //
+                return ret;
+            }
+        }
+
+        protected static int CompressionLeftShiftCount( TArmInstructionSet aIS )
+        {
+            int ret = 2;
+
+            // Interpret the bytes to form an address based upon current
+            // instruction set.
+            switch ( aIS )
+            {
+            default:
+            case TArmInstructionSet.EARM:
+                break;
+            case TArmInstructionSet.ETHUMB:
+                ret = 1;
+                break;
+            case TArmInstructionSet.EJAZELLE:
+                ret = 0;
+                break;
+            }
+            //
+            return ret;
+        }
+
+        private void DbgTrace( SymAddress aOriginalAddress, TArmInstructionSet aOriginalISet )
+        {
+            if ( Count == 5 )
+            {
+                DbgTrace( "BRANCH-F", aOriginalAddress, aOriginalISet );
+            }
+            else
+            {
+                DbgTrace( "BRANCH-P", aOriginalAddress, aOriginalISet );
+            }
+        }
+
+        private void DbgTrace( string aType, SymAddress aOriginalAddress, TArmInstructionSet aOriginalISet )
+        {
+            StringBuilder lines = new StringBuilder();
+            lines.AppendLine( "   " + aType );
+            //
+            if ( iStateData.LastBranch.IsKnown )
+            {
+                lines.AppendLine( string.Format( "      using: {0} 0x{1} to go...",
+                    iBranchAddress.AddressBinary,
+                    iBranchAddress.AddressHex )
+                    );
+                lines.AppendLine( string.Format( "       from: {0} 0x{1} {2} 0x{3:x8} {4}", 
+                    aOriginalAddress.AddressBinary,
+                    aOriginalAddress.AddressHex,
+                    ETMDecodeState.MakeInstructionSetPrefix( aOriginalISet ),
+                    aOriginalAddress,
+                    iStateData.Engine.LookUpSymbol( aOriginalAddress ) ) 
+                    );
+                lines.AppendLine( string.Format( "         to: {0} 0x{1} {2} 0x{3:x8} {4}", 
+                    iStateData.CurrentAddress.AddressBinary,
+                    iStateData.CurrentAddress.AddressHex,
+                    ETMDecodeState.MakeInstructionSetPrefix( iStateData.CurrentInstructionSet ),
+                    iStateData.CurrentAddress, 
+                    iStateData.Engine.LookUpSymbol( iStateData.CurrentAddress ) ) 
+                    );
+            }
+            //
+            Trace( lines.ToString() );
+        }
+        #endregion
+
+        #region From ITracer
+        public void Trace( string aText )
+        {
+            iStateData.Trace( aText );
+        }
+
+        public void Trace( string aFormat, params object[] aParams )
+        {
+            iStateData.Trace( aFormat, aParams );
+        }
+        #endregion
+
+        #region Data members
+        private readonly ETMStateData iStateData;
+        private bool iLastInstructionCancelled = false;
+        private List<SymByte> iBytes = new List<SymByte>();
+        private TArmExceptionType iExceptionType = TArmExceptionType.EUnknown;
+        private TArmSecurityMode iSecurityMode = TArmSecurityMode.EUnknown;
+        private TArmInstructionSet iInstructionSet = TArmInstructionSet.EARM;
+        private SymAddressWithKnownBits iBranchAddress = new SymAddressWithKnownBits();
+        #endregion
+    }
+}