crashanalysercmd/Libraries/Engine/CrashItemLib/Crash/Stacks/CIStack.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.Text;
       
    19 using System.Collections.Generic;
       
    20 using SymbianUtils;
       
    21 using SymbianUtils.Range;
       
    22 using SymbianUtils.DataBuffer;
       
    23 using SymbianUtils.DataBuffer.Entry;
       
    24 using SymbianUtils.DataBuffer.Primer;
       
    25 using SymbianStackLib.Engine;
       
    26 using SymbianStackLib.Data.Source;
       
    27 using SymbianStackLib.Data.Output;
       
    28 using SymbianStackLib.Data.Output.Entry;
       
    29 using SymbianStructuresLib.Uids;
       
    30 using SymbianStructuresLib.Arm.Registers;
       
    31 using CrashItemLib.Crash;
       
    32 using CrashItemLib.Crash.Base;
       
    33 using CrashItemLib.Crash.Registers;
       
    34 using CrashItemLib.Crash.Threads;
       
    35 using CrashItemLib.Crash.Processes;
       
    36 using CrashItemLib.Crash.CodeSegs;
       
    37 using CrashItemLib.Crash.Messages;
       
    38 
       
    39 namespace CrashItemLib.Crash.Stacks
       
    40 {
       
    41 	public class CIStack : CIElement, IEnumerable<CIStackEntry>
       
    42     {
       
    43         #region Static constructors
       
    44         public static CIStack NewStandAlone( CIRegisterList aRegisters, byte[] aData, uint aAddressOfFirstByte, AddressRange aRange )
       
    45         {
       
    46             CIStack ret = new CIStack( aRegisters, aData, aAddressOfFirstByte, aRange );
       
    47             return ret;
       
    48         }
       
    49 
       
    50         internal static CIStack NewThreadStack( CIThread aThread, CIRegisterList aRegisters, byte[] aData, uint aAddressOfFirstByte, AddressRange aRange )
       
    51         {
       
    52             CIStack ret = new CIStack( aRegisters, aData, aAddressOfFirstByte, aRange );
       
    53             return ret;
       
    54         }
       
    55         #endregion
       
    56 
       
    57         #region Constructors
       
    58         private CIStack( CIRegisterList aRegisters, byte[] aData, uint aAddressOfFirstByte, AddressRange aRange )
       
    59             : base( aRegisters.Container )
       
    60         {
       
    61             base.AddSupportedChildType( typeof( CIStackEntry ) );
       
    62             base.AddSupportedChildType( typeof( CIMessage ) );
       
    63 
       
    64             iRegisters = aRegisters;
       
    65             iStackAddressRange = aRange;
       
    66 
       
    67             // Prepare data
       
    68             DataBufferPrimer primer = new DataBufferPrimer( iStackData );
       
    69             primer.Prime( aData, aAddressOfFirstByte );
       
    70         }
       
    71         #endregion
       
    72 
       
    73         #region API
       
    74         #endregion
       
    75 
       
    76         #region Properties
       
    77         public bool IsStackOutputAvailable
       
    78         {
       
    79             get { return iStackOutput != null; }
       
    80         }
       
    81 
       
    82         public bool IsThreadAvailable
       
    83         {
       
    84             get { return OwningThread != null; }
       
    85         }
       
    86 
       
    87         public bool IsProcessAvailable
       
    88         {
       
    89             get { return OwningProcess != null; }
       
    90         }
       
    91 
       
    92         public bool IsOverflow
       
    93         {
       
    94             get
       
    95             {
       
    96                 bool ret = false;
       
    97                 //
       
    98                 bool pointerAvailable = this.Registers.Contains( TArmRegisterType.EArmReg_SP );
       
    99                 if ( pointerAvailable )
       
   100                 {
       
   101                     CIRegister regSP = this.Pointer;
       
   102                     AddressRange stackRange = this.Range;
       
   103                     //
       
   104                     ret = ( regSP <= stackRange.Min );
       
   105                 }
       
   106                 //
       
   107                 return ret;
       
   108             }
       
   109         }
       
   110 
       
   111         public TArmRegisterBank Type
       
   112         {
       
   113             get { return Registers.Bank; }
       
   114         }
       
   115 
       
   116         public uint Base
       
   117         {
       
   118             // NB: CIStack stores addresses differently to the stack
       
   119             // engine, but these are correct so no need to panic.
       
   120             get
       
   121             {
       
   122                 return iStackAddressRange.Min; 
       
   123             }
       
   124         }
       
   125 
       
   126         public uint Limit
       
   127         {
       
   128             // NB: CIStack stores addresses differently to the stack
       
   129             // engine, but these are correct so no need to panic.
       
   130             get
       
   131             {
       
   132                 return iStackAddressRange.Max;
       
   133             }
       
   134         }
       
   135 
       
   136         public uint Size
       
   137         {
       
   138             get
       
   139             {
       
   140                 // The address range contains all-inclusive values.
       
   141                 //
       
   142                 // E.g. a range of 0x00 -> 0x10 would include the values...:
       
   143                 //
       
   144                 //   0x00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F, 0x10
       
   145                 //
       
   146                 // ...and therefore AddressRange.Size would return 17.
       
   147                 //
       
   148                 // Symbian OS treats the range as non-inclusive, so the value is one too large.
       
   149                 // Hence we subtract one
       
   150                 uint ret = iStackAddressRange.Size - 1;
       
   151                 return ret;
       
   152             }
       
   153         }
       
   154 
       
   155         public int EntryCount
       
   156         {
       
   157             get { return iStackOutput.Count; }
       
   158         }
       
   159 
       
   160         public string Algorithm
       
   161         {
       
   162             get
       
   163             {
       
   164                 string ret = "Unknown Algorithm";
       
   165                 if ( iStackOutput != null )
       
   166                 {
       
   167                     ret = iStackOutput.AlgorithmName;
       
   168                 }
       
   169                 return ret;
       
   170             }
       
   171         }
       
   172 
       
   173         public byte[] RawStackData
       
   174         {
       
   175             get { return iStackData.ToArray(); }
       
   176         }
       
   177 
       
   178         public int RawDataLength
       
   179         {
       
   180             get { return iStackData.Count; }
       
   181         }
       
   182 
       
   183         public AddressRange RawDataRange
       
   184         {
       
   185             get { return iStackData.Range; }
       
   186         }
       
   187 
       
   188         public CIRegister Pointer
       
   189         {
       
   190             get
       
   191             {
       
   192                 CIRegister ret = Registers[ TArmRegisterType.EArmReg_SP ];
       
   193                 return ret;
       
   194             }
       
   195         }
       
   196 
       
   197         public uint PointerValue
       
   198         {
       
   199             get
       
   200             {
       
   201                 uint ret = 0;
       
   202                 
       
   203                 // We do it this way so as to avoid calling operator[] on the 
       
   204                 // register list if the register does not exist. The default behaviour
       
   205                 // of the register list class is to create a new register in such a situation
       
   206                 // and we don't really want to do that.
       
   207                 CIRegisterList regs = this.Registers;
       
   208                 if ( regs.Contains( TArmRegisterType.EArmReg_SP ) )
       
   209                 {
       
   210                     ret = this.Pointer.Value;
       
   211                 }
       
   212                 //
       
   213                 return ret;
       
   214             }
       
   215         }
       
   216 
       
   217         public AddressRange Range
       
   218         {
       
   219             get { return iStackAddressRange; }
       
   220             set
       
   221             {
       
   222                 iStackAddressRange = value;
       
   223             }
       
   224         }
       
   225 
       
   226         public CIThread OwningThread
       
   227         {
       
   228             get { return iRegisters.OwningThread; }
       
   229         }
       
   230 
       
   231         public CIProcess OwningProcess
       
   232         {
       
   233             get 
       
   234             {
       
   235                 CIProcess ret = null;
       
   236                 //
       
   237                 if ( OwningThread != null )
       
   238                 {
       
   239                     ret = OwningThread.OwningProcess;
       
   240                 }
       
   241                 //
       
   242                 return ret; 
       
   243             }
       
   244         }
       
   245 
       
   246         public CICodeSegList CodeSegments
       
   247         {
       
   248             get
       
   249             {
       
   250                 CICodeSegList list = null;
       
   251                 CIProcess process = OwningProcess;
       
   252                 if ( process != null )
       
   253                 {
       
   254                     list = process.CodeSegments;
       
   255                 }
       
   256                 return list;
       
   257             }
       
   258         }
       
   259 
       
   260         public CIRegisterList Registers
       
   261         {
       
   262             get { return iRegisters; }
       
   263         }
       
   264 
       
   265         public StackOutputData RawOutputData
       
   266         {
       
   267             get { return iStackOutput; }
       
   268         }
       
   269 
       
   270         internal StackSourceData RawSourceData
       
   271         {
       
   272             get { return iStackData; }
       
   273         }
       
   274         #endregion
       
   275 
       
   276         #region Internal methods
       
   277         private void CreateEntries()
       
   278         {
       
   279             if ( iStackOutput != null )
       
   280             {
       
   281                 int count = iStackOutput.Count;
       
   282                 //
       
   283                 for ( int i = 0; i < count; i++ )
       
   284                 {
       
   285                     StackOutputEntry dataOutputEntry = iStackOutput[ i ];
       
   286                     //
       
   287                     CIStackEntry entry = new CIStackEntry( this, dataOutputEntry );
       
   288                     base.AddChild( entry );
       
   289                 }
       
   290             }
       
   291         }
       
   292         #endregion
       
   293 
       
   294         #region From CIElement
       
   295         internal override void OnFinalize( CIElementFinalizationParameters aParams )
       
   296         {
       
   297             try
       
   298             {
       
   299                 base.OnFinalize( aParams );
       
   300             }
       
   301             finally
       
   302             {
       
   303                 CIStackBuilder builder = new CIStackBuilder( this, aParams.DebugEngine );
       
   304                 builder.Build( TSynchronicity.ESynchronous );
       
   305                 //
       
   306                 iStackOutput = builder.StackEngine.DataOutput;
       
   307                 //
       
   308                 CreateEntries();
       
   309             }
       
   310         }
       
   311         #endregion
       
   312 
       
   313         #region From IEnumerable<CIStackEntry>
       
   314         public new IEnumerator<CIStackEntry> GetEnumerator()
       
   315         {
       
   316             CIElementList<CIStackEntry> entries = base.ChildrenByType<CIStackEntry>();
       
   317             return entries.GetEnumerator();
       
   318         }
       
   319 
       
   320         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
       
   321         {
       
   322             CIElementList<CIStackEntry> entries = base.ChildrenByType<CIStackEntry>();
       
   323             return entries.GetEnumerator();
       
   324         }
       
   325         #endregion
       
   326 
       
   327         #region From System.Object
       
   328         public override string ToString()
       
   329         {
       
   330             StringBuilder ret = new StringBuilder();
       
   331             if ( OwningThread != null )
       
   332             {
       
   333                 ret.Append( "[Stack] " );
       
   334                 ret.Append( OwningThread.ToString() );
       
   335                 ret.Append( " " );
       
   336             }
       
   337             else
       
   338             {
       
   339 
       
   340             }
       
   341             //
       
   342             ret.Append( Registers.BankName );
       
   343             return ret.ToString();
       
   344         }
       
   345         #endregion
       
   346 
       
   347         #region Data members
       
   348         private readonly CIRegisterList iRegisters;
       
   349         private StackSourceData iStackData = new StackSourceData();
       
   350         private AddressRange iStackAddressRange = new AddressRange();
       
   351         private StackOutputData iStackOutput = null;
       
   352         #endregion
       
   353     }
       
   354 }