crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbolLib/Generic/Symbol/GenericSymbol.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbolLib/Generic/Symbol/GenericSymbol.cs Thu Feb 11 15:50:58 2010 +0200
@@ -0,0 +1,464 @@
+/*
+* 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;
+using System.Text;
+using System.Text.RegularExpressions;
+using SymbianUtils.Range;
+using SymbianUtils;
+
+namespace SymbolLib.Generics
+{
+ #region Exception
+ public class GenericSymbolicCreationException : Exception
+ {
+ }
+ #endregion
+
+ public abstract class GenericSymbol
+ {
+ #region Enumerations
+ public enum TAddressType
+ {
+ // Do not change the order - these are priority based with
+ // the most important symbol type appearing with a larger
+ // value
+ EAddressTypeUnknown = -1,
+ EAddressTypeReadOnlySymbol = 0,
+ EAddressTypeKernelGlobalVariable,
+ EAddressTypeSubObject,
+ EAddressTypeLabel,
+ EAddressTypeRAMSymbol,
+ EAddressTypeROMSymbol,
+ }
+
+ public enum TSourceType
+ {
+ ESourceTypeFileSymbol = 0,
+ ESourceTypeFileMap
+ }
+
+ public enum TInstructionSet
+ {
+ EInstructionSetARM = 0,
+ EInstructionSetTHUMB
+ }
+ #endregion
+
+ #region Public constants
+ public const int KNullEntryAddress = 0;
+ public const string KNonMatchingObjectName = "Unknown Object";
+ public const string KNonMatchingSymbolName = "Unknown Symbol";
+ #endregion
+
+ #region Constructors
+ protected GenericSymbol( GenericSymbolCollection aCollection )
+ {
+ iCollection = aCollection;
+ }
+ #endregion
+
+ #region Abstract API
+ public abstract TSourceType SourceType { get; }
+
+ public abstract bool Parse( string aLine );
+ #endregion
+
+ #region Framework API
+ public virtual bool FallsWithinDomain(long aAddress)
+ {
+ return (aAddress >= Address && aAddress <= EndAddress);
+ }
+
+ public virtual bool IsSubObject
+ {
+ get
+ {
+ bool ret = ( AddressType == TAddressType.EAddressTypeSubObject );
+ return ret;
+ }
+ }
+
+ public virtual bool IsLabel
+ {
+ get
+ {
+ bool ret = ( AddressType == TAddressType.EAddressTypeLabel );
+ return ret;
+ }
+ }
+
+ public virtual bool IsSymbol
+ {
+ get
+ {
+ bool ret = ( Collection.BaseAddress == 0 || AddressType == TAddressType.EAddressTypeRAMSymbol || AddressType == TAddressType.EAddressTypeROMSymbol );
+ return ret;
+ }
+ }
+
+ public virtual MemoryModel.TMemoryModelType MemoryModelType // Guess
+ {
+ get
+ {
+ return iStaticMemoryModelType;
+ }
+ }
+
+ public virtual TAddressType AddressType
+ {
+ get
+ {
+ TAddressType ret = TAddressType.EAddressTypeUnknown;
+
+ if ( Address >= 0xF8000000 && Address < 0xFFEFFFFF )
+ {
+ // ROM Symbol, Moving Memory Model
+ ret = TAddressType.EAddressTypeROMSymbol;
+ }
+ else if ( Address >= 0xF4000000 && Address < 0xF7FFFFFF )
+ {
+ // RAM Symbol, Moving Memory Model
+ ret = TAddressType.EAddressTypeRAMSymbol;
+ }
+ else if ( Address >= 0x64000000 && Address < 0x64FFFFFF )
+ {
+ // Kernel global, Moving Memory Model
+ ret = TAddressType.EAddressTypeKernelGlobalVariable;
+ }
+ else if ( Address >= 0xc8000000 && Address < 0xC8FFFFFF)
+ {
+ // Kernel global, Multiple Memory Model
+ ret = TAddressType.EAddressTypeKernelGlobalVariable;
+ }
+ else if ( Address >= 0x80000000 && Address < 0x8FFFFFFF )
+ {
+ // ROM Symbol, Multiple Memory Model
+ ret = TAddressType.EAddressTypeROMSymbol;
+ }
+ else if ( Address >= 0x3C000000 && Address < 0x3DFFFFFF )
+ {
+ // RAM Symbol, Moving Memory Model [1gb]
+ ret = TAddressType.EAddressTypeRAMSymbol;
+ }
+ else if ( Address >= 0x70000000 && Address < 0x7FFFFFFF )
+ {
+ // RAM Symbol, Moving Memory Model [2gb]
+ ret = TAddressType.EAddressTypeRAMSymbol;
+ }
+ else if ( Address < 0x10000000 )
+ {
+ // A non-fixed up ROFS symbol entry
+ ret = TAddressType.EAddressTypeRAMSymbol;
+ }
+
+ // These can over-ride the previous items...
+ if ( iSymbol.IndexOf("Image$$ER_RO$$") >= 0 )
+ {
+ ret = TAddressType.EAddressTypeReadOnlySymbol;
+ }
+ else if ( iSymbol.IndexOf("__sub_object(") > 0 )
+ {
+ ret = TAddressType.EAddressTypeSubObject;
+ }
+ else if ( ret != TAddressType.EAddressTypeKernelGlobalVariable )
+ {
+ bool containsBrackets = iSymbol.Contains( "(" ) && iSymbol.Contains( ")" );
+ if ( !containsBrackets )
+ {
+ ret = TAddressType.EAddressTypeLabel;
+ }
+ }
+
+ return ret;
+ }
+ }
+ #endregion
+
+ #region API
+ public static string UnknownOffset()
+ {
+ string text = "[+ ??????]";
+ return text;
+ }
+
+ public uint Offset( uint aInstructionAddress )
+ {
+ uint baseAddressOffset = aInstructionAddress - System.Convert.ToUInt32( Address );
+ return baseAddressOffset;
+ }
+
+ public string OffsetAsString( uint aInstructionAddress )
+ {
+ uint baseAddressOffset = Offset( aInstructionAddress );
+ string text = "[+ 0x" + baseAddressOffset.ToString( "x4" ) + "]";
+ return text;
+ }
+ #endregion
+
+ #region Properties
+ public TInstructionSet InstructionSet
+ {
+ get
+ {
+ TInstructionSet ret = TInstructionSet.EInstructionSetARM;
+ //
+ if ( ( iFlags & TFlags.EFlagsIsThumb ) == TFlags.EFlagsIsThumb )
+ {
+ ret = TInstructionSet.EInstructionSetTHUMB;
+ }
+ //
+ return ret;
+ }
+ }
+
+ public long BaseAddress
+ {
+ get { return iCollection.BaseAddress; }
+ }
+
+ public long Address
+ {
+ get
+ {
+ long address = BaseAddress + iOffsetAddress;
+ return address;
+ }
+ }
+
+ public long EndAddress
+ {
+ get
+ {
+ long ret = BaseAddress + iOffsetEndAddress;
+ return ret;
+ }
+ }
+
+ public long Size
+ {
+ get { return iSize; }
+ set
+ {
+ System.Diagnostics.Debug.Assert( value >= 0 );
+ iSize = value;
+
+ // We need to update the end address
+ if ( iSize > 0 )
+ {
+ long address = OffsetAddress;
+ OffsetEndAddress = address + iSize - 1;
+ }
+ else
+ {
+ OffsetEndAddress = OffsetAddress;
+ }
+
+ System.Diagnostics.Debug.Assert( iOffsetEndAddress >= OffsetAddress );
+ }
+ }
+
+ public AddressRange AddressRange
+ {
+ get { return new AddressRange( Address, EndAddress ); }
+ }
+
+ public string Symbol
+ {
+ get { return iSymbol; }
+ set
+ {
+ iSymbol = value;
+ if ( StartsWithAny( KVTableOrTypeInfoPrefixes, value ) )
+ {
+ iFlags |= TFlags.EFlagsVTable;
+ }
+ }
+ }
+
+ public string SymbolNameWithoutVTablePrefix
+ {
+ get
+ {
+ StringBuilder ret = new StringBuilder( Symbol );
+ //
+ ret = ret.Replace( "vtable for ", string.Empty );
+ ret = ret.Replace( "typeinfo for ", string.Empty );
+ ret = ret.Replace( "typeinfo name for ", string.Empty );
+ //
+ return ret.ToString();
+ }
+ }
+
+ public string Object
+ {
+ get { return iObject; }
+ set { iObject = value; }
+ }
+
+ public string ObjectWithoutSection
+ {
+ get
+ {
+ string ret = string.Empty;
+ //
+ if ( Object != null )
+ {
+ ret = Object;
+ //
+ int bracketPos = ret.IndexOf( "(" );
+ if ( bracketPos > 0 )
+ {
+ ret = ret.Substring( 0, bracketPos ).Trim();
+ }
+ }
+
+ // Casing looks odd and it can also confuse
+ // hash table look ups in dependent code.
+ //ret = SymbianUtils.Strings.StringCaser.PrettyCase( ret );
+ return ret;
+ }
+ }
+
+ public GenericSymbolCollection Collection
+ {
+ get { return iCollection; }
+ }
+
+ public bool IsUnknownSymbol
+ {
+ get
+ {
+ bool ret = Symbol.StartsWith( KNonMatchingSymbolName ) &&
+ ( OffsetAddress == GenericSymbol.KNullEntryAddress );
+ return ret;
+ }
+ }
+
+ public bool IsVTable
+ {
+ get
+ {
+ bool ret = ( iFlags & TFlags.EFlagsVTable ) == TFlags.EFlagsVTable;
+ return ret;
+ }
+ }
+ #endregion
+
+ #region Internal enumerations
+ [Flags]
+ private enum TFlags : byte
+ {
+ EFlagsNone = 0,
+ EFlagsVTable = 1,
+ EFlagsIsThumb = 2,
+ };
+ #endregion
+
+ #region Internal properties
+ internal long OffsetAddress
+ {
+ get { return iOffsetAddress; }
+ set
+ {
+ long remainder = value & 0x1;
+ if ( remainder != 0 )
+ {
+ iFlags |= TFlags.EFlagsIsThumb;
+ }
+ else
+ {
+ iFlags &= ~TFlags.EFlagsIsThumb;
+ }
+
+ iOffsetAddress = value & 0xFFFFFFFE;
+
+ // If we've not yet decided upon the type of memory model,
+ // now is the time to work it out.
+ if ( iOffsetAddress > 0 && iStaticMemoryModelType == MemoryModel.TMemoryModelType.EMemoryModelUnknown )
+ {
+ long address = Address;
+ iStaticMemoryModelType = MemoryModel.TypeByAddress( address );
+ }
+ }
+ }
+
+ private long OffsetEndAddress
+ {
+ set { iOffsetEndAddress = value; }
+ }
+ #endregion
+
+ #region Internal constants
+ protected const int KBaseHex = 16;
+ private static readonly string[] KVTableOrTypeInfoPrefixes = new string[] { "vtable for ", "typeinfo for ", "typeinfo name for " };
+ #endregion
+
+ #region From System.Object
+ public override string ToString()
+ {
+ string ret = string.Format( "{0:x8} {1:x4} {2} [{3}]", Address, Size, Symbol, Object );
+ return ret;
+ }
+
+ public string ToStringForStream()
+ {
+ StringBuilder ret = new StringBuilder();
+ //
+ ret.Append( Address.ToString( "x8" ) );
+ ret.Append( " " );
+ ret.Append( Size.ToString( "x4" ) );
+ ret.Append( " " );
+ ret.Append( Symbol.PadRight( 40, ' ' ) );
+ ret.Append( " " );
+ ret.Append( Object );
+ //
+ return ret.ToString();
+ }
+
+ public static bool StartsWithAny( string[] aPrefixes, string aText )
+ {
+ bool ret = false;
+ //
+ foreach ( string p in aPrefixes )
+ {
+ if ( aText.StartsWith( p ) )
+ {
+ ret = true;
+ break;
+ }
+ }
+ //
+ return ret;
+ }
+ #endregion
+
+ #region Data members
+ protected long iSize;
+ #endregion
+
+ #region Internal data members
+ private long iOffsetAddress;
+ private long iOffsetEndAddress;
+ private string iSymbol = string.Empty;
+ private string iObject = string.Empty;
+ private TFlags iFlags = TFlags.EFlagsNone;
+ private readonly GenericSymbolCollection iCollection;
+ private static MemoryModel.TMemoryModelType iStaticMemoryModelType = MemoryModel.TMemoryModelType.EMemoryModelUnknown;
+ #endregion
+ }
+}