crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianETMLib/Common/BranchDecoder/ETMBranchDecoderOriginal.cs
changeset 0 818e61de6cd1
equal deleted inserted replaced
-1:000000000000 0:818e61de6cd1
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 using System;
       
    19 using System.Collections.Generic;
       
    20 using System.Text;
       
    21 using SymbianUtils.BasicTypes;
       
    22 using SymbianStructuresLib.Arm;
       
    23 using SymbianStructuresLib.Arm.Exceptions;
       
    24 using SymbianStructuresLib.Arm.SecurityMode;
       
    25 using SymbianETMLib.Common.Types;
       
    26 using SymbianETMLib.Common.Config;
       
    27 using SymbianETMLib.Common.State;
       
    28 using SymbianETMLib.Common.Exception;
       
    29 
       
    30 namespace SymbianETMLib.Common.BranchDecoder
       
    31 {
       
    32     internal class ETMBranchDecoderOriginal : ETMBranchDecoder
       
    33     {
       
    34         #region Constructors
       
    35         public ETMBranchDecoderOriginal( ETMStateData aManager )
       
    36             : base( aManager )
       
    37         {
       
    38         }
       
    39 
       
    40         static ETMBranchDecoderOriginal()
       
    41         {
       
    42             iMaskByte5_ARM = new SymMask( KMaskByte5_ARM );
       
    43             iMaskByte5_THUMB = new SymMask( KMaskByte5_THUMB );
       
    44             iMaskByte5_JAZELLE = new SymMask( KMaskByte5_JAZELLE );
       
    45         }
       
    46         #endregion
       
    47 
       
    48         #region From ETBBranchDecoder
       
    49         public override void Offer( SymByte aByte )
       
    50         {
       
    51             base.Save( aByte );
       
    52         }
       
    53 
       
    54         protected override void DecodeFull()
       
    55         {
       
    56             // We have full 5 bytes of address info.
       
    57             SymMask maskFirst = new SymMask( 0x7E, SymMask.TShiftDirection.ERight, 1 );
       
    58             SymMask maskMiddle = new SymMask( 0x7F );
       
    59 
       
    60             SymByte b;
       
    61             SymAddressWithKnownBits address = new SymAddressWithKnownBits();
       
    62             uint masked = 0;
       
    63             
       
    64             // First byte
       
    65             b = base[ 0 ];
       
    66             address.KnownBits += 6;
       
    67             address.Address |= maskFirst.Apply( b );
       
    68 
       
    69             // Bytes 1, 2, 3
       
    70             for ( int i = 1; i <= 3; i++ )
       
    71             {
       
    72                 b = base[ i ];
       
    73                 b = (byte) maskMiddle.Apply( b );
       
    74                 masked = (uint) ( b << address.KnownBits );
       
    75                 address.KnownBits += 7;
       
    76                 address.Address |= masked;
       
    77             }
       
    78 
       
    79             // Last byte - mask depends on instruction set.
       
    80             b = base[ 4 ];
       
    81             int lastByteAddressBits = 0;
       
    82             if ( this.ContainsInlineException || iMaskByte5_ARM.IsMatch( b ) )
       
    83             {
       
    84                 // Inline exception indicates ARM.
       
    85                 base.InstructionSet = TArmInstructionSet.EARM;
       
    86                 lastByteAddressBits = 3;
       
    87             }
       
    88             else if ( iMaskByte5_THUMB.IsMatch( b ) )
       
    89             {
       
    90                 base.InstructionSet = TArmInstructionSet.ETHUMB;
       
    91                 lastByteAddressBits = 4;
       
    92             }
       
    93             else if ( iMaskByte5_JAZELLE.IsMatch( b ) )
       
    94             {
       
    95                 base.InstructionSet = TArmInstructionSet.EJAZELLE;
       
    96                 lastByteAddressBits = 5;
       
    97             }
       
    98             else
       
    99             {
       
   100                 throw new ETMException( "ERROR: branch type unknown" );
       
   101             }
       
   102 
       
   103             // Now we can process the last byte
       
   104             masked = b.LowestBits( lastByteAddressBits );
       
   105             masked <<= address.KnownBits;
       
   106             address.KnownBits += lastByteAddressBits;
       
   107             address.Address |= masked;
       
   108 
       
   109             // Shift entire address by shift count based upon current instruction set.
       
   110             int isShift = ETMBranchDecoder.CompressionLeftShiftCount( base.InstructionSet );
       
   111             System.Diagnostics.Debug.Assert( address.KnownBits + isShift == 32 );
       
   112             address.KnownBits = 32;
       
   113             address.Address <<= isShift;
       
   114 
       
   115             // Save address
       
   116             base.BranchAddress = address;
       
   117 
       
   118             // We may also need to decode the inline exception
       
   119             if ( ContainsInlineException )
       
   120             {
       
   121                 // Yup, line exception...
       
   122                 DecodeInlineException( base.LastByte );
       
   123             }
       
   124         }
       
   125 
       
   126         protected override void DecodePartial()
       
   127         {
       
   128             // According to Table 7-13, "Missing components of exception Branch address packets"
       
   129             // then after a partial branch, we're always in "no exception" state
       
   130             base.ExceptionType = TArmExceptionType.ENone;
       
   131 
       
   132             // We have full 5 bytes of address info.
       
   133             SymMask maskFirst = new SymMask( 0x7E, SymMask.TShiftDirection.ERight, 1 );
       
   134             SymMask maskMiddle = new SymMask( 0x7F );
       
   135 
       
   136             SymByte b;
       
   137             SymAddressWithKnownBits address = new SymAddressWithKnownBits();
       
   138             uint masked = 0;
       
   139             int count = base.Count;
       
   140 
       
   141             // First byte
       
   142             b = base[ 0 ];
       
   143             address.KnownBits += 6;
       
   144             address.Address |= maskFirst.Apply( b );
       
   145 
       
   146             // Bytes 1, 2, 3
       
   147             for ( int i = 1; i < count; i++ )
       
   148             {
       
   149                 b = base[ i ];
       
   150                 b = (byte) maskMiddle.Apply( b );
       
   151                 masked = (uint) ( b << address.KnownBits );
       
   152                 address.KnownBits += 7;
       
   153                 address.Address |= masked;
       
   154             }
       
   155 
       
   156             // Shift entire address by shift count based upon current instruction set.
       
   157             int isShift = ETMBranchDecoder.CompressionLeftShiftCount( base.InstructionSet );
       
   158             address.KnownBits += isShift;
       
   159             address.Address <<= isShift;
       
   160 
       
   161             // Save address
       
   162             base.BranchAddress = address;
       
   163         }
       
   164 
       
   165         public override void DecodeException( SymByte aByte )
       
   166         {
       
   167             // In a continuation exception byte, bit 7 is always supposed
       
   168             // to be clear, irrespective of whether original or alternative
       
   169             // compression schemes are in use.
       
   170             System.Diagnostics.Debug.Assert( aByte[ 7 ] == false );
       
   171 
       
   172             // Instruction cancellation
       
   173             base.IsLastInstructionCancelled = aByte[ 5 ];
       
   174 
       
   175             // Security
       
   176             base.SecurityMode = TArmSecurityMode.ESecure;
       
   177             if ( aByte[ 0 ] )
       
   178             {
       
   179                 base.SecurityMode = TArmSecurityMode.ENotSecure;
       
   180             }
       
   181 
       
   182             // Exception type
       
   183             TArmExceptionType exceptionType = TArmExceptionType.EUnknown;
       
   184             aByte = (byte) ( ( (byte) ( aByte & 0x1E ) ) >> 1 );
       
   185             switch ( aByte )
       
   186             {
       
   187             case 0:
       
   188                 exceptionType = TArmExceptionType.ENone;
       
   189                 break;
       
   190             case 1:
       
   191                 exceptionType = TArmExceptionType.EHaltingDebug;
       
   192                 break;
       
   193             case 2:
       
   194                 exceptionType = TArmExceptionType.ESecureMonitorCall;
       
   195                 break;
       
   196             default:
       
   197             case 3:
       
   198                 throw new ETMException( "ERROR - reserved exception code during continuation byte" );
       
   199             case 4:
       
   200                 exceptionType = TArmExceptionType.EAsyncDataAbort;
       
   201                 break;
       
   202             case 5:
       
   203                 exceptionType = TArmExceptionType.EJazelle;
       
   204                 break;
       
   205             case 6:
       
   206             case 7:
       
   207                 throw new ETMException( "ERROR - reserved exception code during continuation byte" );
       
   208             case 8:
       
   209                 exceptionType = TArmExceptionType.EProcessorReset;
       
   210                 break;
       
   211             case 9:
       
   212                 exceptionType = TArmExceptionType.EUndefinedInstruction;
       
   213                 break;
       
   214             case 10:
       
   215                 exceptionType = TArmExceptionType.ESVC;
       
   216                 break;
       
   217             case 11:
       
   218                 exceptionType = TArmExceptionType.EPrefetchAbortOrSWBreakpoint;
       
   219                 break;
       
   220             case 12:
       
   221                 exceptionType = TArmExceptionType.ESyncDataAbortOrSWWatchpoint;
       
   222                 break;
       
   223             case 13:
       
   224                 exceptionType = TArmExceptionType.EGeneric;
       
   225                 break;
       
   226             case 14:
       
   227                 exceptionType = TArmExceptionType.EIRQ;
       
   228                 break;
       
   229             case 15:
       
   230                 exceptionType = TArmExceptionType.EFIQ;
       
   231                 break;
       
   232             }
       
   233             base.ExceptionType = exceptionType;
       
   234         }
       
   235         #endregion
       
   236 
       
   237         #region Properties
       
   238         protected virtual bool ContainsInlineException
       
   239         {
       
   240             get
       
   241             {
       
   242                 bool ret = false;
       
   243                 //
       
   244                 bool completeBranch = IsBranchAddressAvailable;
       
   245                 if ( completeBranch )
       
   246                 {
       
   247                     ret = ( LastByte[ 7 ] );
       
   248                 }
       
   249                 //
       
   250                 return ret;
       
   251             }
       
   252         }
       
   253         #endregion
       
   254 
       
   255         #region Internal constants
       
   256         protected const string KMaskByte5_ARM       = "0#001###";
       
   257         protected const string KMaskByte5_THUMB     = "0#01####";
       
   258         protected const string KMaskByte5_JAZELLE   = "0#1#####";
       
   259         #endregion
       
   260 
       
   261         #region Internal methods
       
   262         private void DecodeInlineException( SymByte aByte )
       
   263         {
       
   264             // b1CEEExxx Exception executed in ARM state.
       
   265             // 
       
   266             // The C bit is set to 1 if the exception cancels the last traced instruction.
       
   267             // The EEE bits, bits [5:3], indicate the type of exception as shown in Table 7-9.
       
   268             // Use of this format is deprecated in favor of using an Exception information byte.
       
   269 
       
   270             // Inline exception packets always indicate ARM mode
       
   271             base.InstructionSet = TArmInstructionSet.EARM;
       
   272 
       
   273             // Was it a cancelling branch?
       
   274             base.IsLastInstructionCancelled = aByte[ 6 ];
       
   275 
       
   276             // Set back to no exception unless changed explicitly below.
       
   277             base.ExceptionType = TArmExceptionType.ENone;
       
   278 
       
   279             // Get exception type
       
   280             SymMask mask = new SymMask( "## 111 ###", SymMask.TShiftDirection.ERight, 3 );
       
   281             SymByte exceptionInfo = (byte) mask.Apply( aByte );
       
   282 
       
   283             if ( exceptionInfo == 0 )
       
   284             {
       
   285                 // Have to work this out from the branch address
       
   286                 TArmExceptionVector vector = base.Config.MapToExceptionVector( base.BranchAddress.Address );
       
   287                 switch ( vector )
       
   288                 {
       
   289                 case TArmExceptionVector.EReset:
       
   290                     base.ExceptionType = TArmExceptionType.EProcessorReset;
       
   291                     break;
       
   292                 case TArmExceptionVector.EUndefinedInstruction:
       
   293                     base.ExceptionType = TArmExceptionType.EUndefinedInstruction;
       
   294                     break;
       
   295                 case TArmExceptionVector.ESVC:
       
   296                     base.ExceptionType = TArmExceptionType.ESVC;
       
   297                     break;
       
   298                 case TArmExceptionVector.EPrefetchAbort:
       
   299                     base.ExceptionType = TArmExceptionType.EPrefetchAbortOrSWBreakpoint;
       
   300                     break;
       
   301                 case TArmExceptionVector.EDataAbort:
       
   302                     base.ExceptionType = TArmExceptionType.ESyncDataAbortOrSWWatchpoint;
       
   303                     break;
       
   304                 default:
       
   305                     throw new ETMException( "ERROR - unable to extract exception type from branch address: 0x" + base.BranchAddress );
       
   306                 }
       
   307             }
       
   308             else
       
   309             {
       
   310                 switch ( exceptionInfo )
       
   311                 {
       
   312                 case 1:
       
   313                     base.ExceptionType = TArmExceptionType.EIRQ;
       
   314                     break;
       
   315                 default:
       
   316                 case 2:
       
   317                 case 3:
       
   318                     throw new NotSupportedException( "Reserved exception type" );
       
   319                 case 4:
       
   320                     base.ExceptionType = TArmExceptionType.EJazelle;
       
   321                     break;
       
   322                 case 5:
       
   323                     base.ExceptionType = TArmExceptionType.EFIQ;
       
   324                     break;
       
   325                 case 6:
       
   326                     base.ExceptionType = TArmExceptionType.EAsyncDataAbort;
       
   327                     break;
       
   328                 case 7:
       
   329                     base.ExceptionType = TArmExceptionType.EHaltingDebug;
       
   330                     break;
       
   331                 }
       
   332             }
       
   333         }
       
   334         #endregion
       
   335 
       
   336         #region Data members
       
   337         private static readonly SymMask iMaskByte5_ARM;
       
   338         private static readonly SymMask iMaskByte5_THUMB;
       
   339         private static readonly SymMask iMaskByte5_JAZELLE;
       
   340         #endregion
       
   341     }
       
   342 }