| File: Contracts\StackWalk\Context\ARMContext.cs | Web Access |
| Project: src\runtime\src\native\managed\cdac\Microsoft.Diagnostics.DataContractReader.Contracts\Microsoft.Diagnostics.DataContractReader.Contracts.csproj (Microsoft.Diagnostics.DataContractReader.Contracts) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Runtime.InteropServices; using Microsoft.Diagnostics.DataContractReader.Contracts.StackWalkHelpers.ARM; namespace Microsoft.Diagnostics.DataContractReader.Contracts.StackWalkHelpers; /// <summary> /// ARM-specific thread context. /// </summary> [StructLayout(LayoutKind.Explicit, Pack = 1)] internal struct ARMContext : IPlatformContext { [Flags] public enum ContextFlagsValues : uint { CONTEXT_ARM = 0x00200000, CONTEXT_CONTROL = CONTEXT_ARM | 0x1, CONTEXT_INTEGER = CONTEXT_ARM | 0x2, CONTEXT_FLOATING_POINT = CONTEXT_ARM | 0x4, CONTEXT_DEBUG_REGISTERS = CONTEXT_ARM | 0x8, CONTEXT_FULL = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT, CONTEXT_ALL = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS, CONTEXT_UNWOUND_TO_CALL = 0x20000000, } public readonly uint Size => 0x1a0; public readonly uint ContextControlFlags => (uint)ContextFlagsValues.CONTEXT_CONTROL; public readonly uint FullContextFlags => (uint)ContextFlagsValues.CONTEXT_FULL; public readonly uint AllContextFlags => (uint)ContextFlagsValues.CONTEXT_ALL; public readonly int StackPointerRegister => 13; public TargetPointer StackPointer { readonly get => new(Sp); set => Sp = (uint)value.Value; } public TargetCodePointer InstructionPointer { readonly get => new(Pc); set => Pc = (uint)value.Value; } public TargetPointer FramePointer { readonly get => new(R11); set => R11 = (uint)value.Value; } public uint RawContextFlags { readonly get => ContextFlags; set => ContextFlags = value; } public void Unwind(Target target) { ARMUnwinder unwinder = new(target); unwinder.Unwind(ref this); } public void UnsetSingleStepFlag() { } public bool TrySetRegister(string name, TargetNUInt value) { if (name.Equals("r0", StringComparison.OrdinalIgnoreCase)) { R0 = (uint)value.Value; return true; } if (name.Equals("r1", StringComparison.OrdinalIgnoreCase)) { R1 = (uint)value.Value; return true; } if (name.Equals("r2", StringComparison.OrdinalIgnoreCase)) { R2 = (uint)value.Value; return true; } if (name.Equals("r3", StringComparison.OrdinalIgnoreCase)) { R3 = (uint)value.Value; return true; } if (name.Equals("r4", StringComparison.OrdinalIgnoreCase)) { R4 = (uint)value.Value; return true; } if (name.Equals("r5", StringComparison.OrdinalIgnoreCase)) { R5 = (uint)value.Value; return true; } if (name.Equals("r6", StringComparison.OrdinalIgnoreCase)) { R6 = (uint)value.Value; return true; } if (name.Equals("r7", StringComparison.OrdinalIgnoreCase)) { R7 = (uint)value.Value; return true; } if (name.Equals("r8", StringComparison.OrdinalIgnoreCase)) { R8 = (uint)value.Value; return true; } if (name.Equals("r9", StringComparison.OrdinalIgnoreCase)) { R9 = (uint)value.Value; return true; } if (name.Equals("r10", StringComparison.OrdinalIgnoreCase)) { R10 = (uint)value.Value; return true; } if (name.Equals("r11", StringComparison.OrdinalIgnoreCase)) { R11 = (uint)value.Value; return true; } if (name.Equals("r12", StringComparison.OrdinalIgnoreCase)) { R12 = (uint)value.Value; return true; } if (name.Equals("sp", StringComparison.OrdinalIgnoreCase)) { Sp = (uint)value.Value; return true; } if (name.Equals("lr", StringComparison.OrdinalIgnoreCase)) { Lr = (uint)value.Value; return true; } if (name.Equals("pc", StringComparison.OrdinalIgnoreCase)) { Pc = (uint)value.Value; return true; } if (name.Equals("cpsr", StringComparison.OrdinalIgnoreCase)) { Cpsr = (uint)value.Value; return true; } if (name.Equals("fpscr", StringComparison.OrdinalIgnoreCase)) { Fpscr = (uint)value.Value; return true; } return false; } public bool TryReadRegister(string name, out TargetNUInt value) { value = default; if (name.Equals("r0", StringComparison.OrdinalIgnoreCase)) { value = new TargetNUInt(R0); return true; } if (name.Equals("r1", StringComparison.OrdinalIgnoreCase)) { value = new TargetNUInt(R1); return true; } if (name.Equals("r2", StringComparison.OrdinalIgnoreCase)) { value = new TargetNUInt(R2); return true; } if (name.Equals("r3", StringComparison.OrdinalIgnoreCase)) { value = new TargetNUInt(R3); return true; } if (name.Equals("r4", StringComparison.OrdinalIgnoreCase)) { value = new TargetNUInt(R4); return true; } if (name.Equals("r5", StringComparison.OrdinalIgnoreCase)) { value = new TargetNUInt(R5); return true; } if (name.Equals("r6", StringComparison.OrdinalIgnoreCase)) { value = new TargetNUInt(R6); return true; } if (name.Equals("r7", StringComparison.OrdinalIgnoreCase)) { value = new TargetNUInt(R7); return true; } if (name.Equals("r8", StringComparison.OrdinalIgnoreCase)) { value = new TargetNUInt(R8); return true; } if (name.Equals("r9", StringComparison.OrdinalIgnoreCase)) { value = new TargetNUInt(R9); return true; } if (name.Equals("r10", StringComparison.OrdinalIgnoreCase)) { value = new TargetNUInt(R10); return true; } if (name.Equals("r11", StringComparison.OrdinalIgnoreCase)) { value = new TargetNUInt(R11); return true; } if (name.Equals("r12", StringComparison.OrdinalIgnoreCase)) { value = new TargetNUInt(R12); return true; } if (name.Equals("sp", StringComparison.OrdinalIgnoreCase)) { value = new TargetNUInt(Sp); return true; } if (name.Equals("lr", StringComparison.OrdinalIgnoreCase)) { value = new TargetNUInt(Lr); return true; } if (name.Equals("pc", StringComparison.OrdinalIgnoreCase)) { value = new TargetNUInt(Pc); return true; } if (name.Equals("cpsr", StringComparison.OrdinalIgnoreCase)) { value = new TargetNUInt(Cpsr); return true; } if (name.Equals("fpscr", StringComparison.OrdinalIgnoreCase)) { value = new TargetNUInt(Fpscr); return true; } return false; } public bool TrySetRegister(int number, TargetNUInt value) { switch (number) { case 0: R0 = (uint)value.Value; return true; case 1: R1 = (uint)value.Value; return true; case 2: R2 = (uint)value.Value; return true; case 3: R3 = (uint)value.Value; return true; case 4: R4 = (uint)value.Value; return true; case 5: R5 = (uint)value.Value; return true; case 6: R6 = (uint)value.Value; return true; case 7: R7 = (uint)value.Value; return true; case 8: R8 = (uint)value.Value; return true; case 9: R9 = (uint)value.Value; return true; case 10: R10 = (uint)value.Value; return true; case 11: R11 = (uint)value.Value; return true; case 12: R12 = (uint)value.Value; return true; case 13: Sp = (uint)value.Value; return true; case 14: Lr = (uint)value.Value; return true; case 15: Pc = (uint)value.Value; return true; case 16: Cpsr = (uint)value.Value; return true; default: return false; } } public bool TryReadRegister(int number, out TargetNUInt value) { switch (number) { case 0: value = new TargetNUInt(R0); return true; case 1: value = new TargetNUInt(R1); return true; case 2: value = new TargetNUInt(R2); return true; case 3: value = new TargetNUInt(R3); return true; case 4: value = new TargetNUInt(R4); return true; case 5: value = new TargetNUInt(R5); return true; case 6: value = new TargetNUInt(R6); return true; case 7: value = new TargetNUInt(R7); return true; case 8: value = new TargetNUInt(R8); return true; case 9: value = new TargetNUInt(R9); return true; case 10: value = new TargetNUInt(R10); return true; case 11: value = new TargetNUInt(R11); return true; case 12: value = new TargetNUInt(R12); return true; case 13: value = new TargetNUInt(Sp); return true; case 14: value = new TargetNUInt(Lr); return true; case 15: value = new TargetNUInt(Pc); return true; case 16: value = new TargetNUInt(Cpsr); return true; default: value = default; return false; } } // Control flags [FieldOffset(0x0)] public uint ContextFlags; #region General registers [Register(RegisterType.General)] [FieldOffset(0x4)] public uint R0; [Register(RegisterType.General)] [FieldOffset(0x8)] public uint R1; [Register(RegisterType.General)] [FieldOffset(0xc)] public uint R2; [Register(RegisterType.General)] [FieldOffset(0x10)] public uint R3; [Register(RegisterType.General)] [FieldOffset(0x14)] public uint R4; [Register(RegisterType.General)] [FieldOffset(0x18)] public uint R5; [Register(RegisterType.General)] [FieldOffset(0x1c)] public uint R6; [Register(RegisterType.General)] [FieldOffset(0x20)] public uint R7; [Register(RegisterType.General)] [FieldOffset(0x24)] public uint R8; [Register(RegisterType.General)] [FieldOffset(0x28)] public uint R9; [Register(RegisterType.General)] [FieldOffset(0x2c)] public uint R10; [Register(RegisterType.General | RegisterType.FramePointer)] [FieldOffset(0x30)] public uint R11; [Register(RegisterType.General)] [FieldOffset(0x34)] public uint R12; #endregion #region Control Registers [Register(RegisterType.Control | RegisterType.StackPointer)] [FieldOffset(0x38)] public uint Sp; [Register(RegisterType.Control)] [FieldOffset(0x3c)] public uint Lr; [Register(RegisterType.Control | RegisterType.ProgramCounter)] [FieldOffset(0x40)] public uint Pc; [Register(RegisterType.General)] [FieldOffset(0x44)] public uint Cpsr; #endregion #region Floating Point/NEON Registers [Register(RegisterType.FloatingPoint)] [FieldOffset(0x48)] public uint Fpscr; [FieldOffset(0x50)] public unsafe fixed ulong D[32]; [Register(RegisterType.FloatingPoint)] [FieldOffset(0x50)] public M128A Q0; [Register(RegisterType.FloatingPoint)] [FieldOffset(0x60)] public M128A Q1; [Register(RegisterType.FloatingPoint)] [FieldOffset(0x70)] public M128A Q2; [Register(RegisterType.FloatingPoint)] [FieldOffset(0x80)] public M128A Q3; [Register(RegisterType.FloatingPoint)] [FieldOffset(0x90)] public M128A Q4; [Register(RegisterType.FloatingPoint)] [FieldOffset(0xa0)] public M128A Q5; [Register(RegisterType.FloatingPoint)] [FieldOffset(0xb0)] public M128A Q6; [Register(RegisterType.FloatingPoint)] [FieldOffset(0xc0)] public M128A Q7; [Register(RegisterType.FloatingPoint)] [FieldOffset(0xd0)] public M128A Q8; [Register(RegisterType.FloatingPoint)] [FieldOffset(0xe0)] public M128A Q9; [Register(RegisterType.FloatingPoint)] [FieldOffset(0xf0)] public M128A Q10; [Register(RegisterType.FloatingPoint)] [FieldOffset(0x100)] public M128A Q11; [Register(RegisterType.FloatingPoint)] [FieldOffset(0x110)] public M128A Q12; [Register(RegisterType.FloatingPoint)] [FieldOffset(0x120)] public M128A Q13; [Register(RegisterType.FloatingPoint)] [FieldOffset(0x130)] public M128A Q14; [Register(RegisterType.FloatingPoint)] [FieldOffset(0x140)] public M128A Q15; #endregion #region Debug registers [Register(RegisterType.Debug)] [FieldOffset(0x150)] public unsafe fixed uint Bvr[8]; [Register(RegisterType.Debug)] [FieldOffset(0x170)] public unsafe fixed uint Bcr[8]; [Register(RegisterType.Debug)] [FieldOffset(0x190)] public unsafe fixed uint Wvr[1]; [Register(RegisterType.Debug)] [FieldOffset(0x194)] public unsafe fixed uint Wcr[1]; #endregion [FieldOffset(0x198)] public ulong Padding; }