1a63d08c9SGreg Clayton //===-- RegisterContextDarwin_arm.cpp ---------------------------*- C++ -*-===// 2a63d08c9SGreg Clayton // 3a63d08c9SGreg Clayton // The LLVM Compiler Infrastructure 4a63d08c9SGreg Clayton // 5a63d08c9SGreg Clayton // This file is distributed under the University of Illinois Open Source 6a63d08c9SGreg Clayton // License. See LICENSE.TXT for details. 7a63d08c9SGreg Clayton // 8a63d08c9SGreg Clayton //===----------------------------------------------------------------------===// 9a63d08c9SGreg Clayton 10a67dd8fcSPeter Collingbourne #if defined(__APPLE__) 11a67dd8fcSPeter Collingbourne 12a63d08c9SGreg Clayton #include "RegisterContextDarwin_arm.h" 13a63d08c9SGreg Clayton 14a63d08c9SGreg Clayton // C Includes 15a63d08c9SGreg Clayton #include <mach/mach_types.h> 16a63d08c9SGreg Clayton #include <mach/thread_act.h> 17a63d08c9SGreg Clayton 18a63d08c9SGreg Clayton // C++ Includes 19a63d08c9SGreg Clayton // Other libraries and framework includes 20a63d08c9SGreg Clayton #include "lldb/Core/DataBufferHeap.h" 21a63d08c9SGreg Clayton #include "lldb/Core/DataExtractor.h" 22a63d08c9SGreg Clayton #include "lldb/Core/Log.h" 23a63d08c9SGreg Clayton #include "lldb/Core/RegisterValue.h" 24a63d08c9SGreg Clayton #include "lldb/Core/Scalar.h" 25a63d08c9SGreg Clayton #include "lldb/Host/Endian.h" 2612a19904SDaniel Dunbar #include "llvm/Support/Compiler.h" 2712a19904SDaniel Dunbar 28dce502edSGreg Clayton #include "Plugins/Process/Utility/InstructionUtils.h" 29dce502edSGreg Clayton 3012a19904SDaniel Dunbar // Support building against older versions of LLVM, this macro was added 3112a19904SDaniel Dunbar // recently. 3212a19904SDaniel Dunbar #ifndef LLVM_EXTENSION 3312a19904SDaniel Dunbar #define LLVM_EXTENSION 3412a19904SDaniel Dunbar #endif 35a63d08c9SGreg Clayton 36a63d08c9SGreg Clayton // Project includes 37a63d08c9SGreg Clayton #include "ARM_GCC_Registers.h" 38a63d08c9SGreg Clayton #include "ARM_DWARF_Registers.h" 39a63d08c9SGreg Clayton 4028606954SSaleem Abdulrasool #include "llvm/ADT/STLExtras.h" 4128606954SSaleem Abdulrasool 42a63d08c9SGreg Clayton using namespace lldb; 43a63d08c9SGreg Clayton using namespace lldb_private; 44a63d08c9SGreg Clayton 45a63d08c9SGreg Clayton enum 46a63d08c9SGreg Clayton { 47a63d08c9SGreg Clayton gpr_r0 = 0, 48a63d08c9SGreg Clayton gpr_r1, 49a63d08c9SGreg Clayton gpr_r2, 50a63d08c9SGreg Clayton gpr_r3, 51a63d08c9SGreg Clayton gpr_r4, 52a63d08c9SGreg Clayton gpr_r5, 53a63d08c9SGreg Clayton gpr_r6, 54a63d08c9SGreg Clayton gpr_r7, 55a63d08c9SGreg Clayton gpr_r8, 56a63d08c9SGreg Clayton gpr_r9, 57a63d08c9SGreg Clayton gpr_r10, 58a63d08c9SGreg Clayton gpr_r11, 59a63d08c9SGreg Clayton gpr_r12, 60a63d08c9SGreg Clayton gpr_r13, gpr_sp = gpr_r13, 61a63d08c9SGreg Clayton gpr_r14, gpr_lr = gpr_r14, 62a63d08c9SGreg Clayton gpr_r15, gpr_pc = gpr_r15, 63a63d08c9SGreg Clayton gpr_cpsr, 64a63d08c9SGreg Clayton 65a63d08c9SGreg Clayton fpu_s0, 66a63d08c9SGreg Clayton fpu_s1, 67a63d08c9SGreg Clayton fpu_s2, 68a63d08c9SGreg Clayton fpu_s3, 69a63d08c9SGreg Clayton fpu_s4, 70a63d08c9SGreg Clayton fpu_s5, 71a63d08c9SGreg Clayton fpu_s6, 72a63d08c9SGreg Clayton fpu_s7, 73a63d08c9SGreg Clayton fpu_s8, 74a63d08c9SGreg Clayton fpu_s9, 75a63d08c9SGreg Clayton fpu_s10, 76a63d08c9SGreg Clayton fpu_s11, 77a63d08c9SGreg Clayton fpu_s12, 78a63d08c9SGreg Clayton fpu_s13, 79a63d08c9SGreg Clayton fpu_s14, 80a63d08c9SGreg Clayton fpu_s15, 81a63d08c9SGreg Clayton fpu_s16, 82a63d08c9SGreg Clayton fpu_s17, 83a63d08c9SGreg Clayton fpu_s18, 84a63d08c9SGreg Clayton fpu_s19, 85a63d08c9SGreg Clayton fpu_s20, 86a63d08c9SGreg Clayton fpu_s21, 87a63d08c9SGreg Clayton fpu_s22, 88a63d08c9SGreg Clayton fpu_s23, 89a63d08c9SGreg Clayton fpu_s24, 90a63d08c9SGreg Clayton fpu_s25, 91a63d08c9SGreg Clayton fpu_s26, 92a63d08c9SGreg Clayton fpu_s27, 93a63d08c9SGreg Clayton fpu_s28, 94a63d08c9SGreg Clayton fpu_s29, 95a63d08c9SGreg Clayton fpu_s30, 96a63d08c9SGreg Clayton fpu_s31, 97a63d08c9SGreg Clayton fpu_fpscr, 98a63d08c9SGreg Clayton 99a63d08c9SGreg Clayton exc_exception, 100a63d08c9SGreg Clayton exc_fsr, 101a63d08c9SGreg Clayton exc_far, 102a63d08c9SGreg Clayton 103a63d08c9SGreg Clayton dbg_bvr0, 104a63d08c9SGreg Clayton dbg_bvr1, 105a63d08c9SGreg Clayton dbg_bvr2, 106a63d08c9SGreg Clayton dbg_bvr3, 107a63d08c9SGreg Clayton dbg_bvr4, 108a63d08c9SGreg Clayton dbg_bvr5, 109a63d08c9SGreg Clayton dbg_bvr6, 110a63d08c9SGreg Clayton dbg_bvr7, 111a63d08c9SGreg Clayton dbg_bvr8, 112a63d08c9SGreg Clayton dbg_bvr9, 113a63d08c9SGreg Clayton dbg_bvr10, 114a63d08c9SGreg Clayton dbg_bvr11, 115a63d08c9SGreg Clayton dbg_bvr12, 116a63d08c9SGreg Clayton dbg_bvr13, 117a63d08c9SGreg Clayton dbg_bvr14, 118a63d08c9SGreg Clayton dbg_bvr15, 119a63d08c9SGreg Clayton 120a63d08c9SGreg Clayton dbg_bcr0, 121a63d08c9SGreg Clayton dbg_bcr1, 122a63d08c9SGreg Clayton dbg_bcr2, 123a63d08c9SGreg Clayton dbg_bcr3, 124a63d08c9SGreg Clayton dbg_bcr4, 125a63d08c9SGreg Clayton dbg_bcr5, 126a63d08c9SGreg Clayton dbg_bcr6, 127a63d08c9SGreg Clayton dbg_bcr7, 128a63d08c9SGreg Clayton dbg_bcr8, 129a63d08c9SGreg Clayton dbg_bcr9, 130a63d08c9SGreg Clayton dbg_bcr10, 131a63d08c9SGreg Clayton dbg_bcr11, 132a63d08c9SGreg Clayton dbg_bcr12, 133a63d08c9SGreg Clayton dbg_bcr13, 134a63d08c9SGreg Clayton dbg_bcr14, 135a63d08c9SGreg Clayton dbg_bcr15, 136a63d08c9SGreg Clayton 137a63d08c9SGreg Clayton dbg_wvr0, 138a63d08c9SGreg Clayton dbg_wvr1, 139a63d08c9SGreg Clayton dbg_wvr2, 140a63d08c9SGreg Clayton dbg_wvr3, 141a63d08c9SGreg Clayton dbg_wvr4, 142a63d08c9SGreg Clayton dbg_wvr5, 143a63d08c9SGreg Clayton dbg_wvr6, 144a63d08c9SGreg Clayton dbg_wvr7, 145a63d08c9SGreg Clayton dbg_wvr8, 146a63d08c9SGreg Clayton dbg_wvr9, 147a63d08c9SGreg Clayton dbg_wvr10, 148a63d08c9SGreg Clayton dbg_wvr11, 149a63d08c9SGreg Clayton dbg_wvr12, 150a63d08c9SGreg Clayton dbg_wvr13, 151a63d08c9SGreg Clayton dbg_wvr14, 152a63d08c9SGreg Clayton dbg_wvr15, 153a63d08c9SGreg Clayton 154a63d08c9SGreg Clayton dbg_wcr0, 155a63d08c9SGreg Clayton dbg_wcr1, 156a63d08c9SGreg Clayton dbg_wcr2, 157a63d08c9SGreg Clayton dbg_wcr3, 158a63d08c9SGreg Clayton dbg_wcr4, 159a63d08c9SGreg Clayton dbg_wcr5, 160a63d08c9SGreg Clayton dbg_wcr6, 161a63d08c9SGreg Clayton dbg_wcr7, 162a63d08c9SGreg Clayton dbg_wcr8, 163a63d08c9SGreg Clayton dbg_wcr9, 164a63d08c9SGreg Clayton dbg_wcr10, 165a63d08c9SGreg Clayton dbg_wcr11, 166a63d08c9SGreg Clayton dbg_wcr12, 167a63d08c9SGreg Clayton dbg_wcr13, 168a63d08c9SGreg Clayton dbg_wcr14, 169a63d08c9SGreg Clayton dbg_wcr15, 170a63d08c9SGreg Clayton 171a63d08c9SGreg Clayton k_num_registers 172a63d08c9SGreg Clayton }; 173a63d08c9SGreg Clayton 174a63d08c9SGreg Clayton 175a63d08c9SGreg Clayton RegisterContextDarwin_arm::RegisterContextDarwin_arm(Thread &thread, uint32_t concrete_frame_idx) : 176a63d08c9SGreg Clayton RegisterContext(thread, concrete_frame_idx), 177a63d08c9SGreg Clayton gpr(), 178a63d08c9SGreg Clayton fpu(), 179a63d08c9SGreg Clayton exc() 180a63d08c9SGreg Clayton { 181a63d08c9SGreg Clayton uint32_t i; 182a63d08c9SGreg Clayton for (i=0; i<kNumErrors; i++) 183a63d08c9SGreg Clayton { 184a63d08c9SGreg Clayton gpr_errs[i] = -1; 185a63d08c9SGreg Clayton fpu_errs[i] = -1; 186a63d08c9SGreg Clayton exc_errs[i] = -1; 187a63d08c9SGreg Clayton } 188a63d08c9SGreg Clayton } 189a63d08c9SGreg Clayton 190a63d08c9SGreg Clayton RegisterContextDarwin_arm::~RegisterContextDarwin_arm() 191a63d08c9SGreg Clayton { 192a63d08c9SGreg Clayton } 193a63d08c9SGreg Clayton 194a63d08c9SGreg Clayton 195a63d08c9SGreg Clayton #define GPR_OFFSET(idx) ((idx) * 4) 196a63d08c9SGreg Clayton #define FPU_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextDarwin_arm::GPR)) 197a63d08c9SGreg Clayton #define EXC_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU)) 19812a19904SDaniel Dunbar #define DBG_OFFSET(reg) ((LLVM_EXTENSION offsetof (RegisterContextDarwin_arm::DBG, reg) + sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU) + sizeof (RegisterContextDarwin_arm::EXC))) 199a63d08c9SGreg Clayton 200e979eda7SJohnny Chen #define DEFINE_DBG(reg, i) #reg, NULL, sizeof(((RegisterContextDarwin_arm::DBG *)NULL)->reg[i]), DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, dbg_##reg##i }, NULL, NULL 201a63d08c9SGreg Clayton #define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU) + sizeof (RegisterContextDarwin_arm::EXC)) 202a63d08c9SGreg Clayton 203a63d08c9SGreg Clayton static RegisterInfo g_register_infos[] = { 204a63d08c9SGreg Clayton // General purpose registers 205e979eda7SJohnny Chen // NAME ALT SZ OFFSET ENCODING FORMAT COMPILER DWARF GENERIC GDB LLDB NATIVE VALUE REGS INVALIDATE REGS 206e979eda7SJohnny Chen // ====== ======= == ============= ============= ============ =============== =============== ========================= ===================== ============= ========== =============== 207e979eda7SJohnny Chen { "r0", NULL, 4, GPR_OFFSET(0), eEncodingUint, eFormatHex, { gcc_r0, dwarf_r0, LLDB_INVALID_REGNUM, gdb_arm_r0, gpr_r0 }, NULL, NULL}, 208e979eda7SJohnny Chen { "r1", NULL, 4, GPR_OFFSET(1), eEncodingUint, eFormatHex, { gcc_r1, dwarf_r1, LLDB_INVALID_REGNUM, gdb_arm_r1, gpr_r1 }, NULL, NULL}, 209e979eda7SJohnny Chen { "r2", NULL, 4, GPR_OFFSET(2), eEncodingUint, eFormatHex, { gcc_r2, dwarf_r2, LLDB_INVALID_REGNUM, gdb_arm_r2, gpr_r2 }, NULL, NULL}, 210e979eda7SJohnny Chen { "r3", NULL, 4, GPR_OFFSET(3), eEncodingUint, eFormatHex, { gcc_r3, dwarf_r3, LLDB_INVALID_REGNUM, gdb_arm_r3, gpr_r3 }, NULL, NULL}, 211e979eda7SJohnny Chen { "r4", NULL, 4, GPR_OFFSET(4), eEncodingUint, eFormatHex, { gcc_r4, dwarf_r4, LLDB_INVALID_REGNUM, gdb_arm_r4, gpr_r4 }, NULL, NULL}, 212e979eda7SJohnny Chen { "r5", NULL, 4, GPR_OFFSET(5), eEncodingUint, eFormatHex, { gcc_r5, dwarf_r5, LLDB_INVALID_REGNUM, gdb_arm_r5, gpr_r5 }, NULL, NULL}, 213e979eda7SJohnny Chen { "r6", NULL, 4, GPR_OFFSET(6), eEncodingUint, eFormatHex, { gcc_r6, dwarf_r6, LLDB_INVALID_REGNUM, gdb_arm_r6, gpr_r6 }, NULL, NULL}, 214e979eda7SJohnny Chen { "r7", NULL, 4, GPR_OFFSET(7), eEncodingUint, eFormatHex, { gcc_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, gdb_arm_r7, gpr_r7 }, NULL, NULL}, 215e979eda7SJohnny Chen { "r8", NULL, 4, GPR_OFFSET(8), eEncodingUint, eFormatHex, { gcc_r8, dwarf_r8, LLDB_INVALID_REGNUM, gdb_arm_r8, gpr_r8 }, NULL, NULL}, 216e979eda7SJohnny Chen { "r9", NULL, 4, GPR_OFFSET(9), eEncodingUint, eFormatHex, { gcc_r9, dwarf_r9, LLDB_INVALID_REGNUM, gdb_arm_r9, gpr_r9 }, NULL, NULL}, 217e979eda7SJohnny Chen { "r10", NULL, 4, GPR_OFFSET(10), eEncodingUint, eFormatHex, { gcc_r10, dwarf_r10, LLDB_INVALID_REGNUM, gdb_arm_r10, gpr_r10 }, NULL, NULL}, 218e979eda7SJohnny Chen { "r11", NULL, 4, GPR_OFFSET(11), eEncodingUint, eFormatHex, { gcc_r11, dwarf_r11, LLDB_INVALID_REGNUM, gdb_arm_r11, gpr_r11 }, NULL, NULL}, 219e979eda7SJohnny Chen { "r12", NULL, 4, GPR_OFFSET(12), eEncodingUint, eFormatHex, { gcc_r12, dwarf_r12, LLDB_INVALID_REGNUM, gdb_arm_r12, gpr_r12 }, NULL, NULL}, 220e979eda7SJohnny Chen { "sp", "r13", 4, GPR_OFFSET(13), eEncodingUint, eFormatHex, { gcc_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, gdb_arm_sp, gpr_sp }, NULL, NULL}, 221e979eda7SJohnny Chen { "lr", "r14", 4, GPR_OFFSET(14), eEncodingUint, eFormatHex, { gcc_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, gdb_arm_lr, gpr_lr }, NULL, NULL}, 222e979eda7SJohnny Chen { "pc", "r15", 4, GPR_OFFSET(15), eEncodingUint, eFormatHex, { gcc_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, gdb_arm_pc, gpr_pc }, NULL, NULL}, 223e979eda7SJohnny Chen { "cpsr", "psr", 4, GPR_OFFSET(16), eEncodingUint, eFormatHex, { gcc_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, gdb_arm_cpsr, gpr_cpsr }, NULL, NULL}, 224a63d08c9SGreg Clayton 225e979eda7SJohnny Chen { "s0", NULL, 4, FPU_OFFSET(0), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, gdb_arm_s0, fpu_s0 }, NULL, NULL}, 226e979eda7SJohnny Chen { "s1", NULL, 4, FPU_OFFSET(1), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, gdb_arm_s1, fpu_s1 }, NULL, NULL}, 227e979eda7SJohnny Chen { "s2", NULL, 4, FPU_OFFSET(2), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, gdb_arm_s2, fpu_s2 }, NULL, NULL}, 228e979eda7SJohnny Chen { "s3", NULL, 4, FPU_OFFSET(3), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, gdb_arm_s3, fpu_s3 }, NULL, NULL}, 229e979eda7SJohnny Chen { "s4", NULL, 4, FPU_OFFSET(4), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, gdb_arm_s4, fpu_s4 }, NULL, NULL}, 230e979eda7SJohnny Chen { "s5", NULL, 4, FPU_OFFSET(5), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, gdb_arm_s5, fpu_s5 }, NULL, NULL}, 231e979eda7SJohnny Chen { "s6", NULL, 4, FPU_OFFSET(6), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, gdb_arm_s6, fpu_s6 }, NULL, NULL}, 232e979eda7SJohnny Chen { "s7", NULL, 4, FPU_OFFSET(7), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, gdb_arm_s7, fpu_s7 }, NULL, NULL}, 233e979eda7SJohnny Chen { "s8", NULL, 4, FPU_OFFSET(8), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, gdb_arm_s8, fpu_s8 }, NULL, NULL}, 234e979eda7SJohnny Chen { "s9", NULL, 4, FPU_OFFSET(9), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, gdb_arm_s9, fpu_s9 }, NULL, NULL}, 235e979eda7SJohnny Chen { "s10", NULL, 4, FPU_OFFSET(10), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, gdb_arm_s10, fpu_s10 }, NULL, NULL}, 236e979eda7SJohnny Chen { "s11", NULL, 4, FPU_OFFSET(11), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, gdb_arm_s11, fpu_s11 }, NULL, NULL}, 237e979eda7SJohnny Chen { "s12", NULL, 4, FPU_OFFSET(12), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, gdb_arm_s12, fpu_s12 }, NULL, NULL}, 238e979eda7SJohnny Chen { "s13", NULL, 4, FPU_OFFSET(13), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, gdb_arm_s13, fpu_s13 }, NULL, NULL}, 239e979eda7SJohnny Chen { "s14", NULL, 4, FPU_OFFSET(14), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, gdb_arm_s14, fpu_s14 }, NULL, NULL}, 240e979eda7SJohnny Chen { "s15", NULL, 4, FPU_OFFSET(15), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, gdb_arm_s15, fpu_s15 }, NULL, NULL}, 241e979eda7SJohnny Chen { "s16", NULL, 4, FPU_OFFSET(16), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, gdb_arm_s16, fpu_s16 }, NULL, NULL}, 242e979eda7SJohnny Chen { "s17", NULL, 4, FPU_OFFSET(17), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, gdb_arm_s17, fpu_s17 }, NULL, NULL}, 243e979eda7SJohnny Chen { "s18", NULL, 4, FPU_OFFSET(18), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, gdb_arm_s18, fpu_s18 }, NULL, NULL}, 244e979eda7SJohnny Chen { "s19", NULL, 4, FPU_OFFSET(19), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, gdb_arm_s19, fpu_s19 }, NULL, NULL}, 245e979eda7SJohnny Chen { "s20", NULL, 4, FPU_OFFSET(20), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, gdb_arm_s20, fpu_s20 }, NULL, NULL}, 246e979eda7SJohnny Chen { "s21", NULL, 4, FPU_OFFSET(21), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, gdb_arm_s21, fpu_s21 }, NULL, NULL}, 247e979eda7SJohnny Chen { "s22", NULL, 4, FPU_OFFSET(22), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, gdb_arm_s22, fpu_s22 }, NULL, NULL}, 248e979eda7SJohnny Chen { "s23", NULL, 4, FPU_OFFSET(23), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, gdb_arm_s23, fpu_s23 }, NULL, NULL}, 249e979eda7SJohnny Chen { "s24", NULL, 4, FPU_OFFSET(24), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, gdb_arm_s24, fpu_s24 }, NULL, NULL}, 250e979eda7SJohnny Chen { "s25", NULL, 4, FPU_OFFSET(25), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, gdb_arm_s25, fpu_s25 }, NULL, NULL}, 251e979eda7SJohnny Chen { "s26", NULL, 4, FPU_OFFSET(26), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, gdb_arm_s26, fpu_s26 }, NULL, NULL}, 252e979eda7SJohnny Chen { "s27", NULL, 4, FPU_OFFSET(27), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, gdb_arm_s27, fpu_s27 }, NULL, NULL}, 253e979eda7SJohnny Chen { "s28", NULL, 4, FPU_OFFSET(28), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, gdb_arm_s28, fpu_s28 }, NULL, NULL}, 254e979eda7SJohnny Chen { "s29", NULL, 4, FPU_OFFSET(29), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, gdb_arm_s29, fpu_s29 }, NULL, NULL}, 255e979eda7SJohnny Chen { "s30", NULL, 4, FPU_OFFSET(30), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, gdb_arm_s30, fpu_s30 }, NULL, NULL}, 256e979eda7SJohnny Chen { "s31", NULL, 4, FPU_OFFSET(31), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, gdb_arm_s31, fpu_s31 }, NULL, NULL}, 257e979eda7SJohnny Chen { "fpscr", NULL, 4, FPU_OFFSET(32), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, gdb_arm_fpscr, fpu_fpscr }, NULL, NULL}, 258a63d08c9SGreg Clayton 259e979eda7SJohnny Chen { "exception",NULL, 4, EXC_OFFSET(0), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_exception }, NULL, NULL}, 260e979eda7SJohnny Chen { "fsr", NULL, 4, EXC_OFFSET(1), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_fsr }, NULL, NULL}, 261e979eda7SJohnny Chen { "far", NULL, 4, EXC_OFFSET(2), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_far }, NULL, NULL}, 262a63d08c9SGreg Clayton 263a63d08c9SGreg Clayton { DEFINE_DBG (bvr, 0) }, 264a63d08c9SGreg Clayton { DEFINE_DBG (bvr, 1) }, 265a63d08c9SGreg Clayton { DEFINE_DBG (bvr, 2) }, 266a63d08c9SGreg Clayton { DEFINE_DBG (bvr, 3) }, 267a63d08c9SGreg Clayton { DEFINE_DBG (bvr, 4) }, 268a63d08c9SGreg Clayton { DEFINE_DBG (bvr, 5) }, 269a63d08c9SGreg Clayton { DEFINE_DBG (bvr, 6) }, 270a63d08c9SGreg Clayton { DEFINE_DBG (bvr, 7) }, 271a63d08c9SGreg Clayton { DEFINE_DBG (bvr, 8) }, 272a63d08c9SGreg Clayton { DEFINE_DBG (bvr, 9) }, 273a63d08c9SGreg Clayton { DEFINE_DBG (bvr, 10) }, 274a63d08c9SGreg Clayton { DEFINE_DBG (bvr, 11) }, 275a63d08c9SGreg Clayton { DEFINE_DBG (bvr, 12) }, 276a63d08c9SGreg Clayton { DEFINE_DBG (bvr, 13) }, 277a63d08c9SGreg Clayton { DEFINE_DBG (bvr, 14) }, 278a63d08c9SGreg Clayton { DEFINE_DBG (bvr, 15) }, 279a63d08c9SGreg Clayton 280a63d08c9SGreg Clayton { DEFINE_DBG (bcr, 0) }, 281a63d08c9SGreg Clayton { DEFINE_DBG (bcr, 1) }, 282a63d08c9SGreg Clayton { DEFINE_DBG (bcr, 2) }, 283a63d08c9SGreg Clayton { DEFINE_DBG (bcr, 3) }, 284a63d08c9SGreg Clayton { DEFINE_DBG (bcr, 4) }, 285a63d08c9SGreg Clayton { DEFINE_DBG (bcr, 5) }, 286a63d08c9SGreg Clayton { DEFINE_DBG (bcr, 6) }, 287a63d08c9SGreg Clayton { DEFINE_DBG (bcr, 7) }, 288a63d08c9SGreg Clayton { DEFINE_DBG (bcr, 8) }, 289a63d08c9SGreg Clayton { DEFINE_DBG (bcr, 9) }, 290a63d08c9SGreg Clayton { DEFINE_DBG (bcr, 10) }, 291a63d08c9SGreg Clayton { DEFINE_DBG (bcr, 11) }, 292a63d08c9SGreg Clayton { DEFINE_DBG (bcr, 12) }, 293a63d08c9SGreg Clayton { DEFINE_DBG (bcr, 13) }, 294a63d08c9SGreg Clayton { DEFINE_DBG (bcr, 14) }, 295a63d08c9SGreg Clayton { DEFINE_DBG (bcr, 15) }, 296a63d08c9SGreg Clayton 297a63d08c9SGreg Clayton { DEFINE_DBG (wvr, 0) }, 298a63d08c9SGreg Clayton { DEFINE_DBG (wvr, 1) }, 299a63d08c9SGreg Clayton { DEFINE_DBG (wvr, 2) }, 300a63d08c9SGreg Clayton { DEFINE_DBG (wvr, 3) }, 301a63d08c9SGreg Clayton { DEFINE_DBG (wvr, 4) }, 302a63d08c9SGreg Clayton { DEFINE_DBG (wvr, 5) }, 303a63d08c9SGreg Clayton { DEFINE_DBG (wvr, 6) }, 304a63d08c9SGreg Clayton { DEFINE_DBG (wvr, 7) }, 305a63d08c9SGreg Clayton { DEFINE_DBG (wvr, 8) }, 306a63d08c9SGreg Clayton { DEFINE_DBG (wvr, 9) }, 307a63d08c9SGreg Clayton { DEFINE_DBG (wvr, 10) }, 308a63d08c9SGreg Clayton { DEFINE_DBG (wvr, 11) }, 309a63d08c9SGreg Clayton { DEFINE_DBG (wvr, 12) }, 310a63d08c9SGreg Clayton { DEFINE_DBG (wvr, 13) }, 311a63d08c9SGreg Clayton { DEFINE_DBG (wvr, 14) }, 312a63d08c9SGreg Clayton { DEFINE_DBG (wvr, 15) }, 313a63d08c9SGreg Clayton 314a63d08c9SGreg Clayton { DEFINE_DBG (wcr, 0) }, 315a63d08c9SGreg Clayton { DEFINE_DBG (wcr, 1) }, 316a63d08c9SGreg Clayton { DEFINE_DBG (wcr, 2) }, 317a63d08c9SGreg Clayton { DEFINE_DBG (wcr, 3) }, 318a63d08c9SGreg Clayton { DEFINE_DBG (wcr, 4) }, 319a63d08c9SGreg Clayton { DEFINE_DBG (wcr, 5) }, 320a63d08c9SGreg Clayton { DEFINE_DBG (wcr, 6) }, 321a63d08c9SGreg Clayton { DEFINE_DBG (wcr, 7) }, 322a63d08c9SGreg Clayton { DEFINE_DBG (wcr, 8) }, 323a63d08c9SGreg Clayton { DEFINE_DBG (wcr, 9) }, 324a63d08c9SGreg Clayton { DEFINE_DBG (wcr, 10) }, 325a63d08c9SGreg Clayton { DEFINE_DBG (wcr, 11) }, 326a63d08c9SGreg Clayton { DEFINE_DBG (wcr, 12) }, 327a63d08c9SGreg Clayton { DEFINE_DBG (wcr, 13) }, 328a63d08c9SGreg Clayton { DEFINE_DBG (wcr, 14) }, 329a63d08c9SGreg Clayton { DEFINE_DBG (wcr, 15) } 330a63d08c9SGreg Clayton }; 331a63d08c9SGreg Clayton 332a63d08c9SGreg Clayton // General purpose registers 333a63d08c9SGreg Clayton static uint32_t 334a63d08c9SGreg Clayton g_gpr_regnums[] = 335a63d08c9SGreg Clayton { 336a63d08c9SGreg Clayton gpr_r0, 337a63d08c9SGreg Clayton gpr_r1, 338a63d08c9SGreg Clayton gpr_r2, 339a63d08c9SGreg Clayton gpr_r3, 340a63d08c9SGreg Clayton gpr_r4, 341a63d08c9SGreg Clayton gpr_r5, 342a63d08c9SGreg Clayton gpr_r6, 343a63d08c9SGreg Clayton gpr_r7, 344a63d08c9SGreg Clayton gpr_r8, 345a63d08c9SGreg Clayton gpr_r9, 346a63d08c9SGreg Clayton gpr_r10, 347a63d08c9SGreg Clayton gpr_r11, 348a63d08c9SGreg Clayton gpr_r12, 349a63d08c9SGreg Clayton gpr_sp, 350a63d08c9SGreg Clayton gpr_lr, 351a63d08c9SGreg Clayton gpr_pc, 352a63d08c9SGreg Clayton gpr_cpsr 353a63d08c9SGreg Clayton }; 354a63d08c9SGreg Clayton 355a63d08c9SGreg Clayton // Floating point registers 356a63d08c9SGreg Clayton static uint32_t 357a63d08c9SGreg Clayton g_fpu_regnums[] = 358a63d08c9SGreg Clayton { 359a63d08c9SGreg Clayton fpu_s0, 360a63d08c9SGreg Clayton fpu_s1, 361a63d08c9SGreg Clayton fpu_s2, 362a63d08c9SGreg Clayton fpu_s3, 363a63d08c9SGreg Clayton fpu_s4, 364a63d08c9SGreg Clayton fpu_s5, 365a63d08c9SGreg Clayton fpu_s6, 366a63d08c9SGreg Clayton fpu_s7, 367a63d08c9SGreg Clayton fpu_s8, 368a63d08c9SGreg Clayton fpu_s9, 369a63d08c9SGreg Clayton fpu_s10, 370a63d08c9SGreg Clayton fpu_s11, 371a63d08c9SGreg Clayton fpu_s12, 372a63d08c9SGreg Clayton fpu_s13, 373a63d08c9SGreg Clayton fpu_s14, 374a63d08c9SGreg Clayton fpu_s15, 375a63d08c9SGreg Clayton fpu_s16, 376a63d08c9SGreg Clayton fpu_s17, 377a63d08c9SGreg Clayton fpu_s18, 378a63d08c9SGreg Clayton fpu_s19, 379a63d08c9SGreg Clayton fpu_s20, 380a63d08c9SGreg Clayton fpu_s21, 381a63d08c9SGreg Clayton fpu_s22, 382a63d08c9SGreg Clayton fpu_s23, 383a63d08c9SGreg Clayton fpu_s24, 384a63d08c9SGreg Clayton fpu_s25, 385a63d08c9SGreg Clayton fpu_s26, 386a63d08c9SGreg Clayton fpu_s27, 387a63d08c9SGreg Clayton fpu_s28, 388a63d08c9SGreg Clayton fpu_s29, 389a63d08c9SGreg Clayton fpu_s30, 390a63d08c9SGreg Clayton fpu_s31, 391a63d08c9SGreg Clayton fpu_fpscr, 392a63d08c9SGreg Clayton }; 393a63d08c9SGreg Clayton 394a63d08c9SGreg Clayton // Exception registers 395a63d08c9SGreg Clayton 396a63d08c9SGreg Clayton static uint32_t 397a63d08c9SGreg Clayton g_exc_regnums[] = 398a63d08c9SGreg Clayton { 399a63d08c9SGreg Clayton exc_exception, 400a63d08c9SGreg Clayton exc_fsr, 401a63d08c9SGreg Clayton exc_far, 402a63d08c9SGreg Clayton }; 403a63d08c9SGreg Clayton 40428606954SSaleem Abdulrasool static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos); 405a63d08c9SGreg Clayton 406a63d08c9SGreg Clayton void 407a63d08c9SGreg Clayton RegisterContextDarwin_arm::InvalidateAllRegisters () 408a63d08c9SGreg Clayton { 409a63d08c9SGreg Clayton InvalidateAllRegisterStates(); 410a63d08c9SGreg Clayton } 411a63d08c9SGreg Clayton 412a63d08c9SGreg Clayton 413a63d08c9SGreg Clayton size_t 414a63d08c9SGreg Clayton RegisterContextDarwin_arm::GetRegisterCount () 415a63d08c9SGreg Clayton { 416a63d08c9SGreg Clayton assert(k_num_register_infos == k_num_registers); 417a63d08c9SGreg Clayton return k_num_registers; 418a63d08c9SGreg Clayton } 419a63d08c9SGreg Clayton 420a63d08c9SGreg Clayton const RegisterInfo * 421c7bece56SGreg Clayton RegisterContextDarwin_arm::GetRegisterInfoAtIndex (size_t reg) 422a63d08c9SGreg Clayton { 423a63d08c9SGreg Clayton assert(k_num_register_infos == k_num_registers); 424a63d08c9SGreg Clayton if (reg < k_num_registers) 425a63d08c9SGreg Clayton return &g_register_infos[reg]; 426a63d08c9SGreg Clayton return NULL; 427a63d08c9SGreg Clayton } 428a63d08c9SGreg Clayton 429a63d08c9SGreg Clayton size_t 430a63d08c9SGreg Clayton RegisterContextDarwin_arm::GetRegisterInfosCount () 431a63d08c9SGreg Clayton { 432a63d08c9SGreg Clayton return k_num_register_infos; 433a63d08c9SGreg Clayton } 434a63d08c9SGreg Clayton 435a63d08c9SGreg Clayton const RegisterInfo * 436a63d08c9SGreg Clayton RegisterContextDarwin_arm::GetRegisterInfos () 437a63d08c9SGreg Clayton { 438a63d08c9SGreg Clayton return g_register_infos; 439a63d08c9SGreg Clayton } 440a63d08c9SGreg Clayton 441a63d08c9SGreg Clayton 442a63d08c9SGreg Clayton // Number of registers in each register set 44328606954SSaleem Abdulrasool const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums); 44428606954SSaleem Abdulrasool const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums); 44528606954SSaleem Abdulrasool const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums); 446a63d08c9SGreg Clayton 447a63d08c9SGreg Clayton //---------------------------------------------------------------------- 448a63d08c9SGreg Clayton // Register set definitions. The first definitions at register set index 449a63d08c9SGreg Clayton // of zero is for all registers, followed by other registers sets. The 450a63d08c9SGreg Clayton // register information for the all register set need not be filled in. 451a63d08c9SGreg Clayton //---------------------------------------------------------------------- 452a63d08c9SGreg Clayton static const RegisterSet g_reg_sets[] = 453a63d08c9SGreg Clayton { 454a63d08c9SGreg Clayton { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, }, 455a63d08c9SGreg Clayton { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums }, 456a63d08c9SGreg Clayton { "Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums } 457a63d08c9SGreg Clayton }; 458a63d08c9SGreg Clayton 45928606954SSaleem Abdulrasool const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets); 460a63d08c9SGreg Clayton 461a63d08c9SGreg Clayton 462a63d08c9SGreg Clayton size_t 463a63d08c9SGreg Clayton RegisterContextDarwin_arm::GetRegisterSetCount () 464a63d08c9SGreg Clayton { 465a63d08c9SGreg Clayton return k_num_regsets; 466a63d08c9SGreg Clayton } 467a63d08c9SGreg Clayton 468a63d08c9SGreg Clayton const RegisterSet * 469c7bece56SGreg Clayton RegisterContextDarwin_arm::GetRegisterSet (size_t reg_set) 470a63d08c9SGreg Clayton { 471a63d08c9SGreg Clayton if (reg_set < k_num_regsets) 472a63d08c9SGreg Clayton return &g_reg_sets[reg_set]; 473a63d08c9SGreg Clayton return NULL; 474a63d08c9SGreg Clayton } 475a63d08c9SGreg Clayton 476a63d08c9SGreg Clayton 477a63d08c9SGreg Clayton //---------------------------------------------------------------------- 478*aaa0ba31SBruce Mitchener // Register information definitions for 32 bit i386. 479a63d08c9SGreg Clayton //---------------------------------------------------------------------- 480a63d08c9SGreg Clayton int 481a63d08c9SGreg Clayton RegisterContextDarwin_arm::GetSetForNativeRegNum (int reg) 482a63d08c9SGreg Clayton { 483a63d08c9SGreg Clayton if (reg < fpu_s0) 484a63d08c9SGreg Clayton return GPRRegSet; 485a63d08c9SGreg Clayton else if (reg < exc_exception) 486a63d08c9SGreg Clayton return FPURegSet; 487a63d08c9SGreg Clayton else if (reg < k_num_registers) 488a63d08c9SGreg Clayton return EXCRegSet; 489a63d08c9SGreg Clayton return -1; 490a63d08c9SGreg Clayton } 491a63d08c9SGreg Clayton 492a63d08c9SGreg Clayton int 493a63d08c9SGreg Clayton RegisterContextDarwin_arm::ReadGPR (bool force) 494a63d08c9SGreg Clayton { 495a63d08c9SGreg Clayton int set = GPRRegSet; 496a63d08c9SGreg Clayton if (force || !RegisterSetIsCached(set)) 497a63d08c9SGreg Clayton { 498a63d08c9SGreg Clayton SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr)); 499a63d08c9SGreg Clayton } 500a63d08c9SGreg Clayton return GetError(GPRRegSet, Read); 501a63d08c9SGreg Clayton } 502a63d08c9SGreg Clayton 503a63d08c9SGreg Clayton int 504a63d08c9SGreg Clayton RegisterContextDarwin_arm::ReadFPU (bool force) 505a63d08c9SGreg Clayton { 506a63d08c9SGreg Clayton int set = FPURegSet; 507a63d08c9SGreg Clayton if (force || !RegisterSetIsCached(set)) 508a63d08c9SGreg Clayton { 509a63d08c9SGreg Clayton SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu)); 510a63d08c9SGreg Clayton } 511a63d08c9SGreg Clayton return GetError(FPURegSet, Read); 512a63d08c9SGreg Clayton } 513a63d08c9SGreg Clayton 514a63d08c9SGreg Clayton int 515a63d08c9SGreg Clayton RegisterContextDarwin_arm::ReadEXC (bool force) 516a63d08c9SGreg Clayton { 517a63d08c9SGreg Clayton int set = EXCRegSet; 518a63d08c9SGreg Clayton if (force || !RegisterSetIsCached(set)) 519a63d08c9SGreg Clayton { 520a63d08c9SGreg Clayton SetError(set, Read, DoReadEXC(GetThreadID(), set, exc)); 521a63d08c9SGreg Clayton } 522a63d08c9SGreg Clayton return GetError(EXCRegSet, Read); 523a63d08c9SGreg Clayton } 524a63d08c9SGreg Clayton 525a63d08c9SGreg Clayton int 526a63d08c9SGreg Clayton RegisterContextDarwin_arm::ReadDBG (bool force) 527a63d08c9SGreg Clayton { 528a63d08c9SGreg Clayton int set = DBGRegSet; 529a63d08c9SGreg Clayton if (force || !RegisterSetIsCached(set)) 530a63d08c9SGreg Clayton { 531a63d08c9SGreg Clayton SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg)); 532a63d08c9SGreg Clayton } 533a63d08c9SGreg Clayton return GetError(DBGRegSet, Read); 534a63d08c9SGreg Clayton } 535a63d08c9SGreg Clayton 536a63d08c9SGreg Clayton int 537a63d08c9SGreg Clayton RegisterContextDarwin_arm::WriteGPR () 538a63d08c9SGreg Clayton { 539a63d08c9SGreg Clayton int set = GPRRegSet; 540a63d08c9SGreg Clayton if (!RegisterSetIsCached(set)) 541a63d08c9SGreg Clayton { 542a63d08c9SGreg Clayton SetError (set, Write, -1); 543a63d08c9SGreg Clayton return KERN_INVALID_ARGUMENT; 544a63d08c9SGreg Clayton } 545a63d08c9SGreg Clayton SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr)); 546a63d08c9SGreg Clayton SetError (set, Read, -1); 547a63d08c9SGreg Clayton return GetError(GPRRegSet, Write); 548a63d08c9SGreg Clayton } 549a63d08c9SGreg Clayton 550a63d08c9SGreg Clayton int 551a63d08c9SGreg Clayton RegisterContextDarwin_arm::WriteFPU () 552a63d08c9SGreg Clayton { 553a63d08c9SGreg Clayton int set = FPURegSet; 554a63d08c9SGreg Clayton if (!RegisterSetIsCached(set)) 555a63d08c9SGreg Clayton { 556a63d08c9SGreg Clayton SetError (set, Write, -1); 557a63d08c9SGreg Clayton return KERN_INVALID_ARGUMENT; 558a63d08c9SGreg Clayton } 559a63d08c9SGreg Clayton SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu)); 560a63d08c9SGreg Clayton SetError (set, Read, -1); 561a63d08c9SGreg Clayton return GetError(FPURegSet, Write); 562a63d08c9SGreg Clayton } 563a63d08c9SGreg Clayton 564a63d08c9SGreg Clayton int 565a63d08c9SGreg Clayton RegisterContextDarwin_arm::WriteEXC () 566a63d08c9SGreg Clayton { 567a63d08c9SGreg Clayton int set = EXCRegSet; 568a63d08c9SGreg Clayton if (!RegisterSetIsCached(set)) 569a63d08c9SGreg Clayton { 570a63d08c9SGreg Clayton SetError (set, Write, -1); 571a63d08c9SGreg Clayton return KERN_INVALID_ARGUMENT; 572a63d08c9SGreg Clayton } 573a63d08c9SGreg Clayton SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc)); 574a63d08c9SGreg Clayton SetError (set, Read, -1); 575a63d08c9SGreg Clayton return GetError(EXCRegSet, Write); 576a63d08c9SGreg Clayton } 577a63d08c9SGreg Clayton 578a63d08c9SGreg Clayton int 579a63d08c9SGreg Clayton RegisterContextDarwin_arm::WriteDBG () 580a63d08c9SGreg Clayton { 581a63d08c9SGreg Clayton int set = DBGRegSet; 582a63d08c9SGreg Clayton if (!RegisterSetIsCached(set)) 583a63d08c9SGreg Clayton { 584a63d08c9SGreg Clayton SetError (set, Write, -1); 585a63d08c9SGreg Clayton return KERN_INVALID_ARGUMENT; 586a63d08c9SGreg Clayton } 587a63d08c9SGreg Clayton SetError (set, Write, DoWriteDBG(GetThreadID(), set, dbg)); 588a63d08c9SGreg Clayton SetError (set, Read, -1); 589a63d08c9SGreg Clayton return GetError(DBGRegSet, Write); 590a63d08c9SGreg Clayton } 591a63d08c9SGreg Clayton 592a63d08c9SGreg Clayton 593a63d08c9SGreg Clayton int 594a63d08c9SGreg Clayton RegisterContextDarwin_arm::ReadRegisterSet (uint32_t set, bool force) 595a63d08c9SGreg Clayton { 596a63d08c9SGreg Clayton switch (set) 597a63d08c9SGreg Clayton { 598a63d08c9SGreg Clayton case GPRRegSet: return ReadGPR(force); 599a63d08c9SGreg Clayton case FPURegSet: return ReadFPU(force); 600a63d08c9SGreg Clayton case EXCRegSet: return ReadEXC(force); 601a63d08c9SGreg Clayton case DBGRegSet: return ReadDBG(force); 602a63d08c9SGreg Clayton default: break; 603a63d08c9SGreg Clayton } 604a63d08c9SGreg Clayton return KERN_INVALID_ARGUMENT; 605a63d08c9SGreg Clayton } 606a63d08c9SGreg Clayton 607a63d08c9SGreg Clayton int 608a63d08c9SGreg Clayton RegisterContextDarwin_arm::WriteRegisterSet (uint32_t set) 609a63d08c9SGreg Clayton { 610a63d08c9SGreg Clayton // Make sure we have a valid context to set. 611a63d08c9SGreg Clayton if (RegisterSetIsCached(set)) 612a63d08c9SGreg Clayton { 613a63d08c9SGreg Clayton switch (set) 614a63d08c9SGreg Clayton { 615a63d08c9SGreg Clayton case GPRRegSet: return WriteGPR(); 616a63d08c9SGreg Clayton case FPURegSet: return WriteFPU(); 617a63d08c9SGreg Clayton case EXCRegSet: return WriteEXC(); 618a63d08c9SGreg Clayton case DBGRegSet: return WriteDBG(); 619a63d08c9SGreg Clayton default: break; 620a63d08c9SGreg Clayton } 621a63d08c9SGreg Clayton } 622a63d08c9SGreg Clayton return KERN_INVALID_ARGUMENT; 623a63d08c9SGreg Clayton } 624a63d08c9SGreg Clayton 625a63d08c9SGreg Clayton void 626a63d08c9SGreg Clayton RegisterContextDarwin_arm::LogDBGRegisters (Log *log, const DBG& dbg) 627a63d08c9SGreg Clayton { 628a63d08c9SGreg Clayton if (log) 629a63d08c9SGreg Clayton { 630a63d08c9SGreg Clayton for (uint32_t i=0; i<16; i++) 631a63d08c9SGreg Clayton log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { 0x%8.8x, 0x%8.8x }", 632a63d08c9SGreg Clayton i, i, dbg.bvr[i], dbg.bcr[i], 633a63d08c9SGreg Clayton i, i, dbg.wvr[i], dbg.wcr[i]); 634a63d08c9SGreg Clayton } 635a63d08c9SGreg Clayton } 636a63d08c9SGreg Clayton 637a63d08c9SGreg Clayton 638a63d08c9SGreg Clayton bool 639a63d08c9SGreg Clayton RegisterContextDarwin_arm::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) 640a63d08c9SGreg Clayton { 641a63d08c9SGreg Clayton const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 642a63d08c9SGreg Clayton int set = RegisterContextDarwin_arm::GetSetForNativeRegNum (reg); 643a63d08c9SGreg Clayton 644a63d08c9SGreg Clayton if (set == -1) 645a63d08c9SGreg Clayton return false; 646a63d08c9SGreg Clayton 647a63d08c9SGreg Clayton if (ReadRegisterSet(set, false) != KERN_SUCCESS) 648a63d08c9SGreg Clayton return false; 649a63d08c9SGreg Clayton 650a63d08c9SGreg Clayton switch (reg) 651a63d08c9SGreg Clayton { 652a63d08c9SGreg Clayton case gpr_r0: 653a63d08c9SGreg Clayton case gpr_r1: 654a63d08c9SGreg Clayton case gpr_r2: 655a63d08c9SGreg Clayton case gpr_r3: 656a63d08c9SGreg Clayton case gpr_r4: 657a63d08c9SGreg Clayton case gpr_r5: 658a63d08c9SGreg Clayton case gpr_r6: 659a63d08c9SGreg Clayton case gpr_r7: 660a63d08c9SGreg Clayton case gpr_r8: 661a63d08c9SGreg Clayton case gpr_r9: 662a63d08c9SGreg Clayton case gpr_r10: 663a63d08c9SGreg Clayton case gpr_r11: 664a63d08c9SGreg Clayton case gpr_r12: 665a63d08c9SGreg Clayton case gpr_sp: 666a63d08c9SGreg Clayton case gpr_lr: 667a63d08c9SGreg Clayton case gpr_pc: 668a63d08c9SGreg Clayton case gpr_cpsr: 669a63d08c9SGreg Clayton value.SetUInt32 (gpr.r[reg - gpr_r0]); 670a63d08c9SGreg Clayton break; 671a63d08c9SGreg Clayton 672a63d08c9SGreg Clayton case fpu_s0: 673a63d08c9SGreg Clayton case fpu_s1: 674a63d08c9SGreg Clayton case fpu_s2: 675a63d08c9SGreg Clayton case fpu_s3: 676a63d08c9SGreg Clayton case fpu_s4: 677a63d08c9SGreg Clayton case fpu_s5: 678a63d08c9SGreg Clayton case fpu_s6: 679a63d08c9SGreg Clayton case fpu_s7: 680a63d08c9SGreg Clayton case fpu_s8: 681a63d08c9SGreg Clayton case fpu_s9: 682a63d08c9SGreg Clayton case fpu_s10: 683a63d08c9SGreg Clayton case fpu_s11: 684a63d08c9SGreg Clayton case fpu_s12: 685a63d08c9SGreg Clayton case fpu_s13: 686a63d08c9SGreg Clayton case fpu_s14: 687a63d08c9SGreg Clayton case fpu_s15: 688a63d08c9SGreg Clayton case fpu_s16: 689a63d08c9SGreg Clayton case fpu_s17: 690a63d08c9SGreg Clayton case fpu_s18: 691a63d08c9SGreg Clayton case fpu_s19: 692a63d08c9SGreg Clayton case fpu_s20: 693a63d08c9SGreg Clayton case fpu_s21: 694a63d08c9SGreg Clayton case fpu_s22: 695a63d08c9SGreg Clayton case fpu_s23: 696a63d08c9SGreg Clayton case fpu_s24: 697a63d08c9SGreg Clayton case fpu_s25: 698a63d08c9SGreg Clayton case fpu_s26: 699a63d08c9SGreg Clayton case fpu_s27: 700a63d08c9SGreg Clayton case fpu_s28: 701a63d08c9SGreg Clayton case fpu_s29: 702a63d08c9SGreg Clayton case fpu_s30: 703a63d08c9SGreg Clayton case fpu_s31: 704a63d08c9SGreg Clayton value.SetUInt32 (fpu.floats.s[reg], RegisterValue::eTypeFloat); 705a63d08c9SGreg Clayton break; 706a63d08c9SGreg Clayton 707a63d08c9SGreg Clayton case fpu_fpscr: 708a63d08c9SGreg Clayton value.SetUInt32 (fpu.fpscr); 709a63d08c9SGreg Clayton break; 710a63d08c9SGreg Clayton 711a63d08c9SGreg Clayton case exc_exception: 712a63d08c9SGreg Clayton value.SetUInt32 (exc.exception); 713a63d08c9SGreg Clayton break; 714a63d08c9SGreg Clayton case exc_fsr: 715a63d08c9SGreg Clayton value.SetUInt32 (exc.fsr); 716a63d08c9SGreg Clayton break; 717a63d08c9SGreg Clayton case exc_far: 718a63d08c9SGreg Clayton value.SetUInt32 (exc.far); 719a63d08c9SGreg Clayton break; 720a63d08c9SGreg Clayton 721a63d08c9SGreg Clayton default: 722a63d08c9SGreg Clayton value.SetValueToInvalid(); 723a63d08c9SGreg Clayton return false; 724a63d08c9SGreg Clayton 725a63d08c9SGreg Clayton } 726a63d08c9SGreg Clayton return true; 727a63d08c9SGreg Clayton } 728a63d08c9SGreg Clayton 729a63d08c9SGreg Clayton 730a63d08c9SGreg Clayton bool 731a63d08c9SGreg Clayton RegisterContextDarwin_arm::WriteRegister (const RegisterInfo *reg_info, 732a63d08c9SGreg Clayton const RegisterValue &value) 733a63d08c9SGreg Clayton { 734a63d08c9SGreg Clayton const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 735a63d08c9SGreg Clayton int set = GetSetForNativeRegNum (reg); 736a63d08c9SGreg Clayton 737a63d08c9SGreg Clayton if (set == -1) 738a63d08c9SGreg Clayton return false; 739a63d08c9SGreg Clayton 740a63d08c9SGreg Clayton if (ReadRegisterSet(set, false) != KERN_SUCCESS) 741a63d08c9SGreg Clayton return false; 742a63d08c9SGreg Clayton 743a63d08c9SGreg Clayton switch (reg) 744a63d08c9SGreg Clayton { 745a63d08c9SGreg Clayton case gpr_r0: 746a63d08c9SGreg Clayton case gpr_r1: 747a63d08c9SGreg Clayton case gpr_r2: 748a63d08c9SGreg Clayton case gpr_r3: 749a63d08c9SGreg Clayton case gpr_r4: 750a63d08c9SGreg Clayton case gpr_r5: 751a63d08c9SGreg Clayton case gpr_r6: 752a63d08c9SGreg Clayton case gpr_r7: 753a63d08c9SGreg Clayton case gpr_r8: 754a63d08c9SGreg Clayton case gpr_r9: 755a63d08c9SGreg Clayton case gpr_r10: 756a63d08c9SGreg Clayton case gpr_r11: 757a63d08c9SGreg Clayton case gpr_r12: 758a63d08c9SGreg Clayton case gpr_sp: 759a63d08c9SGreg Clayton case gpr_lr: 760a63d08c9SGreg Clayton case gpr_pc: 761a63d08c9SGreg Clayton case gpr_cpsr: 762a63d08c9SGreg Clayton gpr.r[reg - gpr_r0] = value.GetAsUInt32(); 763a63d08c9SGreg Clayton break; 764a63d08c9SGreg Clayton 765a63d08c9SGreg Clayton case fpu_s0: 766a63d08c9SGreg Clayton case fpu_s1: 767a63d08c9SGreg Clayton case fpu_s2: 768a63d08c9SGreg Clayton case fpu_s3: 769a63d08c9SGreg Clayton case fpu_s4: 770a63d08c9SGreg Clayton case fpu_s5: 771a63d08c9SGreg Clayton case fpu_s6: 772a63d08c9SGreg Clayton case fpu_s7: 773a63d08c9SGreg Clayton case fpu_s8: 774a63d08c9SGreg Clayton case fpu_s9: 775a63d08c9SGreg Clayton case fpu_s10: 776a63d08c9SGreg Clayton case fpu_s11: 777a63d08c9SGreg Clayton case fpu_s12: 778a63d08c9SGreg Clayton case fpu_s13: 779a63d08c9SGreg Clayton case fpu_s14: 780a63d08c9SGreg Clayton case fpu_s15: 781a63d08c9SGreg Clayton case fpu_s16: 782a63d08c9SGreg Clayton case fpu_s17: 783a63d08c9SGreg Clayton case fpu_s18: 784a63d08c9SGreg Clayton case fpu_s19: 785a63d08c9SGreg Clayton case fpu_s20: 786a63d08c9SGreg Clayton case fpu_s21: 787a63d08c9SGreg Clayton case fpu_s22: 788a63d08c9SGreg Clayton case fpu_s23: 789a63d08c9SGreg Clayton case fpu_s24: 790a63d08c9SGreg Clayton case fpu_s25: 791a63d08c9SGreg Clayton case fpu_s26: 792a63d08c9SGreg Clayton case fpu_s27: 793a63d08c9SGreg Clayton case fpu_s28: 794a63d08c9SGreg Clayton case fpu_s29: 795a63d08c9SGreg Clayton case fpu_s30: 796a63d08c9SGreg Clayton case fpu_s31: 797a63d08c9SGreg Clayton fpu.floats.s[reg] = value.GetAsUInt32(); 798a63d08c9SGreg Clayton break; 799a63d08c9SGreg Clayton 800a63d08c9SGreg Clayton case fpu_fpscr: 801a63d08c9SGreg Clayton fpu.fpscr = value.GetAsUInt32(); 802a63d08c9SGreg Clayton break; 803a63d08c9SGreg Clayton 804a63d08c9SGreg Clayton case exc_exception: 805a63d08c9SGreg Clayton exc.exception = value.GetAsUInt32(); 806a63d08c9SGreg Clayton break; 807a63d08c9SGreg Clayton case exc_fsr: 808a63d08c9SGreg Clayton exc.fsr = value.GetAsUInt32(); 809a63d08c9SGreg Clayton break; 810a63d08c9SGreg Clayton case exc_far: 811a63d08c9SGreg Clayton exc.far = value.GetAsUInt32(); 812a63d08c9SGreg Clayton break; 813a63d08c9SGreg Clayton 814a63d08c9SGreg Clayton default: 815a63d08c9SGreg Clayton return false; 816a63d08c9SGreg Clayton 817a63d08c9SGreg Clayton } 818a63d08c9SGreg Clayton return WriteRegisterSet(set) == KERN_SUCCESS; 819a63d08c9SGreg Clayton } 820a63d08c9SGreg Clayton 821a63d08c9SGreg Clayton bool 822a63d08c9SGreg Clayton RegisterContextDarwin_arm::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) 823a63d08c9SGreg Clayton { 824a63d08c9SGreg Clayton data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0)); 825a63d08c9SGreg Clayton if (data_sp && 826a63d08c9SGreg Clayton ReadGPR (false) == KERN_SUCCESS && 827a63d08c9SGreg Clayton ReadFPU (false) == KERN_SUCCESS && 828a63d08c9SGreg Clayton ReadEXC (false) == KERN_SUCCESS) 829a63d08c9SGreg Clayton { 830a63d08c9SGreg Clayton uint8_t *dst = data_sp->GetBytes(); 831a63d08c9SGreg Clayton ::memcpy (dst, &gpr, sizeof(gpr)); 832a63d08c9SGreg Clayton dst += sizeof(gpr); 833a63d08c9SGreg Clayton 834a63d08c9SGreg Clayton ::memcpy (dst, &fpu, sizeof(fpu)); 835a63d08c9SGreg Clayton dst += sizeof(gpr); 836a63d08c9SGreg Clayton 837a63d08c9SGreg Clayton ::memcpy (dst, &exc, sizeof(exc)); 838a63d08c9SGreg Clayton return true; 839a63d08c9SGreg Clayton } 840a63d08c9SGreg Clayton return false; 841a63d08c9SGreg Clayton } 842a63d08c9SGreg Clayton 843a63d08c9SGreg Clayton bool 844a63d08c9SGreg Clayton RegisterContextDarwin_arm::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) 845a63d08c9SGreg Clayton { 846a63d08c9SGreg Clayton if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) 847a63d08c9SGreg Clayton { 848a63d08c9SGreg Clayton const uint8_t *src = data_sp->GetBytes(); 849a63d08c9SGreg Clayton ::memcpy (&gpr, src, sizeof(gpr)); 850a63d08c9SGreg Clayton src += sizeof(gpr); 851a63d08c9SGreg Clayton 852a63d08c9SGreg Clayton ::memcpy (&fpu, src, sizeof(fpu)); 853a63d08c9SGreg Clayton src += sizeof(gpr); 854a63d08c9SGreg Clayton 855a63d08c9SGreg Clayton ::memcpy (&exc, src, sizeof(exc)); 856a63d08c9SGreg Clayton uint32_t success_count = 0; 857a63d08c9SGreg Clayton if (WriteGPR() == KERN_SUCCESS) 858a63d08c9SGreg Clayton ++success_count; 859a63d08c9SGreg Clayton if (WriteFPU() == KERN_SUCCESS) 860a63d08c9SGreg Clayton ++success_count; 861a63d08c9SGreg Clayton if (WriteEXC() == KERN_SUCCESS) 862a63d08c9SGreg Clayton ++success_count; 863a63d08c9SGreg Clayton return success_count == 3; 864a63d08c9SGreg Clayton } 865a63d08c9SGreg Clayton return false; 866a63d08c9SGreg Clayton } 867a63d08c9SGreg Clayton 868a63d08c9SGreg Clayton uint32_t 869e7c7c3deSJean-Daniel Dupas RegisterContextDarwin_arm::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t reg) 870a63d08c9SGreg Clayton { 871a63d08c9SGreg Clayton if (kind == eRegisterKindGeneric) 872a63d08c9SGreg Clayton { 873a63d08c9SGreg Clayton switch (reg) 874a63d08c9SGreg Clayton { 875a63d08c9SGreg Clayton case LLDB_REGNUM_GENERIC_PC: return gpr_pc; 876a63d08c9SGreg Clayton case LLDB_REGNUM_GENERIC_SP: return gpr_sp; 877a63d08c9SGreg Clayton case LLDB_REGNUM_GENERIC_FP: return gpr_r7; 878a63d08c9SGreg Clayton case LLDB_REGNUM_GENERIC_RA: return gpr_lr; 879a63d08c9SGreg Clayton case LLDB_REGNUM_GENERIC_FLAGS: return gpr_cpsr; 880a63d08c9SGreg Clayton default: 881a63d08c9SGreg Clayton break; 882a63d08c9SGreg Clayton } 883a63d08c9SGreg Clayton } 884a63d08c9SGreg Clayton else if (kind == eRegisterKindDWARF) 885a63d08c9SGreg Clayton { 886a63d08c9SGreg Clayton switch (reg) 887a63d08c9SGreg Clayton { 888a63d08c9SGreg Clayton case dwarf_r0: return gpr_r0; 889a63d08c9SGreg Clayton case dwarf_r1: return gpr_r1; 890a63d08c9SGreg Clayton case dwarf_r2: return gpr_r2; 891a63d08c9SGreg Clayton case dwarf_r3: return gpr_r3; 892a63d08c9SGreg Clayton case dwarf_r4: return gpr_r4; 893a63d08c9SGreg Clayton case dwarf_r5: return gpr_r5; 894a63d08c9SGreg Clayton case dwarf_r6: return gpr_r6; 895a63d08c9SGreg Clayton case dwarf_r7: return gpr_r7; 896a63d08c9SGreg Clayton case dwarf_r8: return gpr_r8; 897a63d08c9SGreg Clayton case dwarf_r9: return gpr_r9; 898a63d08c9SGreg Clayton case dwarf_r10: return gpr_r10; 899a63d08c9SGreg Clayton case dwarf_r11: return gpr_r11; 900a63d08c9SGreg Clayton case dwarf_r12: return gpr_r12; 901a63d08c9SGreg Clayton case dwarf_sp: return gpr_sp; 902a63d08c9SGreg Clayton case dwarf_lr: return gpr_lr; 903a63d08c9SGreg Clayton case dwarf_pc: return gpr_pc; 904a63d08c9SGreg Clayton case dwarf_spsr: return gpr_cpsr; 905a63d08c9SGreg Clayton 906a63d08c9SGreg Clayton case dwarf_s0: return fpu_s0; 907a63d08c9SGreg Clayton case dwarf_s1: return fpu_s1; 908a63d08c9SGreg Clayton case dwarf_s2: return fpu_s2; 909a63d08c9SGreg Clayton case dwarf_s3: return fpu_s3; 910a63d08c9SGreg Clayton case dwarf_s4: return fpu_s4; 911a63d08c9SGreg Clayton case dwarf_s5: return fpu_s5; 912a63d08c9SGreg Clayton case dwarf_s6: return fpu_s6; 913a63d08c9SGreg Clayton case dwarf_s7: return fpu_s7; 914a63d08c9SGreg Clayton case dwarf_s8: return fpu_s8; 915a63d08c9SGreg Clayton case dwarf_s9: return fpu_s9; 916a63d08c9SGreg Clayton case dwarf_s10: return fpu_s10; 917a63d08c9SGreg Clayton case dwarf_s11: return fpu_s11; 918a63d08c9SGreg Clayton case dwarf_s12: return fpu_s12; 919a63d08c9SGreg Clayton case dwarf_s13: return fpu_s13; 920a63d08c9SGreg Clayton case dwarf_s14: return fpu_s14; 921a63d08c9SGreg Clayton case dwarf_s15: return fpu_s15; 922a63d08c9SGreg Clayton case dwarf_s16: return fpu_s16; 923a63d08c9SGreg Clayton case dwarf_s17: return fpu_s17; 924a63d08c9SGreg Clayton case dwarf_s18: return fpu_s18; 925a63d08c9SGreg Clayton case dwarf_s19: return fpu_s19; 926a63d08c9SGreg Clayton case dwarf_s20: return fpu_s20; 927a63d08c9SGreg Clayton case dwarf_s21: return fpu_s21; 928a63d08c9SGreg Clayton case dwarf_s22: return fpu_s22; 929a63d08c9SGreg Clayton case dwarf_s23: return fpu_s23; 930a63d08c9SGreg Clayton case dwarf_s24: return fpu_s24; 931a63d08c9SGreg Clayton case dwarf_s25: return fpu_s25; 932a63d08c9SGreg Clayton case dwarf_s26: return fpu_s26; 933a63d08c9SGreg Clayton case dwarf_s27: return fpu_s27; 934a63d08c9SGreg Clayton case dwarf_s28: return fpu_s28; 935a63d08c9SGreg Clayton case dwarf_s29: return fpu_s29; 936a63d08c9SGreg Clayton case dwarf_s30: return fpu_s30; 937a63d08c9SGreg Clayton case dwarf_s31: return fpu_s31; 938a63d08c9SGreg Clayton 939a63d08c9SGreg Clayton default: 940a63d08c9SGreg Clayton break; 941a63d08c9SGreg Clayton } 942a63d08c9SGreg Clayton } 943a63d08c9SGreg Clayton else if (kind == eRegisterKindGCC) 944a63d08c9SGreg Clayton { 945a63d08c9SGreg Clayton switch (reg) 946a63d08c9SGreg Clayton { 947a63d08c9SGreg Clayton case gcc_r0: return gpr_r0; 948a63d08c9SGreg Clayton case gcc_r1: return gpr_r1; 949a63d08c9SGreg Clayton case gcc_r2: return gpr_r2; 950a63d08c9SGreg Clayton case gcc_r3: return gpr_r3; 951a63d08c9SGreg Clayton case gcc_r4: return gpr_r4; 952a63d08c9SGreg Clayton case gcc_r5: return gpr_r5; 953a63d08c9SGreg Clayton case gcc_r6: return gpr_r6; 954a63d08c9SGreg Clayton case gcc_r7: return gpr_r7; 955a63d08c9SGreg Clayton case gcc_r8: return gpr_r8; 956a63d08c9SGreg Clayton case gcc_r9: return gpr_r9; 957a63d08c9SGreg Clayton case gcc_r10: return gpr_r10; 958a63d08c9SGreg Clayton case gcc_r11: return gpr_r11; 959a63d08c9SGreg Clayton case gcc_r12: return gpr_r12; 960a63d08c9SGreg Clayton case gcc_sp: return gpr_sp; 961a63d08c9SGreg Clayton case gcc_lr: return gpr_lr; 962a63d08c9SGreg Clayton case gcc_pc: return gpr_pc; 963a63d08c9SGreg Clayton case gcc_cpsr: return gpr_cpsr; 964a63d08c9SGreg Clayton } 965a63d08c9SGreg Clayton } 966a63d08c9SGreg Clayton else if (kind == eRegisterKindLLDB) 967a63d08c9SGreg Clayton { 968a63d08c9SGreg Clayton return reg; 969a63d08c9SGreg Clayton } 970a63d08c9SGreg Clayton return LLDB_INVALID_REGNUM; 971a63d08c9SGreg Clayton } 972a63d08c9SGreg Clayton 973a63d08c9SGreg Clayton 974a63d08c9SGreg Clayton uint32_t 975a63d08c9SGreg Clayton RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints () 976a63d08c9SGreg Clayton { 977a63d08c9SGreg Clayton #if defined (__arm__) 978a63d08c9SGreg Clayton // Set the init value to something that will let us know that we need to 979a63d08c9SGreg Clayton // autodetect how many breakpoints are supported dynamically... 980a63d08c9SGreg Clayton static uint32_t g_num_supported_hw_breakpoints = UINT32_MAX; 981a63d08c9SGreg Clayton if (g_num_supported_hw_breakpoints == UINT32_MAX) 982a63d08c9SGreg Clayton { 983a63d08c9SGreg Clayton // Set this to zero in case we can't tell if there are any HW breakpoints 984a63d08c9SGreg Clayton g_num_supported_hw_breakpoints = 0; 985a63d08c9SGreg Clayton 986a63d08c9SGreg Clayton uint32_t register_DBGDIDR; 987a63d08c9SGreg Clayton 988a63d08c9SGreg Clayton asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR)); 989dce502edSGreg Clayton g_num_supported_hw_breakpoints = Bits32 (register_DBGDIDR, 27, 24); 990a63d08c9SGreg Clayton // Zero is reserved for the BRP count, so don't increment it if it is zero 991a63d08c9SGreg Clayton if (g_num_supported_hw_breakpoints > 0) 992a63d08c9SGreg Clayton g_num_supported_hw_breakpoints++; 99389f138aeSGreg Clayton // if (log) log->Printf ("DBGDIDR=0x%8.8x (number BRP pairs = %u)", register_DBGDIDR, g_num_supported_hw_breakpoints); 994a63d08c9SGreg Clayton 995a63d08c9SGreg Clayton } 996a63d08c9SGreg Clayton return g_num_supported_hw_breakpoints; 997a63d08c9SGreg Clayton #else 998a63d08c9SGreg Clayton // TODO: figure out remote case here! 999a63d08c9SGreg Clayton return 6; 1000a63d08c9SGreg Clayton #endif 1001a63d08c9SGreg Clayton } 1002a63d08c9SGreg Clayton 1003a63d08c9SGreg Clayton uint32_t 1004a63d08c9SGreg Clayton RegisterContextDarwin_arm::SetHardwareBreakpoint (lldb::addr_t addr, size_t size) 1005a63d08c9SGreg Clayton { 1006a63d08c9SGreg Clayton // Make sure our address isn't bogus 1007a63d08c9SGreg Clayton if (addr & 1) 1008a63d08c9SGreg Clayton return LLDB_INVALID_INDEX32; 1009a63d08c9SGreg Clayton 1010a63d08c9SGreg Clayton int kret = ReadDBG (false); 1011a63d08c9SGreg Clayton 1012a63d08c9SGreg Clayton if (kret == KERN_SUCCESS) 1013a63d08c9SGreg Clayton { 1014a63d08c9SGreg Clayton const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints(); 1015a63d08c9SGreg Clayton uint32_t i; 1016a63d08c9SGreg Clayton for (i=0; i<num_hw_breakpoints; ++i) 1017a63d08c9SGreg Clayton { 1018a63d08c9SGreg Clayton if ((dbg.bcr[i] & BCR_ENABLE) == 0) 1019a63d08c9SGreg Clayton break; // We found an available hw breakpoint slot (in i) 1020a63d08c9SGreg Clayton } 1021a63d08c9SGreg Clayton 1022a63d08c9SGreg Clayton // See if we found an available hw breakpoint slot above 1023a63d08c9SGreg Clayton if (i < num_hw_breakpoints) 1024a63d08c9SGreg Clayton { 1025a63d08c9SGreg Clayton // Make sure bits 1:0 are clear in our address 1026a63d08c9SGreg Clayton dbg.bvr[i] = addr & ~((lldb::addr_t)3); 1027a63d08c9SGreg Clayton 1028a63d08c9SGreg Clayton if (size == 2 || addr & 2) 1029a63d08c9SGreg Clayton { 1030a63d08c9SGreg Clayton uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1; 1031a63d08c9SGreg Clayton 1032a63d08c9SGreg Clayton // We have a thumb breakpoint 1033a63d08c9SGreg Clayton // We have an ARM breakpoint 1034a63d08c9SGreg Clayton dbg.bcr[i] = BCR_M_IMVA_MATCH | // Stop on address mismatch 1035a63d08c9SGreg Clayton byte_addr_select | // Set the correct byte address select so we only trigger on the correct opcode 1036a63d08c9SGreg Clayton S_USER | // Which modes should this breakpoint stop in? 1037a63d08c9SGreg Clayton BCR_ENABLE; // Enable this hardware breakpoint 103889f138aeSGreg Clayton // if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (Thumb)", 103989f138aeSGreg Clayton // addr, 104089f138aeSGreg Clayton // size, 104189f138aeSGreg Clayton // i, 104289f138aeSGreg Clayton // i, 104389f138aeSGreg Clayton // dbg.bvr[i], 104489f138aeSGreg Clayton // dbg.bcr[i]); 1045a63d08c9SGreg Clayton } 1046a63d08c9SGreg Clayton else if (size == 4) 1047a63d08c9SGreg Clayton { 1048a63d08c9SGreg Clayton // We have an ARM breakpoint 1049a63d08c9SGreg Clayton dbg.bcr[i] = BCR_M_IMVA_MATCH | // Stop on address mismatch 1050a63d08c9SGreg Clayton BAS_IMVA_ALL | // Stop on any of the four bytes following the IMVA 1051a63d08c9SGreg Clayton S_USER | // Which modes should this breakpoint stop in? 1052a63d08c9SGreg Clayton BCR_ENABLE; // Enable this hardware breakpoint 105389f138aeSGreg Clayton // if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (ARM)", 105489f138aeSGreg Clayton // addr, 105589f138aeSGreg Clayton // size, 105689f138aeSGreg Clayton // i, 105789f138aeSGreg Clayton // i, 105889f138aeSGreg Clayton // dbg.bvr[i], 105989f138aeSGreg Clayton // dbg.bcr[i]); 1060a63d08c9SGreg Clayton } 1061a63d08c9SGreg Clayton 1062a63d08c9SGreg Clayton kret = WriteDBG(); 106389f138aeSGreg Clayton // if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint() WriteDBG() => 0x%8.8x.", kret); 1064a63d08c9SGreg Clayton 1065a63d08c9SGreg Clayton if (kret == KERN_SUCCESS) 1066a63d08c9SGreg Clayton return i; 1067a63d08c9SGreg Clayton } 106889f138aeSGreg Clayton // else 106989f138aeSGreg Clayton // { 107089f138aeSGreg Clayton // if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(addr = %8.8p, size = %u) => all hardware breakpoint resources are being used.", addr, size); 107189f138aeSGreg Clayton // } 1072a63d08c9SGreg Clayton } 1073a63d08c9SGreg Clayton 1074a63d08c9SGreg Clayton return LLDB_INVALID_INDEX32; 1075a63d08c9SGreg Clayton } 1076a63d08c9SGreg Clayton 1077a63d08c9SGreg Clayton bool 1078a63d08c9SGreg Clayton RegisterContextDarwin_arm::ClearHardwareBreakpoint (uint32_t hw_index) 1079a63d08c9SGreg Clayton { 1080a63d08c9SGreg Clayton int kret = ReadDBG (false); 1081a63d08c9SGreg Clayton 1082a63d08c9SGreg Clayton const uint32_t num_hw_points = NumSupportedHardwareBreakpoints(); 1083a63d08c9SGreg Clayton if (kret == KERN_SUCCESS) 1084a63d08c9SGreg Clayton { 1085a63d08c9SGreg Clayton if (hw_index < num_hw_points) 1086a63d08c9SGreg Clayton { 1087a63d08c9SGreg Clayton dbg.bcr[hw_index] = 0; 108889f138aeSGreg Clayton // if (log) log->Printf ("RegisterContextDarwin_arm::SetHardwareBreakpoint( %u ) - BVR%u = 0x%8.8x BCR%u = 0x%8.8x", 108989f138aeSGreg Clayton // hw_index, 109089f138aeSGreg Clayton // hw_index, 109189f138aeSGreg Clayton // dbg.bvr[hw_index], 109289f138aeSGreg Clayton // hw_index, 109389f138aeSGreg Clayton // dbg.bcr[hw_index]); 1094a63d08c9SGreg Clayton 1095a63d08c9SGreg Clayton kret = WriteDBG(); 1096a63d08c9SGreg Clayton 1097a63d08c9SGreg Clayton if (kret == KERN_SUCCESS) 1098a63d08c9SGreg Clayton return true; 1099a63d08c9SGreg Clayton } 1100a63d08c9SGreg Clayton } 1101a63d08c9SGreg Clayton return false; 1102a63d08c9SGreg Clayton } 1103a63d08c9SGreg Clayton 1104a63d08c9SGreg Clayton uint32_t 1105a63d08c9SGreg Clayton RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints () 1106a63d08c9SGreg Clayton { 1107a63d08c9SGreg Clayton #if defined (__arm__) 1108a63d08c9SGreg Clayton // Set the init value to something that will let us know that we need to 1109a63d08c9SGreg Clayton // autodetect how many watchpoints are supported dynamically... 1110a63d08c9SGreg Clayton static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX; 1111a63d08c9SGreg Clayton if (g_num_supported_hw_watchpoints == UINT32_MAX) 1112a63d08c9SGreg Clayton { 1113a63d08c9SGreg Clayton // Set this to zero in case we can't tell if there are any HW breakpoints 1114a63d08c9SGreg Clayton g_num_supported_hw_watchpoints = 0; 1115a63d08c9SGreg Clayton 1116a63d08c9SGreg Clayton uint32_t register_DBGDIDR; 1117a63d08c9SGreg Clayton asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR)); 1118dce502edSGreg Clayton g_num_supported_hw_watchpoints = Bits32 (register_DBGDIDR, 31, 28) + 1; 111989f138aeSGreg Clayton // if (log) log->Printf ("DBGDIDR=0x%8.8x (number WRP pairs = %u)", register_DBGDIDR, g_num_supported_hw_watchpoints); 1120a63d08c9SGreg Clayton } 1121a63d08c9SGreg Clayton return g_num_supported_hw_watchpoints; 1122a63d08c9SGreg Clayton #else 1123a63d08c9SGreg Clayton // TODO: figure out remote case here! 1124a63d08c9SGreg Clayton return 2; 1125a63d08c9SGreg Clayton #endif 1126a63d08c9SGreg Clayton } 1127a63d08c9SGreg Clayton 1128a63d08c9SGreg Clayton 1129a63d08c9SGreg Clayton uint32_t 1130a63d08c9SGreg Clayton RegisterContextDarwin_arm::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write) 1131a63d08c9SGreg Clayton { 113289f138aeSGreg Clayton // if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(addr = %8.8p, size = %u, read = %u, write = %u)", addr, size, read, write); 1133a63d08c9SGreg Clayton 1134a63d08c9SGreg Clayton const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); 1135a63d08c9SGreg Clayton 1136a63d08c9SGreg Clayton // Can't watch zero bytes 1137a63d08c9SGreg Clayton if (size == 0) 1138a63d08c9SGreg Clayton return LLDB_INVALID_INDEX32; 1139a63d08c9SGreg Clayton 1140a63d08c9SGreg Clayton // We must watch for either read or write 1141a63d08c9SGreg Clayton if (read == false && write == false) 1142a63d08c9SGreg Clayton return LLDB_INVALID_INDEX32; 1143a63d08c9SGreg Clayton 1144a63d08c9SGreg Clayton // Can't watch more than 4 bytes per WVR/WCR pair 1145a63d08c9SGreg Clayton if (size > 4) 1146a63d08c9SGreg Clayton return LLDB_INVALID_INDEX32; 1147a63d08c9SGreg Clayton 1148a63d08c9SGreg Clayton // We can only watch up to four bytes that follow a 4 byte aligned address 1149a63d08c9SGreg Clayton // per watchpoint register pair. Since we have at most so we can only watch 1150a63d08c9SGreg Clayton // until the next 4 byte boundary and we need to make sure we can properly 1151a63d08c9SGreg Clayton // encode this. 1152a63d08c9SGreg Clayton uint32_t addr_word_offset = addr % 4; 115389f138aeSGreg Clayton // if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset); 1154a63d08c9SGreg Clayton 1155a63d08c9SGreg Clayton uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset; 115689f138aeSGreg Clayton // if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask); 1157a63d08c9SGreg Clayton if (byte_mask > 0xfu) 1158a63d08c9SGreg Clayton return LLDB_INVALID_INDEX32; 1159a63d08c9SGreg Clayton 1160a63d08c9SGreg Clayton // Read the debug state 1161a63d08c9SGreg Clayton int kret = ReadDBG (false); 1162a63d08c9SGreg Clayton 1163a63d08c9SGreg Clayton if (kret == KERN_SUCCESS) 1164a63d08c9SGreg Clayton { 1165a63d08c9SGreg Clayton // Check to make sure we have the needed hardware support 1166a63d08c9SGreg Clayton uint32_t i = 0; 1167a63d08c9SGreg Clayton 1168a63d08c9SGreg Clayton for (i=0; i<num_hw_watchpoints; ++i) 1169a63d08c9SGreg Clayton { 1170a63d08c9SGreg Clayton if ((dbg.wcr[i] & WCR_ENABLE) == 0) 1171a63d08c9SGreg Clayton break; // We found an available hw breakpoint slot (in i) 1172a63d08c9SGreg Clayton } 1173a63d08c9SGreg Clayton 1174a63d08c9SGreg Clayton // See if we found an available hw breakpoint slot above 1175a63d08c9SGreg Clayton if (i < num_hw_watchpoints) 1176a63d08c9SGreg Clayton { 1177a63d08c9SGreg Clayton // Make the byte_mask into a valid Byte Address Select mask 1178a63d08c9SGreg Clayton uint32_t byte_address_select = byte_mask << 5; 1179a63d08c9SGreg Clayton // Make sure bits 1:0 are clear in our address 1180a63d08c9SGreg Clayton dbg.wvr[i] = addr & ~((lldb::addr_t)3); 1181a63d08c9SGreg Clayton dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA that we will watch 1182a63d08c9SGreg Clayton S_USER | // Stop only in user mode 1183a63d08c9SGreg Clayton (read ? WCR_LOAD : 0) | // Stop on read access? 1184a63d08c9SGreg Clayton (write ? WCR_STORE : 0) | // Stop on write access? 1185a63d08c9SGreg Clayton WCR_ENABLE; // Enable this watchpoint; 1186a63d08c9SGreg Clayton 1187a63d08c9SGreg Clayton kret = WriteDBG(); 118889f138aeSGreg Clayton // if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() WriteDBG() => 0x%8.8x.", kret); 1189a63d08c9SGreg Clayton 1190a63d08c9SGreg Clayton if (kret == KERN_SUCCESS) 1191a63d08c9SGreg Clayton return i; 1192a63d08c9SGreg Clayton } 1193a63d08c9SGreg Clayton else 1194a63d08c9SGreg Clayton { 119589f138aeSGreg Clayton // if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints); 1196a63d08c9SGreg Clayton } 1197a63d08c9SGreg Clayton } 1198a63d08c9SGreg Clayton return LLDB_INVALID_INDEX32; 1199a63d08c9SGreg Clayton } 1200a63d08c9SGreg Clayton 1201a63d08c9SGreg Clayton bool 1202a63d08c9SGreg Clayton RegisterContextDarwin_arm::ClearHardwareWatchpoint (uint32_t hw_index) 1203a63d08c9SGreg Clayton { 1204a63d08c9SGreg Clayton int kret = ReadDBG (false); 1205a63d08c9SGreg Clayton 1206a63d08c9SGreg Clayton const uint32_t num_hw_points = NumSupportedHardwareWatchpoints(); 1207a63d08c9SGreg Clayton if (kret == KERN_SUCCESS) 1208a63d08c9SGreg Clayton { 1209a63d08c9SGreg Clayton if (hw_index < num_hw_points) 1210a63d08c9SGreg Clayton { 1211a63d08c9SGreg Clayton dbg.wcr[hw_index] = 0; 121289f138aeSGreg Clayton // if (log) log->Printf ("RegisterContextDarwin_arm::ClearHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x WCR%u = 0x%8.8x", 121389f138aeSGreg Clayton // hw_index, 121489f138aeSGreg Clayton // hw_index, 121589f138aeSGreg Clayton // dbg.wvr[hw_index], 121689f138aeSGreg Clayton // hw_index, 121789f138aeSGreg Clayton // dbg.wcr[hw_index]); 1218a63d08c9SGreg Clayton 1219a63d08c9SGreg Clayton kret = WriteDBG(); 1220a63d08c9SGreg Clayton 1221a63d08c9SGreg Clayton if (kret == KERN_SUCCESS) 1222a63d08c9SGreg Clayton return true; 1223a63d08c9SGreg Clayton } 1224a63d08c9SGreg Clayton } 1225a63d08c9SGreg Clayton return false; 1226a63d08c9SGreg Clayton } 1227a63d08c9SGreg Clayton 1228a67dd8fcSPeter Collingbourne #endif 1229