diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/Libraries/Engine/CrashDebuggerLib/Structures/UserContextTable/UserContextTableEntry.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/Libraries/Engine/CrashDebuggerLib/Structures/UserContextTable/UserContextTableEntry.cs Thu Feb 11 15:50:58 2010 +0200 @@ -0,0 +1,147 @@ +/* +* Copyright (c) 2004-2008 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.Generic; +using System.Text; +using SymbianStructuresLib.Arm.Registers; +using SymbianUtils.DataBuffer; +using SymbianUtils.DataBuffer.Entry; + +namespace CrashDebuggerLib.Structures.UserContextTable +{ + internal class UserContextTableEntry + { + #region Enumerations + public enum TType + { + EUndefined, /**< register is not available */ + EOffsetFromSp, /**< iOffset is offset from stack pointer */ + EOffsetFromStackTop, /**< iOffset is offset from stack top */ + ESpPlusOffset, /**< value = SP + offset */ + } + #endregion + + #region Constructors + public UserContextTableEntry() + { + } + #endregion + + #region API + public bool IsAvailable( bool aIsCurrentThread ) + { + bool ret = false; + // + switch ( Type ) + { + case TType.EOffsetFromSp: + // Not allowed when it's the current thread + ret = ( !aIsCurrentThread ); + break; + case TType.EOffsetFromStackTop: + // Always allowed + ret = true; + break; + case TType.ESpPlusOffset: + // Not allowed when it's the current thread + ret = ( !aIsCurrentThread ); + break; + default: + case TType.EUndefined: + break; + } + // + return ret; + } + + public uint Process( ArmRegister aSp, DataBuffer aStackData ) + { + uint ret = 0; + // + switch ( Type ) + { + case TType.EUndefined: + throw new NotSupportedException(); + case TType.EOffsetFromSp: + ret = UpdateUsingOffsetFromSp( aSp, aStackData ); + break; + case TType.EOffsetFromStackTop: + ret = UpdateUsingOffsetFromStackTop( aSp, aStackData ); + break; + case TType.ESpPlusOffset: + ret = UpdateUsingSpPlusOffset( aSp, aStackData ); + break; + } + // + return ret; + } + #endregion + + #region Properties + public TType Type + { + get { return iType; } + set { iType = value; } + } + + public byte Offset + { + get { return iOffset; } + set { iOffset = value; } + } + + public uint OffsetAsDWord + { + get { return (uint) Offset * 4; } + } + #endregion + + #region Internal methods + private uint UpdateUsingOffsetFromSp( ArmRegister aSp, DataBuffer aStackData ) + { + uint sp = aSp; + uint offset = OffsetAsDWord; + uint fetchAddr = offset + sp; + DataBufferUint val = aStackData[ fetchAddr ]; + return val; + } + + private uint UpdateUsingOffsetFromStackTop( ArmRegister aSp, DataBuffer aStackData ) + { + uint stackTop = aStackData.Last.Address + 1; + uint offset = OffsetAsDWord; + uint fetchAddr = stackTop - offset; + DataBufferUint val = aStackData[ fetchAddr ]; + return val; + } + + private uint UpdateUsingSpPlusOffset( ArmRegister aSp, DataBuffer aStackData ) + { + uint sp = aSp; + uint offset = OffsetAsDWord; + uint val = offset + sp; + return val; + } + #endregion + + #region Data members + private TType iType = TType.EUndefined; + private byte iOffset = 0; + #endregion + } +}