crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianStructuresLib/Debug/Symbols/Symbols/Symbol.cs
changeset 0 818e61de6cd1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianStructuresLib/Debug/Symbols/Symbols/Symbol.cs	Thu Feb 11 15:50:58 2010 +0200
@@ -0,0 +1,605 @@
+#define TRACE_INTERNING
+/*
+* 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 System.ComponentModel;
+using SymbianUtils.Range;
+using SymbianUtils.Strings;
+using SymbianStructuresLib.Arm;
+using SymbianStructuresLib.MemoryModel;
+using SymbianStructuresLib.Debug.Symbols.Constants;
+using SymbianStructuresLib.Debug.Common.Id;
+
+namespace SymbianStructuresLib.Debug.Symbols
+{
+	public class Symbol : IFormattable
+    {
+        #region Static constructors
+        public static Symbol New( SymbolCollection aCollection )
+        {
+            return new Symbol( aCollection );
+        }
+
+        public static Symbol NewDefault()
+        {
+            Symbol ret = new Symbol( null );
+            //
+            ret.IsDefault = true;
+            ret.Size = 0;
+            ret.OffsetAddress = SymbolConstants.KNullEntryAddress;
+            ret.Object = SymbolConstants.KNonMatchingObjectName;
+            ret.iName = InternedName.NewExplicit( SymbolConstants.KNonMatchingInternedName );
+            //
+            return ret;
+        }
+
+        internal static Symbol NewDefault( SymbolCollection aCollection )
+        {
+            Symbol ret = new Symbol( aCollection );
+            //
+            ret.IsDefault = true;
+            ret.Size = 0;
+            ret.OffsetAddress = SymbolConstants.KNullEntryAddress;
+            ret.Object = SymbolConstants.KNonMatchingObjectName;
+            ret.iName = InternedName.NewExplicit( SymbolConstants.KNonMatchingInternedName );
+            //
+            return ret;
+        }
+
+        internal static Symbol NewTemp( SymbolCollection aCollection, uint aAddress )
+        {
+            Symbol ret = new Symbol( aCollection );
+            //
+            ret.Size = 0;
+            ret.OffsetAddress = aAddress - aCollection.BaseAddress;
+            ret.iName = InternedName.NewExplicit( "TempInternal" );
+            ret.Object = "TempInternal";
+            //
+            return ret;
+        }
+
+        internal static Symbol NewClone( SymbolCollection aCollection, Symbol aSymbol )
+        {
+            return new Symbol( aCollection, aSymbol );
+        }
+        #endregion
+
+        #region Constructors
+        private Symbol( SymbolCollection aCollection )
+		{
+            iCollection = aCollection;
+            //
+            if ( aCollection != null )
+            {
+                iId = aCollection.IdAllocator.AllocateId().Value;
+            }
+		}
+
+        private Symbol( SymbolCollection aCollection, Symbol aSymbol )
+            : this( aCollection )
+        {
+            iSize = aSymbol.iSize;
+            iOffsetAddress = aSymbol.iOffsetAddress;
+            iName = aSymbol.iName;
+            iObject = aSymbol.iObject;
+            iFlags = aSymbol.iFlags;
+            iId = aCollection.IdAllocator.AllocateId().Value;
+        }
+		#endregion
+
+		#region API
+		public bool Contains( uint aAddress )
+		{
+            bool ret = ( aAddress >= Address && aAddress <= EndAddress );
+            return ret;
+		}
+
+        public uint Offset( uint aInstructionAddress )
+        {
+            uint offset = aInstructionAddress - Address;
+            return offset;
+        }
+        #endregion
+
+        #region Properties
+		public uint Address
+		{
+			get
+            {
+                uint address = BaseAddress + OffsetAddress;
+                return address;
+            }
+		}
+
+		public uint EndAddress
+		{
+			get
+            {
+                uint address = Address;
+                uint size = Size;
+                //
+                if ( size > 0 )
+                {
+                    address += ( size - 1 );
+                }
+                //
+                return address;
+            }
+		}
+
+		public uint Size
+		{
+			get { return iSize; }
+			set
+			{
+				iSize = value;
+				System.Diagnostics.Debug.Assert( OffsetEndAddress >= OffsetAddress );
+			}
+		}
+
+        public AddressRange AddressRange
+        {
+            get { return new AddressRange( Address, EndAddress ); }
+        }
+
+		public string Name
+		{
+			get
+            {
+                string ret = string.Empty;
+                //
+                if ( iName != null )
+                {
+                    ret = iName.ToString();
+                }
+                //
+                return ret;
+            }
+			set
+			{
+                iName = InternedName.New( value );
+               
+                // Remove all property flags
+                iFlags &= ~TFlags.EFlagsIsFunction;
+                iFlags &= ~TFlags.EFlagsIsVTable;
+                iFlags &= ~TFlags.EFlagsIsReadonly;
+                iFlags &= ~TFlags.EFlagsIsSubObject;
+
+                if ( InternedName.IsVTable( value ) )
+                {
+                    iFlags |= TFlags.EFlagsIsVTable;
+                }
+                else if ( InternedName.IsReadOnly( value ) )
+                {
+                    iFlags |= TFlags.EFlagsIsReadonly;
+                }
+                else if ( InternedName.IsSubObject( value ) )
+                {
+                    iFlags |= TFlags.EFlagsIsSubObject;
+                }
+                else if ( InternedName.IsFunction( value ) )
+                {
+                    iFlags |= TFlags.EFlagsIsFunction;
+                }
+            }
+		}
+
+        public string NameWithoutVTablePrefix
+		{
+			get
+            {
+                StringBuilder ret = new StringBuilder( Name );
+                //
+                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
+            {
+                string ret = string.Empty;
+                //
+                if ( iObject != null )
+                {
+                    ret = iObject;
+                }
+                //
+                return ret;
+            }
+			set
+            {
+                iObject = string.Intern( 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();
+                    }
+                }
+                //
+				return ret;
+			}
+		}
+
+        public SymbolCollection Collection
+        {
+            // NB: can be null
+            get { return iCollection; }
+        }
+
+        public TArmInstructionSet InstructionSet
+        {
+            get
+            {
+                TArmInstructionSet ret = TArmInstructionSet.EARM;
+                uint remainder = iOffsetAddress & 0x1;
+                if ( remainder != 0 )
+                {
+                    ret = TArmInstructionSet.ETHUMB;
+                }
+                return ret;
+            }
+        }
+
+        public PlatformId Id
+        {
+            get { return new PlatformId( iId ); }
+        }
+
+        [Browsable( false )]
+        [EditorBrowsable( EditorBrowsableState.Never )]
+        public uint OffsetAddress
+        {
+            get
+            {
+                // Don't include the top bit in any returned address
+                uint ret = iOffsetAddress & 0xFFFFFFFE;
+                return ret;
+            }
+            set
+            {
+                iOffsetAddress = value;
+            }
+        }
+
+        [Browsable( false )]
+        [EditorBrowsable( EditorBrowsableState.Never )]
+        private uint OffsetEndAddress
+        {
+            get
+            {
+                uint ret = iOffsetAddress + iSize;
+                if ( InstructionSet == TArmInstructionSet.ETHUMB && iSize > 0 )
+                {
+                    // For thumb, the end address is one too big, due to the MSB.
+                    --ret;
+                }
+                return ret;
+            }
+        }
+        #endregion
+
+        #region Type query
+        public bool IsFunction
+        {
+            get
+            {
+                bool ret = ( iFlags & TFlags.EFlagsIsFunction ) != 0;
+                return ret;
+            }
+        }
+
+        public bool IsVTable
+        {
+            get
+            {
+                bool ret = ( iFlags & TFlags.EFlagsIsVTable ) == TFlags.EFlagsIsVTable;
+                return ret;
+            }
+        }
+
+        public bool IsDefault
+        {
+            get
+            {
+                bool ret = ( iFlags & TFlags.EFlagsIsDefault ) == TFlags.EFlagsIsDefault;
+                return ret;
+            }
+            set
+            {
+                if ( value )
+                {
+                    iFlags |= TFlags.EFlagsIsDefault;
+                }
+                else
+                {
+                    iFlags &= ~TFlags.EFlagsIsDefault;
+                }
+            }
+        }
+
+        public bool IsFromRAMLoadedCode
+        {
+            get
+            {
+                uint address = this.Address;
+                TMemoryModelRegion region = MMUtilities.RegionByAddress( address );
+                bool ret = ( region == TMemoryModelRegion.EMemoryModelRegionRAMLoadedCode );
+                return ret;
+            }
+        }
+
+		public TSymbolType Type
+		{
+			get
+			{
+                TSymbolType ret = TSymbolType.EUnknown;
+
+                // First check against forced flags
+                if ( ( iFlags & TFlags.EFlagsIsForcedSection ) == TFlags.EFlagsIsForcedSection )
+                {
+                    ret = TSymbolType.ESection;
+                }
+                else if ( ( iFlags & TFlags.EFlagsIsForcedCode ) == TFlags.EFlagsIsForcedCode )
+                {
+                    ret = TSymbolType.ECode;
+                }
+                else if ( ( iFlags & TFlags.EFlagsIsForcedData ) == TFlags.EFlagsIsForcedData )
+                {
+                    ret = TSymbolType.EData;
+                }
+                else if ( ( iFlags & TFlags.EFlagsIsForcedNumber ) == TFlags.EFlagsIsForcedNumber )
+                {
+                    ret = TSymbolType.ENumber;
+                }
+                 
+                // If still unknown, work it out...
+                if ( ret == TSymbolType.EUnknown )
+                {
+                    // First entries override type
+                    if ( ( iFlags & TFlags.EFlagsIsReadonly ) != 0 )
+                    {
+                        ret = TSymbolType.EReadOnlySymbol;
+                    }
+                    else if ( ( iFlags & TFlags.EFlagsIsSubObject ) != 0 )
+                    {
+                        ret = TSymbolType.ESubObject;
+                    }
+                    else if ( Address >= 0xF8000000 && Address < 0xFFEFFFFF )
+                    {
+                        // ROM Symbol, Moving Memory Model
+                        ret = TSymbolType.EROMSymbol;
+                    }
+                    else if ( Address >= 0xF4000000 && Address < 0xF7FFFFFF )
+                    {
+                        // RAM Symbol, Moving Memory Model
+                        ret = TSymbolType.ERAMSymbol;
+                    }
+                    else if ( Address >= 0x64000000 && Address < 0x64FFFFFF )
+                    {
+                        // Kernel global, Moving Memory Model
+                        ret = TSymbolType.EKernelGlobalVariable;
+                    }
+                    else if ( Address >= 0xc8000000 && Address < 0xC8FFFFFF )
+                    {
+                        // Kernel global, Multiple Memory Model
+                        ret = TSymbolType.EKernelGlobalVariable;
+                    }
+                    else if ( Address >= 0x80000000 && Address < 0x8FFFFFFF )
+                    {
+                        // ROM Symbol, Multiple Memory Model
+                        ret = TSymbolType.EROMSymbol;
+                    }
+                    else if ( Address >= 0x3C000000 && Address < 0x3DFFFFFF )
+                    {
+                        // RAM Symbol, Moving Memory Model [1gb]
+                        ret = TSymbolType.ERAMSymbol;
+                    }
+                    else if ( Address >= 0x70000000 && Address < 0x7FFFFFFF )
+                    {
+                        // RAM Symbol, Moving Memory Model [2gb]
+                        ret = TSymbolType.ERAMSymbol;
+                    }
+                    else if ( Address < 0x10000000 )
+                    {
+                        // A non-fixed up ROFS symbol entry
+                        ret = TSymbolType.ERAMSymbol;
+                    }
+                    else if ( ret != TSymbolType.EKernelGlobalVariable )
+                    {
+                        bool isFunction = IsFunction;
+                        if ( isFunction == false )
+                        {
+                            ret = TSymbolType.ELabel;
+                        }
+                    }
+                }
+                //
+				return ret;
+			}
+            set
+            {
+                iFlags &= ~TFlags.EFlagsIsForcedCode;
+                iFlags &= ~TFlags.EFlagsIsForcedData;
+                iFlags &= ~TFlags.EFlagsIsForcedNumber;
+                iFlags &= ~TFlags.EFlagsIsForcedSection;
+                //
+                switch ( value )
+                {
+                case TSymbolType.ESection:
+                    iFlags |= TFlags.EFlagsIsForcedSection;
+                    break;
+                case TSymbolType.ECode:
+                    iFlags |= TFlags.EFlagsIsForcedCode;
+                    break;
+                case TSymbolType.EData:
+                    iFlags |= TFlags.EFlagsIsForcedData;
+                    break;
+                case TSymbolType.ENumber:
+                    iFlags |= TFlags.EFlagsIsForcedNumber;
+                    break;
+                default:
+                    throw new ArgumentException( "Specified type cannot be programatically set" );
+                }
+            }
+        }
+
+        public TSymbolSource Source
+        {
+            get
+            {
+                TSymbolSource ret = TSymbolSource.ESourceWasUnknown;
+                //
+                if ( ( iFlags & TFlags.EFlagsIsFromMapFile ) == TFlags.EFlagsIsFromMapFile )
+                {
+                    ret = TSymbolSource.ESourceWasMapFile;
+                }
+                else if ( ( iFlags & TFlags.EFlagsIsFromSymbolFile ) == TFlags.EFlagsIsFromSymbolFile )
+                {
+                    ret = TSymbolSource.ESourceWasSymbolFile;
+                }
+                //
+                return ret;
+            }
+            set
+            {
+                iFlags &= ~TFlags.EFlagsIsFromMapFile;
+                iFlags &= ~TFlags.EFlagsIsFromSymbolFile;
+                //
+                switch ( value )
+                {
+                case TSymbolSource.ESourceWasMapFile:
+                    iFlags |= TFlags.EFlagsIsFromMapFile;
+                    break;
+                case TSymbolSource.ESourceWasSymbolFile:
+                    iFlags |= TFlags.EFlagsIsFromSymbolFile;
+                    break;
+                default:
+                case TSymbolSource.ESourceWasUnknown:
+                    break;
+                }
+            }
+        }
+		#endregion
+        
+        #region Internal enumerations
+        [Flags]
+        private enum TFlags : ushort
+        {
+            EFlagsNone = 0,
+            EFlagsIsDefault = 1,
+            EFlagsIsVTable = 2,
+            EFlagsIsFunction = 4,
+            EFlagsIsReadonly = 8,
+            EFlagsIsSubObject = 16,
+            EFlagsIsForcedCode = 32,
+            EFlagsIsForcedData = 64,
+            EFlagsIsForcedNumber = 128,
+            EFlagsIsForcedSection = 256,
+            EFlagsIsFromMapFile = 512,
+            EFlagsIsFromSymbolFile = 1024
+        };
+        #endregion
+
+        #region Internal methods
+        private uint BaseAddress
+        {
+            get
+            {
+                if ( iCollection != null )
+                {
+                    return iCollection.BaseAddress;
+                }
+                //
+                return 0;
+            }
+        }
+        #endregion
+
+        #region From System.Object
+        public override string ToString()
+		{
+            string ret = ToString( null, null );
+			return ret;
+		}
+
+        public string ToStringOffset( uint aFrom )
+        {
+            uint baseAddressOffset = Offset( aFrom );
+            string text = "[+ 0x" + baseAddressOffset.ToString( "x4" ) + "]";
+            return text;
+        }
+	    #endregion
+
+        #region IFormattable Members
+        public string ToString( string aFormat, IFormatProvider aFormatProvider )
+        {
+            string ret = string.Empty;
+            //
+            if ( string.IsNullOrEmpty( aFormat ) )
+            {
+                ret = string.Format( "{0:x8}    {1:x4}    {2} [{3}]", Address, Size, Name, Object );
+            }
+            else
+            {
+                string format = aFormat.Trim().ToUpper();
+                //
+                if ( format == "STREAM" )
+                {
+                    ret = string.Format( "{0:x8}    {1:x4}    {2} [{3}]", Address, Size, Name.PadRight( 40, ' ' ), Object );
+                }
+                else
+                {
+                    throw new FormatException( String.Format( "Invalid format string: '{0}'.", aFormat ) );
+                }
+            }
+            //
+            return ret;
+        }
+        #endregion
+
+		#region Data members
+        private readonly SymbolCollection iCollection;
+        private readonly uint iId; // This saves 8 bytes per instance over using PlatformId directly
+        private uint iSize;
+		private uint iOffsetAddress;
+        private string iObject = null;
+        private InternedName iName = null;
+        private TFlags iFlags = TFlags.EFlagsNone;
+		#endregion
+    }
+}
\ No newline at end of file