crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianStructuresLib/Debug/Symbols/Symbols/Symbol.cs
changeset 0 818e61de6cd1
equal deleted inserted replaced
-1:000000000000 0:818e61de6cd1
       
     1 #define TRACE_INTERNING
       
     2 /*
       
     3 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     4 * All rights reserved.
       
     5 * This component and the accompanying materials are made available
       
     6 * under the terms of "Eclipse Public License v1.0"
       
     7 * which accompanies this distribution, and is available
       
     8 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     9 *
       
    10 * Initial Contributors:
       
    11 * Nokia Corporation - initial contribution.
       
    12 *
       
    13 * Contributors:
       
    14 * 
       
    15 * Description:
       
    16 *
       
    17 */
       
    18 using System;
       
    19 using System.Collections;
       
    20 using System.Text;
       
    21 using System.Text.RegularExpressions;
       
    22 using System.ComponentModel;
       
    23 using SymbianUtils.Range;
       
    24 using SymbianUtils.Strings;
       
    25 using SymbianStructuresLib.Arm;
       
    26 using SymbianStructuresLib.MemoryModel;
       
    27 using SymbianStructuresLib.Debug.Symbols.Constants;
       
    28 using SymbianStructuresLib.Debug.Common.Id;
       
    29 
       
    30 namespace SymbianStructuresLib.Debug.Symbols
       
    31 {
       
    32 	public class Symbol : IFormattable
       
    33     {
       
    34         #region Static constructors
       
    35         public static Symbol New( SymbolCollection aCollection )
       
    36         {
       
    37             return new Symbol( aCollection );
       
    38         }
       
    39 
       
    40         public static Symbol NewDefault()
       
    41         {
       
    42             Symbol ret = new Symbol( null );
       
    43             //
       
    44             ret.IsDefault = true;
       
    45             ret.Size = 0;
       
    46             ret.OffsetAddress = SymbolConstants.KNullEntryAddress;
       
    47             ret.Object = SymbolConstants.KNonMatchingObjectName;
       
    48             ret.iName = InternedName.NewExplicit( SymbolConstants.KNonMatchingInternedName );
       
    49             //
       
    50             return ret;
       
    51         }
       
    52 
       
    53         internal static Symbol NewDefault( SymbolCollection aCollection )
       
    54         {
       
    55             Symbol ret = new Symbol( aCollection );
       
    56             //
       
    57             ret.IsDefault = true;
       
    58             ret.Size = 0;
       
    59             ret.OffsetAddress = SymbolConstants.KNullEntryAddress;
       
    60             ret.Object = SymbolConstants.KNonMatchingObjectName;
       
    61             ret.iName = InternedName.NewExplicit( SymbolConstants.KNonMatchingInternedName );
       
    62             //
       
    63             return ret;
       
    64         }
       
    65 
       
    66         internal static Symbol NewTemp( SymbolCollection aCollection, uint aAddress )
       
    67         {
       
    68             Symbol ret = new Symbol( aCollection );
       
    69             //
       
    70             ret.Size = 0;
       
    71             ret.OffsetAddress = aAddress - aCollection.BaseAddress;
       
    72             ret.iName = InternedName.NewExplicit( "TempInternal" );
       
    73             ret.Object = "TempInternal";
       
    74             //
       
    75             return ret;
       
    76         }
       
    77 
       
    78         internal static Symbol NewClone( SymbolCollection aCollection, Symbol aSymbol )
       
    79         {
       
    80             return new Symbol( aCollection, aSymbol );
       
    81         }
       
    82         #endregion
       
    83 
       
    84         #region Constructors
       
    85         private Symbol( SymbolCollection aCollection )
       
    86 		{
       
    87             iCollection = aCollection;
       
    88             //
       
    89             if ( aCollection != null )
       
    90             {
       
    91                 iId = aCollection.IdAllocator.AllocateId().Value;
       
    92             }
       
    93 		}
       
    94 
       
    95         private Symbol( SymbolCollection aCollection, Symbol aSymbol )
       
    96             : this( aCollection )
       
    97         {
       
    98             iSize = aSymbol.iSize;
       
    99             iOffsetAddress = aSymbol.iOffsetAddress;
       
   100             iName = aSymbol.iName;
       
   101             iObject = aSymbol.iObject;
       
   102             iFlags = aSymbol.iFlags;
       
   103             iId = aCollection.IdAllocator.AllocateId().Value;
       
   104         }
       
   105 		#endregion
       
   106 
       
   107 		#region API
       
   108 		public bool Contains( uint aAddress )
       
   109 		{
       
   110             bool ret = ( aAddress >= Address && aAddress <= EndAddress );
       
   111             return ret;
       
   112 		}
       
   113 
       
   114         public uint Offset( uint aInstructionAddress )
       
   115         {
       
   116             uint offset = aInstructionAddress - Address;
       
   117             return offset;
       
   118         }
       
   119         #endregion
       
   120 
       
   121         #region Properties
       
   122 		public uint Address
       
   123 		{
       
   124 			get
       
   125             {
       
   126                 uint address = BaseAddress + OffsetAddress;
       
   127                 return address;
       
   128             }
       
   129 		}
       
   130 
       
   131 		public uint EndAddress
       
   132 		{
       
   133 			get
       
   134             {
       
   135                 uint address = Address;
       
   136                 uint size = Size;
       
   137                 //
       
   138                 if ( size > 0 )
       
   139                 {
       
   140                     address += ( size - 1 );
       
   141                 }
       
   142                 //
       
   143                 return address;
       
   144             }
       
   145 		}
       
   146 
       
   147 		public uint Size
       
   148 		{
       
   149 			get { return iSize; }
       
   150 			set
       
   151 			{
       
   152 				iSize = value;
       
   153 				System.Diagnostics.Debug.Assert( OffsetEndAddress >= OffsetAddress );
       
   154 			}
       
   155 		}
       
   156 
       
   157         public AddressRange AddressRange
       
   158         {
       
   159             get { return new AddressRange( Address, EndAddress ); }
       
   160         }
       
   161 
       
   162 		public string Name
       
   163 		{
       
   164 			get
       
   165             {
       
   166                 string ret = string.Empty;
       
   167                 //
       
   168                 if ( iName != null )
       
   169                 {
       
   170                     ret = iName.ToString();
       
   171                 }
       
   172                 //
       
   173                 return ret;
       
   174             }
       
   175 			set
       
   176 			{
       
   177                 iName = InternedName.New( value );
       
   178                
       
   179                 // Remove all property flags
       
   180                 iFlags &= ~TFlags.EFlagsIsFunction;
       
   181                 iFlags &= ~TFlags.EFlagsIsVTable;
       
   182                 iFlags &= ~TFlags.EFlagsIsReadonly;
       
   183                 iFlags &= ~TFlags.EFlagsIsSubObject;
       
   184 
       
   185                 if ( InternedName.IsVTable( value ) )
       
   186                 {
       
   187                     iFlags |= TFlags.EFlagsIsVTable;
       
   188                 }
       
   189                 else if ( InternedName.IsReadOnly( value ) )
       
   190                 {
       
   191                     iFlags |= TFlags.EFlagsIsReadonly;
       
   192                 }
       
   193                 else if ( InternedName.IsSubObject( value ) )
       
   194                 {
       
   195                     iFlags |= TFlags.EFlagsIsSubObject;
       
   196                 }
       
   197                 else if ( InternedName.IsFunction( value ) )
       
   198                 {
       
   199                     iFlags |= TFlags.EFlagsIsFunction;
       
   200                 }
       
   201             }
       
   202 		}
       
   203 
       
   204         public string NameWithoutVTablePrefix
       
   205 		{
       
   206 			get
       
   207             {
       
   208                 StringBuilder ret = new StringBuilder( Name );
       
   209                 //
       
   210                 ret = ret.Replace( "vtable for ", string.Empty );
       
   211                 ret = ret.Replace( "typeinfo for ", string.Empty );
       
   212                 ret = ret.Replace( "typeinfo name for ", string.Empty );
       
   213                 //
       
   214                 return ret.ToString();
       
   215             }
       
   216 		}
       
   217 
       
   218 		public string Object
       
   219 		{
       
   220 			get
       
   221             {
       
   222                 string ret = string.Empty;
       
   223                 //
       
   224                 if ( iObject != null )
       
   225                 {
       
   226                     ret = iObject;
       
   227                 }
       
   228                 //
       
   229                 return ret;
       
   230             }
       
   231 			set
       
   232             {
       
   233                 iObject = string.Intern( value );
       
   234             }
       
   235 		}
       
   236 
       
   237 		public string ObjectWithoutSection
       
   238 		{
       
   239 			get
       
   240 			{
       
   241 				string ret = string.Empty;
       
   242                 //
       
   243                 if  ( Object != null )
       
   244                 {
       
   245                     ret = Object;
       
   246                     //
       
   247                     int bracketPos = ret.IndexOf( "(" );
       
   248                     if	( bracketPos > 0 )
       
   249                     {
       
   250                         ret = ret.Substring( 0, bracketPos ).Trim();
       
   251                     }
       
   252                 }
       
   253                 //
       
   254 				return ret;
       
   255 			}
       
   256 		}
       
   257 
       
   258         public SymbolCollection Collection
       
   259         {
       
   260             // NB: can be null
       
   261             get { return iCollection; }
       
   262         }
       
   263 
       
   264         public TArmInstructionSet InstructionSet
       
   265         {
       
   266             get
       
   267             {
       
   268                 TArmInstructionSet ret = TArmInstructionSet.EARM;
       
   269                 uint remainder = iOffsetAddress & 0x1;
       
   270                 if ( remainder != 0 )
       
   271                 {
       
   272                     ret = TArmInstructionSet.ETHUMB;
       
   273                 }
       
   274                 return ret;
       
   275             }
       
   276         }
       
   277 
       
   278         public PlatformId Id
       
   279         {
       
   280             get { return new PlatformId( iId ); }
       
   281         }
       
   282 
       
   283         [Browsable( false )]
       
   284         [EditorBrowsable( EditorBrowsableState.Never )]
       
   285         public uint OffsetAddress
       
   286         {
       
   287             get
       
   288             {
       
   289                 // Don't include the top bit in any returned address
       
   290                 uint ret = iOffsetAddress & 0xFFFFFFFE;
       
   291                 return ret;
       
   292             }
       
   293             set
       
   294             {
       
   295                 iOffsetAddress = value;
       
   296             }
       
   297         }
       
   298 
       
   299         [Browsable( false )]
       
   300         [EditorBrowsable( EditorBrowsableState.Never )]
       
   301         private uint OffsetEndAddress
       
   302         {
       
   303             get
       
   304             {
       
   305                 uint ret = iOffsetAddress + iSize;
       
   306                 if ( InstructionSet == TArmInstructionSet.ETHUMB && iSize > 0 )
       
   307                 {
       
   308                     // For thumb, the end address is one too big, due to the MSB.
       
   309                     --ret;
       
   310                 }
       
   311                 return ret;
       
   312             }
       
   313         }
       
   314         #endregion
       
   315 
       
   316         #region Type query
       
   317         public bool IsFunction
       
   318         {
       
   319             get
       
   320             {
       
   321                 bool ret = ( iFlags & TFlags.EFlagsIsFunction ) != 0;
       
   322                 return ret;
       
   323             }
       
   324         }
       
   325 
       
   326         public bool IsVTable
       
   327         {
       
   328             get
       
   329             {
       
   330                 bool ret = ( iFlags & TFlags.EFlagsIsVTable ) == TFlags.EFlagsIsVTable;
       
   331                 return ret;
       
   332             }
       
   333         }
       
   334 
       
   335         public bool IsDefault
       
   336         {
       
   337             get
       
   338             {
       
   339                 bool ret = ( iFlags & TFlags.EFlagsIsDefault ) == TFlags.EFlagsIsDefault;
       
   340                 return ret;
       
   341             }
       
   342             set
       
   343             {
       
   344                 if ( value )
       
   345                 {
       
   346                     iFlags |= TFlags.EFlagsIsDefault;
       
   347                 }
       
   348                 else
       
   349                 {
       
   350                     iFlags &= ~TFlags.EFlagsIsDefault;
       
   351                 }
       
   352             }
       
   353         }
       
   354 
       
   355         public bool IsFromRAMLoadedCode
       
   356         {
       
   357             get
       
   358             {
       
   359                 uint address = this.Address;
       
   360                 TMemoryModelRegion region = MMUtilities.RegionByAddress( address );
       
   361                 bool ret = ( region == TMemoryModelRegion.EMemoryModelRegionRAMLoadedCode );
       
   362                 return ret;
       
   363             }
       
   364         }
       
   365 
       
   366 		public TSymbolType Type
       
   367 		{
       
   368 			get
       
   369 			{
       
   370                 TSymbolType ret = TSymbolType.EUnknown;
       
   371 
       
   372                 // First check against forced flags
       
   373                 if ( ( iFlags & TFlags.EFlagsIsForcedSection ) == TFlags.EFlagsIsForcedSection )
       
   374                 {
       
   375                     ret = TSymbolType.ESection;
       
   376                 }
       
   377                 else if ( ( iFlags & TFlags.EFlagsIsForcedCode ) == TFlags.EFlagsIsForcedCode )
       
   378                 {
       
   379                     ret = TSymbolType.ECode;
       
   380                 }
       
   381                 else if ( ( iFlags & TFlags.EFlagsIsForcedData ) == TFlags.EFlagsIsForcedData )
       
   382                 {
       
   383                     ret = TSymbolType.EData;
       
   384                 }
       
   385                 else if ( ( iFlags & TFlags.EFlagsIsForcedNumber ) == TFlags.EFlagsIsForcedNumber )
       
   386                 {
       
   387                     ret = TSymbolType.ENumber;
       
   388                 }
       
   389                  
       
   390                 // If still unknown, work it out...
       
   391                 if ( ret == TSymbolType.EUnknown )
       
   392                 {
       
   393                     // First entries override type
       
   394                     if ( ( iFlags & TFlags.EFlagsIsReadonly ) != 0 )
       
   395                     {
       
   396                         ret = TSymbolType.EReadOnlySymbol;
       
   397                     }
       
   398                     else if ( ( iFlags & TFlags.EFlagsIsSubObject ) != 0 )
       
   399                     {
       
   400                         ret = TSymbolType.ESubObject;
       
   401                     }
       
   402                     else if ( Address >= 0xF8000000 && Address < 0xFFEFFFFF )
       
   403                     {
       
   404                         // ROM Symbol, Moving Memory Model
       
   405                         ret = TSymbolType.EROMSymbol;
       
   406                     }
       
   407                     else if ( Address >= 0xF4000000 && Address < 0xF7FFFFFF )
       
   408                     {
       
   409                         // RAM Symbol, Moving Memory Model
       
   410                         ret = TSymbolType.ERAMSymbol;
       
   411                     }
       
   412                     else if ( Address >= 0x64000000 && Address < 0x64FFFFFF )
       
   413                     {
       
   414                         // Kernel global, Moving Memory Model
       
   415                         ret = TSymbolType.EKernelGlobalVariable;
       
   416                     }
       
   417                     else if ( Address >= 0xc8000000 && Address < 0xC8FFFFFF )
       
   418                     {
       
   419                         // Kernel global, Multiple Memory Model
       
   420                         ret = TSymbolType.EKernelGlobalVariable;
       
   421                     }
       
   422                     else if ( Address >= 0x80000000 && Address < 0x8FFFFFFF )
       
   423                     {
       
   424                         // ROM Symbol, Multiple Memory Model
       
   425                         ret = TSymbolType.EROMSymbol;
       
   426                     }
       
   427                     else if ( Address >= 0x3C000000 && Address < 0x3DFFFFFF )
       
   428                     {
       
   429                         // RAM Symbol, Moving Memory Model [1gb]
       
   430                         ret = TSymbolType.ERAMSymbol;
       
   431                     }
       
   432                     else if ( Address >= 0x70000000 && Address < 0x7FFFFFFF )
       
   433                     {
       
   434                         // RAM Symbol, Moving Memory Model [2gb]
       
   435                         ret = TSymbolType.ERAMSymbol;
       
   436                     }
       
   437                     else if ( Address < 0x10000000 )
       
   438                     {
       
   439                         // A non-fixed up ROFS symbol entry
       
   440                         ret = TSymbolType.ERAMSymbol;
       
   441                     }
       
   442                     else if ( ret != TSymbolType.EKernelGlobalVariable )
       
   443                     {
       
   444                         bool isFunction = IsFunction;
       
   445                         if ( isFunction == false )
       
   446                         {
       
   447                             ret = TSymbolType.ELabel;
       
   448                         }
       
   449                     }
       
   450                 }
       
   451                 //
       
   452 				return ret;
       
   453 			}
       
   454             set
       
   455             {
       
   456                 iFlags &= ~TFlags.EFlagsIsForcedCode;
       
   457                 iFlags &= ~TFlags.EFlagsIsForcedData;
       
   458                 iFlags &= ~TFlags.EFlagsIsForcedNumber;
       
   459                 iFlags &= ~TFlags.EFlagsIsForcedSection;
       
   460                 //
       
   461                 switch ( value )
       
   462                 {
       
   463                 case TSymbolType.ESection:
       
   464                     iFlags |= TFlags.EFlagsIsForcedSection;
       
   465                     break;
       
   466                 case TSymbolType.ECode:
       
   467                     iFlags |= TFlags.EFlagsIsForcedCode;
       
   468                     break;
       
   469                 case TSymbolType.EData:
       
   470                     iFlags |= TFlags.EFlagsIsForcedData;
       
   471                     break;
       
   472                 case TSymbolType.ENumber:
       
   473                     iFlags |= TFlags.EFlagsIsForcedNumber;
       
   474                     break;
       
   475                 default:
       
   476                     throw new ArgumentException( "Specified type cannot be programatically set" );
       
   477                 }
       
   478             }
       
   479         }
       
   480 
       
   481         public TSymbolSource Source
       
   482         {
       
   483             get
       
   484             {
       
   485                 TSymbolSource ret = TSymbolSource.ESourceWasUnknown;
       
   486                 //
       
   487                 if ( ( iFlags & TFlags.EFlagsIsFromMapFile ) == TFlags.EFlagsIsFromMapFile )
       
   488                 {
       
   489                     ret = TSymbolSource.ESourceWasMapFile;
       
   490                 }
       
   491                 else if ( ( iFlags & TFlags.EFlagsIsFromSymbolFile ) == TFlags.EFlagsIsFromSymbolFile )
       
   492                 {
       
   493                     ret = TSymbolSource.ESourceWasSymbolFile;
       
   494                 }
       
   495                 //
       
   496                 return ret;
       
   497             }
       
   498             set
       
   499             {
       
   500                 iFlags &= ~TFlags.EFlagsIsFromMapFile;
       
   501                 iFlags &= ~TFlags.EFlagsIsFromSymbolFile;
       
   502                 //
       
   503                 switch ( value )
       
   504                 {
       
   505                 case TSymbolSource.ESourceWasMapFile:
       
   506                     iFlags |= TFlags.EFlagsIsFromMapFile;
       
   507                     break;
       
   508                 case TSymbolSource.ESourceWasSymbolFile:
       
   509                     iFlags |= TFlags.EFlagsIsFromSymbolFile;
       
   510                     break;
       
   511                 default:
       
   512                 case TSymbolSource.ESourceWasUnknown:
       
   513                     break;
       
   514                 }
       
   515             }
       
   516         }
       
   517 		#endregion
       
   518         
       
   519         #region Internal enumerations
       
   520         [Flags]
       
   521         private enum TFlags : ushort
       
   522         {
       
   523             EFlagsNone = 0,
       
   524             EFlagsIsDefault = 1,
       
   525             EFlagsIsVTable = 2,
       
   526             EFlagsIsFunction = 4,
       
   527             EFlagsIsReadonly = 8,
       
   528             EFlagsIsSubObject = 16,
       
   529             EFlagsIsForcedCode = 32,
       
   530             EFlagsIsForcedData = 64,
       
   531             EFlagsIsForcedNumber = 128,
       
   532             EFlagsIsForcedSection = 256,
       
   533             EFlagsIsFromMapFile = 512,
       
   534             EFlagsIsFromSymbolFile = 1024
       
   535         };
       
   536         #endregion
       
   537 
       
   538         #region Internal methods
       
   539         private uint BaseAddress
       
   540         {
       
   541             get
       
   542             {
       
   543                 if ( iCollection != null )
       
   544                 {
       
   545                     return iCollection.BaseAddress;
       
   546                 }
       
   547                 //
       
   548                 return 0;
       
   549             }
       
   550         }
       
   551         #endregion
       
   552 
       
   553         #region From System.Object
       
   554         public override string ToString()
       
   555 		{
       
   556             string ret = ToString( null, null );
       
   557 			return ret;
       
   558 		}
       
   559 
       
   560         public string ToStringOffset( uint aFrom )
       
   561         {
       
   562             uint baseAddressOffset = Offset( aFrom );
       
   563             string text = "[+ 0x" + baseAddressOffset.ToString( "x4" ) + "]";
       
   564             return text;
       
   565         }
       
   566 	    #endregion
       
   567 
       
   568         #region IFormattable Members
       
   569         public string ToString( string aFormat, IFormatProvider aFormatProvider )
       
   570         {
       
   571             string ret = string.Empty;
       
   572             //
       
   573             if ( string.IsNullOrEmpty( aFormat ) )
       
   574             {
       
   575                 ret = string.Format( "{0:x8}    {1:x4}    {2} [{3}]", Address, Size, Name, Object );
       
   576             }
       
   577             else
       
   578             {
       
   579                 string format = aFormat.Trim().ToUpper();
       
   580                 //
       
   581                 if ( format == "STREAM" )
       
   582                 {
       
   583                     ret = string.Format( "{0:x8}    {1:x4}    {2} [{3}]", Address, Size, Name.PadRight( 40, ' ' ), Object );
       
   584                 }
       
   585                 else
       
   586                 {
       
   587                     throw new FormatException( String.Format( "Invalid format string: '{0}'.", aFormat ) );
       
   588                 }
       
   589             }
       
   590             //
       
   591             return ret;
       
   592         }
       
   593         #endregion
       
   594 
       
   595 		#region Data members
       
   596         private readonly SymbolCollection iCollection;
       
   597         private readonly uint iId; // This saves 8 bytes per instance over using PlatformId directly
       
   598         private uint iSize;
       
   599 		private uint iOffsetAddress;
       
   600         private string iObject = null;
       
   601         private InternedName iName = null;
       
   602         private TFlags iFlags = TFlags.EFlagsNone;
       
   603 		#endregion
       
   604     }
       
   605 }