crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianStructuresLib/Debug/Code/Code/CodeCollection.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 using System;
       
    18 using System.IO;
       
    19 using System.Text;
       
    20 using System.Collections.Generic;
       
    21 using SymbianUtils;
       
    22 using SymbianUtils.Range;
       
    23 using SymbianUtils.Streams;
       
    24 using SymbianStructuresLib.Arm;
       
    25 using SymbianStructuresLib.Arm.Instructions;
       
    26 using SymbianStructuresLib.CodeSegments;
       
    27 using SymbianStructuresLib.Debug.Common.Id;
       
    28 using SymbianStructuresLib.Debug.Common.FileName;
       
    29 using SymbianStructuresLib.Debug.Common.Interfaces;
       
    30 using SymbianStructuresLib.Debug.Code.Interfaces;
       
    31 
       
    32 namespace SymbianStructuresLib.Debug.Code
       
    33 {
       
    34     public sealed class CodeCollection : DisposableObject, IComparable<CodeCollection>, IArmInstructionProvider
       
    35     {
       
    36         #region Static constructors
       
    37         public static CodeCollection New( IPlatformIdAllocator aIdAllocator, string aFileNameInHost, string aFileNameInDevice )
       
    38         {
       
    39             CodeCollection ret = new CodeCollection( aIdAllocator, aFileNameInHost, aFileNameInDevice );
       
    40             return ret;
       
    41         }
       
    42 
       
    43         public static CodeCollection NewCopy( IPlatformIdAllocator aIdAllocator, CodeCollection aCollection )
       
    44         {
       
    45             CodeCollection ret = new CodeCollection( aIdAllocator, aCollection );
       
    46             return ret;
       
    47         }
       
    48 
       
    49         public static CodeCollection NewByHostFileName( IPlatformIdAllocator aIdAllocator, string aFileName )
       
    50         {
       
    51             CodeCollection ret = new CodeCollection( aIdAllocator, aFileName );
       
    52             return ret;
       
    53         }
       
    54         #endregion
       
    55 
       
    56         #region Delegates & events
       
    57         public delegate void RelocationStatusChangeHandler( CodeCollection aCollection );
       
    58         public event RelocationStatusChangeHandler RelocationStatusChanged;
       
    59         #endregion
       
    60 
       
    61         #region Constructors
       
    62         private CodeCollection( IPlatformIdAllocator aIdAllocator, string aFileNameInHost )
       
    63 		{
       
    64             iId = aIdAllocator.AllocateId();
       
    65             iFileName = PlatformFileName.NewByHostName( aFileNameInHost );
       
    66 		}
       
    67 
       
    68         private CodeCollection( IPlatformIdAllocator aIdAllocator, string aFileNameInHost, string aFileNameInDevice )
       
    69             : this( aIdAllocator, aFileNameInHost )
       
    70         {
       
    71             iFileName.FileNameInDevice = aFileNameInDevice;
       
    72         }
       
    73 
       
    74         private CodeCollection( IPlatformIdAllocator aIdAllocator, CodeCollection aCopy )
       
    75         {
       
    76             iId = aIdAllocator.AllocateId();
       
    77             //
       
    78             iCode = aCopy.iCode;
       
    79             iTag = aCopy.iTag;
       
    80             iFlags = aCopy.iFlags;
       
    81             iTagged = aCopy.iTagged;
       
    82             iBaseAddress = aCopy.iBaseAddress;
       
    83             iCodeSegmentResolver = aCopy.iCodeSegmentResolver;
       
    84             iRelocationHandler = aCopy.iRelocationHandler;
       
    85             iFileName = PlatformFileName.New( aCopy.FileName );
       
    86             iInstructionConverter = aCopy.IfaceInstructionConverter;
       
    87             iCodeSegmentResolver = aCopy.IfaceCodeSegmentResolver;
       
    88             iRelocationHandler = aCopy.IfaceRelocationHandler;
       
    89         }            
       
    90 		#endregion
       
    91 
       
    92         #region API
       
    93         public bool Contains( uint aAddress )
       
    94         {
       
    95             bool ret = IsInstructionAddressValid( aAddress );
       
    96             return ret;
       
    97         }
       
    98 
       
    99         public bool IsMatchingCodeSegment( CodeSegDefinition aCodeSegment )
       
   100         {
       
   101             bool ret = false;
       
   102             //
       
   103             if ( iCodeSegmentResolver != null )
       
   104             {
       
   105                 ret = iCodeSegmentResolver.IsMatchingCodeSegment( this, aCodeSegment );
       
   106             }
       
   107             else
       
   108             {
       
   109                 PlatformFileName codeSegName = PlatformFileName.NewByDeviceName( aCodeSegment.FileName );
       
   110                 ret = FileName.Equals( codeSegName );
       
   111             }
       
   112             //
       
   113             return ret;
       
   114         }
       
   115 
       
   116         public void Relocate( uint aTo )
       
   117         {
       
   118             if ( aTo != iBaseAddress )
       
   119             {
       
   120                 uint old = iBaseAddress;
       
   121                 iBaseAddress = aTo;
       
   122                 //
       
   123                 if ( iRelocationHandler != null )
       
   124                 {
       
   125                     iRelocationHandler.PrepareForRelocation( this, old, BaseAddress );
       
   126                 }
       
   127             }
       
   128         }
       
   129         #endregion
       
   130 
       
   131 		#region Properties
       
   132 		public uint Size
       
   133 		{
       
   134             get
       
   135             {
       
   136                 uint ret = 0;
       
   137                 if ( iCode != null )
       
   138                 {
       
   139                     ret = (uint) iCode.Length;
       
   140                 }
       
   141                 return ret;
       
   142             }
       
   143 		}
       
   144 
       
   145         public bool Tagged
       
   146         {
       
   147             get { return iTagged; }
       
   148             set
       
   149             { 
       
   150                 iTagged = value; 
       
   151             }
       
   152         }
       
   153 
       
   154         public bool IsRelocatable
       
   155         {
       
   156             get { return ( iFlags & TFlags.EFlagsIsRelocatable ) == TFlags.EFlagsIsRelocatable; }
       
   157             set
       
   158             {
       
   159                 lock ( iFlagLock )
       
   160                 {
       
   161                     bool wasSet = ( iFlags & TFlags.EFlagsIsRelocatable ) == TFlags.EFlagsIsRelocatable;
       
   162                     if ( wasSet != value )
       
   163                     {
       
   164                         if ( value )
       
   165                         {
       
   166                             iFlags |= TFlags.EFlagsIsRelocatable;
       
   167                         }
       
   168                         else
       
   169                         {
       
   170                             iFlags &= ~TFlags.EFlagsIsRelocatable;
       
   171                         }
       
   172 
       
   173                         // Report event if needed
       
   174                         if ( RelocationStatusChanged != null )
       
   175                         {
       
   176                             RelocationStatusChanged( this );
       
   177                         }
       
   178                     }
       
   179                 }
       
   180             }
       
   181         }
       
   182 
       
   183         public bool IsFixed
       
   184         {
       
   185             get { return !IsRelocatable; }
       
   186             set { IsRelocatable = !value; }
       
   187         }
       
   188 
       
   189         public object Tag
       
   190         {
       
   191             get { return iTag; }
       
   192             set
       
   193             {
       
   194                 iTag = value;
       
   195             }
       
   196         }
       
   197 
       
   198         public uint BaseAddress
       
   199         {
       
   200             get
       
   201             {
       
   202                 uint ret = iBaseAddress;
       
   203                 return ret;
       
   204             }
       
   205         }
       
   206 
       
   207         public bool IsCodeAvailable
       
   208         {
       
   209             get { return iCode != null; }
       
   210         }
       
   211 
       
   212         public byte[] Code
       
   213         {
       
   214             get { return iCode; }
       
   215             set
       
   216             {
       
   217                 iCode = value;
       
   218             }
       
   219         }
       
   220 
       
   221         public PlatformId Id
       
   222         {
       
   223             get { return iId; }
       
   224         }
       
   225 
       
   226         public PlatformFileName FileName
       
   227 		{
       
   228 			get { return iFileName; }
       
   229 		}
       
   230 
       
   231         public CodeCollectionList ParentList
       
   232         {
       
   233             get { return iParentList; }
       
   234             internal set { iParentList = value; }
       
   235         }
       
   236 		#endregion
       
   237 
       
   238         #region Properties - interfaces
       
   239         public ICodeCollectionCodeSegmentResolver IfaceCodeSegmentResolver
       
   240         {
       
   241             get { return iCodeSegmentResolver; }
       
   242             set { iCodeSegmentResolver = value; }
       
   243         }
       
   244 
       
   245         public ICodeCollectionRelocationHandler IfaceRelocationHandler
       
   246         {
       
   247             get { return iRelocationHandler; }
       
   248             set { iRelocationHandler = value; }
       
   249         }
       
   250 
       
   251         public ICodeCollectionInstructionConverter IfaceInstructionConverter
       
   252         {
       
   253             get { return iInstructionConverter; }
       
   254             set { iInstructionConverter = value; }
       
   255         }
       
   256         #endregion
       
   257 
       
   258         #region Internal enumerations
       
   259         [Flags]
       
   260         private enum TFlags : byte
       
   261         {
       
   262             EFlagsNone = 0,
       
   263             EFlagsIsRelocatable = 1
       
   264         };
       
   265         #endregion
       
   266 
       
   267         #region Internal constants
       
   268         #endregion
       
   269 
       
   270         #region Internal methods
       
   271         #endregion
       
   272 
       
   273         #region From IArmInstructionProvider
       
   274         public bool IsInstructionAddressValid( uint aAddress )
       
   275         {
       
   276             bool valid = false;
       
   277             //
       
   278             if ( IsCodeAvailable )
       
   279             {
       
   280                 AddressRange range = new AddressRange( this.BaseAddress, 0 );
       
   281                 range.UpdateMax( range.Min + iCode.Length );
       
   282                 //
       
   283                 valid = range.Contains( aAddress );
       
   284             }
       
   285             //
       
   286             return valid;
       
   287         }
       
   288 
       
   289         public uint GetDataUInt32( uint aAddress )
       
   290         {
       
   291             uint ret = 0;
       
   292             IArmInstruction[] inst = null;
       
   293             //
       
   294             bool available = GetInstructions( aAddress, TArmInstructionSet.EARM, 1, out inst );
       
   295             if ( available && inst.Length >= 1 )
       
   296             {
       
   297                 ret = inst[ 0 ].AIRawValue;
       
   298             }
       
   299             //
       
   300             return ret;
       
   301         }
       
   302 
       
   303         public ushort GetDataUInt16( uint aAddress )
       
   304         {
       
   305             ushort ret = 0;
       
   306             IArmInstruction[] inst = null;
       
   307             //
       
   308             bool available = GetInstructions( aAddress, TArmInstructionSet.ETHUMB, 1, out inst );
       
   309             if ( available && inst.Length >= 1 )
       
   310             {
       
   311                 ret = inst[ 0 ].AIRawValue;
       
   312             }
       
   313             //
       
   314             return ret;
       
   315         }
       
   316 
       
   317         public bool GetInstructions( uint aAddress, TArmInstructionSet aInstructionSet, int aCount, out IArmInstruction[] aInstructions )
       
   318         {
       
   319             bool valid = false;
       
   320             aInstructions = new IArmInstruction[ 0 ];
       
   321       
       
   322             // We need the code and the instruction converter
       
   323             if ( IsCodeAvailable && IfaceInstructionConverter != null )
       
   324             {
       
   325                 // Check range is valid
       
   326                 AddressRange range = new AddressRange( iBaseAddress, 0 );
       
   327                 range.UpdateMax( range.Min + iCode.Length );
       
   328                 uint extent = aAddress + ( (uint) aCount * (uint) aInstructionSet );
       
   329                 //
       
   330                 valid = range.Contains( aAddress ) && range.Contains( extent );
       
   331                 if ( valid )
       
   332                 {
       
   333                     List<uint> rawInstructions = new List<uint>();
       
   334                     //
       
   335                     using ( SymbianStreamReaderLE reader = SymbianStreamReaderLE.New( new MemoryStream( iCode ) ) )
       
   336                     {
       
   337                         uint address = aAddress - iBaseAddress;
       
   338                         reader.Seek( address );
       
   339                         //
       
   340                         for ( int i = 0; i < aCount; i++ )
       
   341                         {
       
   342                             uint value = 0;
       
   343                             //
       
   344                             switch ( aInstructionSet )
       
   345                             {
       
   346                             case TArmInstructionSet.ETHUMB:
       
   347                                 value = reader.ReadUInt16();
       
   348                                 break;
       
   349                             case TArmInstructionSet.EARM:
       
   350                                 value = reader.ReadUInt32();
       
   351                                 break;
       
   352                             default:
       
   353                             case TArmInstructionSet.EJAZELLE:
       
   354                                 throw new NotSupportedException( "Jazelle is not supported" );
       
   355                             }
       
   356                             //
       
   357                             rawInstructions.Add( value );
       
   358                             address += (uint) aInstructionSet;
       
   359                         }
       
   360                     }
       
   361                     //
       
   362                     aInstructions = iInstructionConverter.ConvertRawValuesToInstructions( aInstructionSet, rawInstructions.ToArray(), aAddress );
       
   363                 }
       
   364             }
       
   365 
       
   366             // Return empty array if not valid
       
   367             return valid;
       
   368         }
       
   369         #endregion
       
   370 
       
   371         #region From IComparable<CodeCollection>
       
   372         public int CompareTo( CodeCollection aCollection )
       
   373 		{
       
   374             int ret = ( aCollection.FileName == this.FileName ) ? 0 : -1;
       
   375 			//
       
   376             if ( ret == 0 )
       
   377             {
       
   378                 if ( BaseAddress == aCollection.BaseAddress )
       
   379                 {
       
   380                     ret = 0;
       
   381                 }
       
   382                 else if ( BaseAddress > aCollection.BaseAddress )
       
   383                 {
       
   384                     ret = 1;
       
   385                 }
       
   386                 else
       
   387                 {
       
   388                     ret = -1;
       
   389                 }
       
   390             }
       
   391 			//
       
   392 			return ret;
       
   393 		}
       
   394 		#endregion
       
   395 
       
   396         #region From DisposableObject
       
   397         protected override void CleanupManagedResources()
       
   398         {
       
   399             try
       
   400             {
       
   401                 base.CleanupManagedResources();
       
   402             }
       
   403             finally
       
   404             {
       
   405                 iTag = null;
       
   406                 iParentList = null;
       
   407                 iInstructionConverter = null;
       
   408                 iCodeSegmentResolver = null;
       
   409                 iRelocationHandler = null;
       
   410             }
       
   411         }
       
   412         #endregion
       
   413 
       
   414         #region From System.Object
       
   415         public override string ToString()
       
   416         {
       
   417             return iFileName.ToString();
       
   418         }
       
   419 
       
   420         public override bool Equals( object aObject )
       
   421         {
       
   422             if ( aObject != null && aObject is CodeCollection )
       
   423             {
       
   424                 CodeCollection col = (CodeCollection) aObject;
       
   425                 bool ret = ( col.FileName == this.FileName );
       
   426                 return ret;
       
   427             }
       
   428             //
       
   429             return base.Equals( aObject );
       
   430         }
       
   431 
       
   432         public override int GetHashCode()
       
   433         {
       
   434             return iFileName.GetHashCode();
       
   435         }
       
   436         #endregion
       
   437 
       
   438         #region Data members
       
   439         private readonly PlatformId iId;
       
   440         private readonly PlatformFileName iFileName;
       
   441         private object iTag = null;
       
   442         private object iFlagLock = new object();
       
   443         private byte[] iCode = null;
       
   444         private uint iBaseAddress = 0;
       
   445         private bool iTagged = false;
       
   446         private TFlags iFlags = TFlags.EFlagsNone;
       
   447         private CodeCollectionList iParentList = null;
       
   448         private ICodeCollectionCodeSegmentResolver iCodeSegmentResolver = null;
       
   449         private ICodeCollectionRelocationHandler iRelocationHandler = null;
       
   450         private ICodeCollectionInstructionConverter iInstructionConverter = null;
       
   451 		#endregion
       
   452     }
       
   453 }