1 //===-- RegisterContextDarwin_arm64.cpp ---------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #if defined(__APPLE__) 11 12 #include "RegisterContextDarwin_arm64.h" 13 14 // C Includes 15 #include <mach/mach_types.h> 16 #include <mach/thread_act.h> 17 #include <sys/sysctl.h> 18 19 // C++ Includes 20 // Other libraries and framework includes 21 #include "lldb/Core/DataBufferHeap.h" 22 #include "lldb/Core/DataExtractor.h" 23 #include "lldb/Core/Log.h" 24 #include "lldb/Core/RegisterValue.h" 25 #include "lldb/Core/Scalar.h" 26 #include "lldb/Host/Endian.h" 27 #include "llvm/ADT/STLExtras.h" 28 #include "llvm/Support/Compiler.h" 29 30 #include "Plugins/Process/Utility/InstructionUtils.h" 31 32 // Support building against older versions of LLVM, this macro was added 33 // recently. 34 #ifndef LLVM_EXTENSION 35 #define LLVM_EXTENSION 36 #endif 37 38 // Project includes 39 #include "ARM64_GCC_Registers.h" 40 #include "ARM64_DWARF_Registers.h" 41 42 using namespace lldb; 43 using namespace lldb_private; 44 45 enum 46 { 47 gpr_x0 = 0, 48 gpr_x1, 49 gpr_x2, 50 gpr_x3, 51 gpr_x4, 52 gpr_x5, 53 gpr_x6, 54 gpr_x7, 55 gpr_x8, 56 gpr_x9, 57 gpr_x10, 58 gpr_x11, 59 gpr_x12, 60 gpr_x13, 61 gpr_x14, 62 gpr_x15, 63 gpr_x16, 64 gpr_x17, 65 gpr_x18, 66 gpr_x19, 67 gpr_x20, 68 gpr_x21, 69 gpr_x22, 70 gpr_x23, 71 gpr_x24, 72 gpr_x25, 73 gpr_x26, 74 gpr_x27, 75 gpr_x28, 76 gpr_x29 = 29, gpr_fp = gpr_x29, 77 gpr_x30 = 30, gpr_lr = gpr_x30, gpr_ra = gpr_x30, 78 gpr_x31 = 31, gpr_sp = gpr_x31, 79 gpr_pc = 32, 80 gpr_cpsr, 81 82 fpu_v0, 83 fpu_v1, 84 fpu_v2, 85 fpu_v3, 86 fpu_v4, 87 fpu_v5, 88 fpu_v6, 89 fpu_v7, 90 fpu_v8, 91 fpu_v9, 92 fpu_v10, 93 fpu_v11, 94 fpu_v12, 95 fpu_v13, 96 fpu_v14, 97 fpu_v15, 98 fpu_v16, 99 fpu_v17, 100 fpu_v18, 101 fpu_v19, 102 fpu_v20, 103 fpu_v21, 104 fpu_v22, 105 fpu_v23, 106 fpu_v24, 107 fpu_v25, 108 fpu_v26, 109 fpu_v27, 110 fpu_v28, 111 fpu_v29, 112 fpu_v30, 113 fpu_v31, 114 115 fpu_fpsr, 116 fpu_fpcr, 117 118 exc_far, 119 exc_esr, 120 exc_exception, 121 122 dbg_bvr0, 123 dbg_bvr1, 124 dbg_bvr2, 125 dbg_bvr3, 126 dbg_bvr4, 127 dbg_bvr5, 128 dbg_bvr6, 129 dbg_bvr7, 130 dbg_bvr8, 131 dbg_bvr9, 132 dbg_bvr10, 133 dbg_bvr11, 134 dbg_bvr12, 135 dbg_bvr13, 136 dbg_bvr14, 137 dbg_bvr15, 138 139 dbg_bcr0, 140 dbg_bcr1, 141 dbg_bcr2, 142 dbg_bcr3, 143 dbg_bcr4, 144 dbg_bcr5, 145 dbg_bcr6, 146 dbg_bcr7, 147 dbg_bcr8, 148 dbg_bcr9, 149 dbg_bcr10, 150 dbg_bcr11, 151 dbg_bcr12, 152 dbg_bcr13, 153 dbg_bcr14, 154 dbg_bcr15, 155 156 dbg_wvr0, 157 dbg_wvr1, 158 dbg_wvr2, 159 dbg_wvr3, 160 dbg_wvr4, 161 dbg_wvr5, 162 dbg_wvr6, 163 dbg_wvr7, 164 dbg_wvr8, 165 dbg_wvr9, 166 dbg_wvr10, 167 dbg_wvr11, 168 dbg_wvr12, 169 dbg_wvr13, 170 dbg_wvr14, 171 dbg_wvr15, 172 173 dbg_wcr0, 174 dbg_wcr1, 175 dbg_wcr2, 176 dbg_wcr3, 177 dbg_wcr4, 178 dbg_wcr5, 179 dbg_wcr6, 180 dbg_wcr7, 181 dbg_wcr8, 182 dbg_wcr9, 183 dbg_wcr10, 184 dbg_wcr11, 185 dbg_wcr12, 186 dbg_wcr13, 187 dbg_wcr14, 188 dbg_wcr15, 189 190 k_num_registers 191 }; 192 193 194 RegisterContextDarwin_arm64::RegisterContextDarwin_arm64(Thread &thread, uint32_t concrete_frame_idx) : 195 RegisterContext(thread, concrete_frame_idx), 196 gpr(), 197 fpu(), 198 exc() 199 { 200 uint32_t i; 201 for (i=0; i<kNumErrors; i++) 202 { 203 gpr_errs[i] = -1; 204 fpu_errs[i] = -1; 205 exc_errs[i] = -1; 206 } 207 } 208 209 RegisterContextDarwin_arm64::~RegisterContextDarwin_arm64() 210 { 211 } 212 213 214 #define GPR_OFFSET(idx) ((idx) * 8) 215 #define GPR_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::GPR, reg)) 216 217 #define FPU_OFFSET(idx) ((idx) * 16 + sizeof (RegisterContextDarwin_arm64::GPR)) 218 #define FPU_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::FPU, reg)) 219 220 #define EXC_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::EXC, reg) + sizeof (RegisterContextDarwin_arm64::GPR) + sizeof (RegisterContextDarwin_arm64::FPU)) 221 #define DBG_OFFSET_NAME(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_arm64::DBG, reg) + sizeof (RegisterContextDarwin_arm64::GPR) + sizeof (RegisterContextDarwin_arm64::FPU) + sizeof (RegisterContextDarwin_arm64::EXC)) 222 223 #define DEFINE_DBG(reg, i) #reg, NULL, sizeof(((RegisterContextDarwin_arm64::DBG *)NULL)->reg[i]), DBG_OFFSET_NAME(reg[i]), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, dbg_##reg##i }, NULL, NULL 224 #define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_arm64::GPR) + sizeof (RegisterContextDarwin_arm64::FPU) + sizeof (RegisterContextDarwin_arm64::EXC)) 225 226 static RegisterInfo g_register_infos[] = { 227 // General purpose registers 228 // NAME ALT SZ OFFSET ENCODING FORMAT COMPILER DWARF GENERIC GDB LLDB NATIVE VALUE REGS INVALIDATE REGS 229 // ====== ======= == ============= ============= ============ =============== =============== ========================= ===================== ============= ========== =============== 230 { "x0", NULL, 8, GPR_OFFSET(0), eEncodingUint, eFormatHex, { arm64_gcc::x0, arm64_dwarf::x0, LLDB_INVALID_REGNUM, arm64_gcc::x0, gpr_x0 }, NULL, NULL}, 231 { "x1", NULL, 8, GPR_OFFSET(1), eEncodingUint, eFormatHex, { arm64_gcc::x1, arm64_dwarf::x1, LLDB_INVALID_REGNUM, arm64_gcc::x1, gpr_x1 }, NULL, NULL}, 232 { "x2", NULL, 8, GPR_OFFSET(2), eEncodingUint, eFormatHex, { arm64_gcc::x2, arm64_dwarf::x2, LLDB_INVALID_REGNUM, arm64_gcc::x2, gpr_x2 }, NULL, NULL}, 233 { "x3", NULL, 8, GPR_OFFSET(3), eEncodingUint, eFormatHex, { arm64_gcc::x3, arm64_dwarf::x3, LLDB_INVALID_REGNUM, arm64_gcc::x3, gpr_x3 }, NULL, NULL}, 234 { "x4", NULL, 8, GPR_OFFSET(4), eEncodingUint, eFormatHex, { arm64_gcc::x4, arm64_dwarf::x4, LLDB_INVALID_REGNUM, arm64_gcc::x4, gpr_x4 }, NULL, NULL}, 235 { "x5", NULL, 8, GPR_OFFSET(5), eEncodingUint, eFormatHex, { arm64_gcc::x5, arm64_dwarf::x5, LLDB_INVALID_REGNUM, arm64_gcc::x5, gpr_x5 }, NULL, NULL}, 236 { "x6", NULL, 8, GPR_OFFSET(6), eEncodingUint, eFormatHex, { arm64_gcc::x6, arm64_dwarf::x6, LLDB_INVALID_REGNUM, arm64_gcc::x6, gpr_x6 }, NULL, NULL}, 237 { "x7", NULL, 8, GPR_OFFSET(7), eEncodingUint, eFormatHex, { arm64_gcc::x7, arm64_dwarf::x7, LLDB_INVALID_REGNUM, arm64_gcc::x7, gpr_x7 }, NULL, NULL}, 238 { "x8", NULL, 8, GPR_OFFSET(8), eEncodingUint, eFormatHex, { arm64_gcc::x8, arm64_dwarf::x8, LLDB_INVALID_REGNUM, arm64_gcc::x8, gpr_x8 }, NULL, NULL}, 239 { "x9", NULL, 8, GPR_OFFSET(9), eEncodingUint, eFormatHex, { arm64_gcc::x9, arm64_dwarf::x9, LLDB_INVALID_REGNUM, arm64_gcc::x9, gpr_x9 }, NULL, NULL}, 240 { "x10", NULL, 8, GPR_OFFSET(10), eEncodingUint, eFormatHex, { arm64_gcc::x10, arm64_dwarf::x10, LLDB_INVALID_REGNUM, arm64_gcc::x10, gpr_x10 }, NULL, NULL}, 241 { "x11", NULL, 8, GPR_OFFSET(11), eEncodingUint, eFormatHex, { arm64_gcc::x11, arm64_dwarf::x11, LLDB_INVALID_REGNUM, arm64_gcc::x11, gpr_x11 }, NULL, NULL}, 242 { "x12", NULL, 8, GPR_OFFSET(12), eEncodingUint, eFormatHex, { arm64_gcc::x12, arm64_dwarf::x12, LLDB_INVALID_REGNUM, arm64_gcc::x12, gpr_x12 }, NULL, NULL}, 243 { "x13", NULL, 8, GPR_OFFSET(13), eEncodingUint, eFormatHex, { arm64_gcc::x13, arm64_dwarf::x13, LLDB_INVALID_REGNUM, arm64_gcc::x13, gpr_x13 }, NULL, NULL}, 244 { "x14", NULL, 8, GPR_OFFSET(14), eEncodingUint, eFormatHex, { arm64_gcc::x14, arm64_dwarf::x14, LLDB_INVALID_REGNUM, arm64_gcc::x14, gpr_x14 }, NULL, NULL}, 245 { "x15", NULL, 8, GPR_OFFSET(15), eEncodingUint, eFormatHex, { arm64_gcc::x15, arm64_dwarf::x15, LLDB_INVALID_REGNUM, arm64_gcc::x15, gpr_x15 }, NULL, NULL}, 246 { "x16", NULL, 8, GPR_OFFSET(16), eEncodingUint, eFormatHex, { arm64_gcc::x16, arm64_dwarf::x16, LLDB_INVALID_REGNUM, arm64_gcc::x16, gpr_x16 }, NULL, NULL}, 247 { "x17", NULL, 8, GPR_OFFSET(17), eEncodingUint, eFormatHex, { arm64_gcc::x17, arm64_dwarf::x17, LLDB_INVALID_REGNUM, arm64_gcc::x17, gpr_x17 }, NULL, NULL}, 248 { "x18", NULL, 8, GPR_OFFSET(18), eEncodingUint, eFormatHex, { arm64_gcc::x18, arm64_dwarf::x18, LLDB_INVALID_REGNUM, arm64_gcc::x18, gpr_x18 }, NULL, NULL}, 249 { "x19", NULL, 8, GPR_OFFSET(19), eEncodingUint, eFormatHex, { arm64_gcc::x19, arm64_dwarf::x19, LLDB_INVALID_REGNUM, arm64_gcc::x19, gpr_x19 }, NULL, NULL}, 250 { "x20", NULL, 8, GPR_OFFSET(20), eEncodingUint, eFormatHex, { arm64_gcc::x20, arm64_dwarf::x20, LLDB_INVALID_REGNUM, arm64_gcc::x20, gpr_x20 }, NULL, NULL}, 251 { "x21", NULL, 8, GPR_OFFSET(21), eEncodingUint, eFormatHex, { arm64_gcc::x21, arm64_dwarf::x21, LLDB_INVALID_REGNUM, arm64_gcc::x21, gpr_x21 }, NULL, NULL}, 252 { "x22", NULL, 8, GPR_OFFSET(22), eEncodingUint, eFormatHex, { arm64_gcc::x22, arm64_dwarf::x22, LLDB_INVALID_REGNUM, arm64_gcc::x22, gpr_x22 }, NULL, NULL}, 253 { "x23", NULL, 8, GPR_OFFSET(23), eEncodingUint, eFormatHex, { arm64_gcc::x23, arm64_dwarf::x23, LLDB_INVALID_REGNUM, arm64_gcc::x23, gpr_x23 }, NULL, NULL}, 254 { "x24", NULL, 8, GPR_OFFSET(24), eEncodingUint, eFormatHex, { arm64_gcc::x24, arm64_dwarf::x24, LLDB_INVALID_REGNUM, arm64_gcc::x24, gpr_x24 }, NULL, NULL}, 255 { "x25", NULL, 8, GPR_OFFSET(25), eEncodingUint, eFormatHex, { arm64_gcc::x25, arm64_dwarf::x25, LLDB_INVALID_REGNUM, arm64_gcc::x25, gpr_x25 }, NULL, NULL}, 256 { "x26", NULL, 8, GPR_OFFSET(26), eEncodingUint, eFormatHex, { arm64_gcc::x26, arm64_dwarf::x26, LLDB_INVALID_REGNUM, arm64_gcc::x26, gpr_x26 }, NULL, NULL}, 257 { "x27", NULL, 8, GPR_OFFSET(27), eEncodingUint, eFormatHex, { arm64_gcc::x27, arm64_dwarf::x27, LLDB_INVALID_REGNUM, arm64_gcc::x27, gpr_x27 }, NULL, NULL}, 258 { "x28", NULL, 8, GPR_OFFSET(28), eEncodingUint, eFormatHex, { arm64_gcc::x28, arm64_dwarf::x28, LLDB_INVALID_REGNUM, arm64_gcc::x28, gpr_x28 }, NULL, NULL}, 259 260 { "fp", "x29", 8, GPR_OFFSET(29), eEncodingUint, eFormatHex, { arm64_gcc::fp, arm64_dwarf::fp, LLDB_REGNUM_GENERIC_FP, arm64_gcc::fp, gpr_fp }, NULL, NULL}, 261 { "lr", "x30", 8, GPR_OFFSET(30), eEncodingUint, eFormatHex, { arm64_gcc::lr, arm64_dwarf::lr, LLDB_REGNUM_GENERIC_RA, arm64_gcc::lr, gpr_lr }, NULL, NULL}, 262 { "sp", "x31", 8, GPR_OFFSET(31), eEncodingUint, eFormatHex, { arm64_gcc::sp, arm64_dwarf::sp, LLDB_REGNUM_GENERIC_SP, arm64_gcc::sp, gpr_sp }, NULL, NULL}, 263 { "pc", NULL, 8, GPR_OFFSET(32), eEncodingUint, eFormatHex, { arm64_gcc::pc, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, arm64_gcc::pc, gpr_pc }, NULL, NULL}, 264 265 { "cpsr", NULL, 4, GPR_OFFSET_NAME(cpsr), eEncodingUint, eFormatHex, { arm64_gcc::cpsr, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, arm64_gcc::cpsr, gpr_cpsr }, NULL, NULL}, 266 267 { "v0", NULL, 16, FPU_OFFSET(0), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v0, LLDB_INVALID_REGNUM, arm64_gcc::v0, fpu_v0 }, NULL, NULL}, 268 { "v1", NULL, 16, FPU_OFFSET(1), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v1, LLDB_INVALID_REGNUM, arm64_gcc::v1, fpu_v1 }, NULL, NULL}, 269 { "v2", NULL, 16, FPU_OFFSET(2), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v2, LLDB_INVALID_REGNUM, arm64_gcc::v2, fpu_v2 }, NULL, NULL}, 270 { "v3", NULL, 16, FPU_OFFSET(3), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v3, LLDB_INVALID_REGNUM, arm64_gcc::v3, fpu_v3 }, NULL, NULL}, 271 { "v4", NULL, 16, FPU_OFFSET(4), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v4, LLDB_INVALID_REGNUM, arm64_gcc::v4, fpu_v4 }, NULL, NULL}, 272 { "v5", NULL, 16, FPU_OFFSET(5), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v5, LLDB_INVALID_REGNUM, arm64_gcc::v5, fpu_v5 }, NULL, NULL}, 273 { "v6", NULL, 16, FPU_OFFSET(6), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v6, LLDB_INVALID_REGNUM, arm64_gcc::v6, fpu_v6 }, NULL, NULL}, 274 { "v7", NULL, 16, FPU_OFFSET(7), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v7, LLDB_INVALID_REGNUM, arm64_gcc::v7, fpu_v7 }, NULL, NULL}, 275 { "v8", NULL, 16, FPU_OFFSET(8), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v8, LLDB_INVALID_REGNUM, arm64_gcc::v8, fpu_v8 }, NULL, NULL}, 276 { "v9", NULL, 16, FPU_OFFSET(9), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v9, LLDB_INVALID_REGNUM, arm64_gcc::v9, fpu_v9 }, NULL, NULL}, 277 { "v10", NULL, 16, FPU_OFFSET(10), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v10, LLDB_INVALID_REGNUM, arm64_gcc::v10, fpu_v10 }, NULL, NULL}, 278 { "v11", NULL, 16, FPU_OFFSET(11), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v11, LLDB_INVALID_REGNUM, arm64_gcc::v11, fpu_v11 }, NULL, NULL}, 279 { "v12", NULL, 16, FPU_OFFSET(12), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v12, LLDB_INVALID_REGNUM, arm64_gcc::v12, fpu_v12 }, NULL, NULL}, 280 { "v13", NULL, 16, FPU_OFFSET(13), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v13, LLDB_INVALID_REGNUM, arm64_gcc::v13, fpu_v13 }, NULL, NULL}, 281 { "v14", NULL, 16, FPU_OFFSET(14), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v14, LLDB_INVALID_REGNUM, arm64_gcc::v14, fpu_v14 }, NULL, NULL}, 282 { "v15", NULL, 16, FPU_OFFSET(15), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v15, LLDB_INVALID_REGNUM, arm64_gcc::v15, fpu_v15 }, NULL, NULL}, 283 { "v16", NULL, 16, FPU_OFFSET(16), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v16, LLDB_INVALID_REGNUM, arm64_gcc::v16, fpu_v16 }, NULL, NULL}, 284 { "v17", NULL, 16, FPU_OFFSET(17), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v17, LLDB_INVALID_REGNUM, arm64_gcc::v17, fpu_v17 }, NULL, NULL}, 285 { "v18", NULL, 16, FPU_OFFSET(18), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v18, LLDB_INVALID_REGNUM, arm64_gcc::v18, fpu_v18 }, NULL, NULL}, 286 { "v19", NULL, 16, FPU_OFFSET(19), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v19, LLDB_INVALID_REGNUM, arm64_gcc::v19, fpu_v19 }, NULL, NULL}, 287 { "v20", NULL, 16, FPU_OFFSET(20), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v20, LLDB_INVALID_REGNUM, arm64_gcc::v20, fpu_v20 }, NULL, NULL}, 288 { "v21", NULL, 16, FPU_OFFSET(21), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v21, LLDB_INVALID_REGNUM, arm64_gcc::v21, fpu_v21 }, NULL, NULL}, 289 { "v22", NULL, 16, FPU_OFFSET(22), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v22, LLDB_INVALID_REGNUM, arm64_gcc::v22, fpu_v22 }, NULL, NULL}, 290 { "v23", NULL, 16, FPU_OFFSET(23), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v23, LLDB_INVALID_REGNUM, arm64_gcc::v23, fpu_v23 }, NULL, NULL}, 291 { "v24", NULL, 16, FPU_OFFSET(24), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v24, LLDB_INVALID_REGNUM, arm64_gcc::v24, fpu_v24 }, NULL, NULL}, 292 { "v25", NULL, 16, FPU_OFFSET(25), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v25, LLDB_INVALID_REGNUM, arm64_gcc::v25, fpu_v25 }, NULL, NULL}, 293 { "v26", NULL, 16, FPU_OFFSET(26), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v26, LLDB_INVALID_REGNUM, arm64_gcc::v26, fpu_v26 }, NULL, NULL}, 294 { "v27", NULL, 16, FPU_OFFSET(27), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v27, LLDB_INVALID_REGNUM, arm64_gcc::v27, fpu_v27 }, NULL, NULL}, 295 { "v28", NULL, 16, FPU_OFFSET(28), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v28, LLDB_INVALID_REGNUM, arm64_gcc::v28, fpu_v28 }, NULL, NULL}, 296 { "v29", NULL, 16, FPU_OFFSET(29), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v29, LLDB_INVALID_REGNUM, arm64_gcc::v29, fpu_v29 }, NULL, NULL}, 297 { "v30", NULL, 16, FPU_OFFSET(30), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v30, LLDB_INVALID_REGNUM, arm64_gcc::v30, fpu_v30 }, NULL, NULL}, 298 { "v31", NULL, 16, FPU_OFFSET(31), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, arm64_dwarf::v31, LLDB_INVALID_REGNUM, arm64_gcc::v31, fpu_v31 }, NULL, NULL}, 299 300 { "fpsr", NULL, 4, FPU_OFFSET_NAME(fpsr), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpsr }, NULL, NULL}, 301 { "fpcr", NULL, 4, FPU_OFFSET_NAME(fpcr), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpcr }, NULL, NULL}, 302 303 { "far", NULL, 8, EXC_OFFSET_NAME(far), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_far }, NULL, NULL}, 304 { "esr", NULL, 4, EXC_OFFSET_NAME(esr), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_esr }, NULL, NULL}, 305 { "exception",NULL, 4, EXC_OFFSET_NAME(exception), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_exception }, NULL, NULL}, 306 307 { DEFINE_DBG (bvr, 0) }, 308 { DEFINE_DBG (bvr, 1) }, 309 { DEFINE_DBG (bvr, 2) }, 310 { DEFINE_DBG (bvr, 3) }, 311 { DEFINE_DBG (bvr, 4) }, 312 { DEFINE_DBG (bvr, 5) }, 313 { DEFINE_DBG (bvr, 6) }, 314 { DEFINE_DBG (bvr, 7) }, 315 { DEFINE_DBG (bvr, 8) }, 316 { DEFINE_DBG (bvr, 9) }, 317 { DEFINE_DBG (bvr, 10) }, 318 { DEFINE_DBG (bvr, 11) }, 319 { DEFINE_DBG (bvr, 12) }, 320 { DEFINE_DBG (bvr, 13) }, 321 { DEFINE_DBG (bvr, 14) }, 322 { DEFINE_DBG (bvr, 15) }, 323 324 { DEFINE_DBG (bcr, 0) }, 325 { DEFINE_DBG (bcr, 1) }, 326 { DEFINE_DBG (bcr, 2) }, 327 { DEFINE_DBG (bcr, 3) }, 328 { DEFINE_DBG (bcr, 4) }, 329 { DEFINE_DBG (bcr, 5) }, 330 { DEFINE_DBG (bcr, 6) }, 331 { DEFINE_DBG (bcr, 7) }, 332 { DEFINE_DBG (bcr, 8) }, 333 { DEFINE_DBG (bcr, 9) }, 334 { DEFINE_DBG (bcr, 10) }, 335 { DEFINE_DBG (bcr, 11) }, 336 { DEFINE_DBG (bcr, 12) }, 337 { DEFINE_DBG (bcr, 13) }, 338 { DEFINE_DBG (bcr, 14) }, 339 { DEFINE_DBG (bcr, 15) }, 340 341 { DEFINE_DBG (wvr, 0) }, 342 { DEFINE_DBG (wvr, 1) }, 343 { DEFINE_DBG (wvr, 2) }, 344 { DEFINE_DBG (wvr, 3) }, 345 { DEFINE_DBG (wvr, 4) }, 346 { DEFINE_DBG (wvr, 5) }, 347 { DEFINE_DBG (wvr, 6) }, 348 { DEFINE_DBG (wvr, 7) }, 349 { DEFINE_DBG (wvr, 8) }, 350 { DEFINE_DBG (wvr, 9) }, 351 { DEFINE_DBG (wvr, 10) }, 352 { DEFINE_DBG (wvr, 11) }, 353 { DEFINE_DBG (wvr, 12) }, 354 { DEFINE_DBG (wvr, 13) }, 355 { DEFINE_DBG (wvr, 14) }, 356 { DEFINE_DBG (wvr, 15) }, 357 358 { DEFINE_DBG (wcr, 0) }, 359 { DEFINE_DBG (wcr, 1) }, 360 { DEFINE_DBG (wcr, 2) }, 361 { DEFINE_DBG (wcr, 3) }, 362 { DEFINE_DBG (wcr, 4) }, 363 { DEFINE_DBG (wcr, 5) }, 364 { DEFINE_DBG (wcr, 6) }, 365 { DEFINE_DBG (wcr, 7) }, 366 { DEFINE_DBG (wcr, 8) }, 367 { DEFINE_DBG (wcr, 9) }, 368 { DEFINE_DBG (wcr, 10) }, 369 { DEFINE_DBG (wcr, 11) }, 370 { DEFINE_DBG (wcr, 12) }, 371 { DEFINE_DBG (wcr, 13) }, 372 { DEFINE_DBG (wcr, 14) }, 373 { DEFINE_DBG (wcr, 15) } 374 }; 375 376 // General purpose registers 377 static uint32_t 378 g_gpr_regnums[] = 379 { 380 gpr_x0, 381 gpr_x1, 382 gpr_x2, 383 gpr_x3, 384 gpr_x4, 385 gpr_x5, 386 gpr_x6, 387 gpr_x7, 388 gpr_x8, 389 gpr_x9, 390 gpr_x10, 391 gpr_x11, 392 gpr_x12, 393 gpr_x13, 394 gpr_x14, 395 gpr_x15, 396 gpr_x16, 397 gpr_x17, 398 gpr_x18, 399 gpr_x19, 400 gpr_x20, 401 gpr_x21, 402 gpr_x22, 403 gpr_x23, 404 gpr_x24, 405 gpr_x25, 406 gpr_x26, 407 gpr_x27, 408 gpr_x28, 409 gpr_fp, 410 gpr_lr, 411 gpr_sp, 412 gpr_pc, 413 gpr_cpsr 414 }; 415 416 // Floating point registers 417 static uint32_t 418 g_fpu_regnums[] = 419 { 420 fpu_v0, 421 fpu_v1, 422 fpu_v2, 423 fpu_v3, 424 fpu_v4, 425 fpu_v5, 426 fpu_v6, 427 fpu_v7, 428 fpu_v8, 429 fpu_v9, 430 fpu_v10, 431 fpu_v11, 432 fpu_v12, 433 fpu_v13, 434 fpu_v14, 435 fpu_v15, 436 fpu_v16, 437 fpu_v17, 438 fpu_v18, 439 fpu_v19, 440 fpu_v20, 441 fpu_v21, 442 fpu_v22, 443 fpu_v23, 444 fpu_v24, 445 fpu_v25, 446 fpu_v26, 447 fpu_v27, 448 fpu_v28, 449 fpu_v29, 450 fpu_v30, 451 fpu_v31, 452 fpu_fpsr, 453 fpu_fpcr 454 }; 455 456 // Exception registers 457 458 static uint32_t 459 g_exc_regnums[] = 460 { 461 exc_far, 462 exc_esr, 463 exc_exception 464 }; 465 466 static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos); 467 468 void 469 RegisterContextDarwin_arm64::InvalidateAllRegisters () 470 { 471 InvalidateAllRegisterStates(); 472 } 473 474 475 size_t 476 RegisterContextDarwin_arm64::GetRegisterCount () 477 { 478 assert(k_num_register_infos == k_num_registers); 479 return k_num_registers; 480 } 481 482 const RegisterInfo * 483 RegisterContextDarwin_arm64::GetRegisterInfoAtIndex (size_t reg) 484 { 485 assert(k_num_register_infos == k_num_registers); 486 if (reg < k_num_registers) 487 return &g_register_infos[reg]; 488 return NULL; 489 } 490 491 size_t 492 RegisterContextDarwin_arm64::GetRegisterInfosCount () 493 { 494 return k_num_register_infos; 495 } 496 497 const RegisterInfo * 498 RegisterContextDarwin_arm64::GetRegisterInfos () 499 { 500 return g_register_infos; 501 } 502 503 504 // Number of registers in each register set 505 const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums); 506 const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums); 507 const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums); 508 509 //---------------------------------------------------------------------- 510 // Register set definitions. The first definitions at register set index 511 // of zero is for all registers, followed by other registers sets. The 512 // register information for the all register set need not be filled in. 513 //---------------------------------------------------------------------- 514 static const RegisterSet g_reg_sets[] = 515 { 516 { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, }, 517 { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums }, 518 { "Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums } 519 }; 520 521 const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets); 522 523 524 size_t 525 RegisterContextDarwin_arm64::GetRegisterSetCount () 526 { 527 return k_num_regsets; 528 } 529 530 const RegisterSet * 531 RegisterContextDarwin_arm64::GetRegisterSet (size_t reg_set) 532 { 533 if (reg_set < k_num_regsets) 534 return &g_reg_sets[reg_set]; 535 return NULL; 536 } 537 538 539 //---------------------------------------------------------------------- 540 // Register information definitions for arm64 541 //---------------------------------------------------------------------- 542 int 543 RegisterContextDarwin_arm64::GetSetForNativeRegNum (int reg) 544 { 545 if (reg < fpu_v0) 546 return GPRRegSet; 547 else if (reg < exc_far) 548 return FPURegSet; 549 else if (reg < k_num_registers) 550 return EXCRegSet; 551 return -1; 552 } 553 554 int 555 RegisterContextDarwin_arm64::ReadGPR (bool force) 556 { 557 int set = GPRRegSet; 558 if (force || !RegisterSetIsCached(set)) 559 { 560 SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr)); 561 } 562 return GetError(GPRRegSet, Read); 563 } 564 565 int 566 RegisterContextDarwin_arm64::ReadFPU (bool force) 567 { 568 int set = FPURegSet; 569 if (force || !RegisterSetIsCached(set)) 570 { 571 SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu)); 572 } 573 return GetError(FPURegSet, Read); 574 } 575 576 int 577 RegisterContextDarwin_arm64::ReadEXC (bool force) 578 { 579 int set = EXCRegSet; 580 if (force || !RegisterSetIsCached(set)) 581 { 582 SetError(set, Read, DoReadEXC(GetThreadID(), set, exc)); 583 } 584 return GetError(EXCRegSet, Read); 585 } 586 587 int 588 RegisterContextDarwin_arm64::ReadDBG (bool force) 589 { 590 int set = DBGRegSet; 591 if (force || !RegisterSetIsCached(set)) 592 { 593 SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg)); 594 } 595 return GetError(DBGRegSet, Read); 596 } 597 598 int 599 RegisterContextDarwin_arm64::WriteGPR () 600 { 601 int set = GPRRegSet; 602 if (!RegisterSetIsCached(set)) 603 { 604 SetError (set, Write, -1); 605 return KERN_INVALID_ARGUMENT; 606 } 607 SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr)); 608 SetError (set, Read, -1); 609 return GetError(GPRRegSet, Write); 610 } 611 612 int 613 RegisterContextDarwin_arm64::WriteFPU () 614 { 615 int set = FPURegSet; 616 if (!RegisterSetIsCached(set)) 617 { 618 SetError (set, Write, -1); 619 return KERN_INVALID_ARGUMENT; 620 } 621 SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu)); 622 SetError (set, Read, -1); 623 return GetError(FPURegSet, Write); 624 } 625 626 int 627 RegisterContextDarwin_arm64::WriteEXC () 628 { 629 int set = EXCRegSet; 630 if (!RegisterSetIsCached(set)) 631 { 632 SetError (set, Write, -1); 633 return KERN_INVALID_ARGUMENT; 634 } 635 SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc)); 636 SetError (set, Read, -1); 637 return GetError(EXCRegSet, Write); 638 } 639 640 int 641 RegisterContextDarwin_arm64::WriteDBG () 642 { 643 int set = DBGRegSet; 644 if (!RegisterSetIsCached(set)) 645 { 646 SetError (set, Write, -1); 647 return KERN_INVALID_ARGUMENT; 648 } 649 SetError (set, Write, DoWriteDBG(GetThreadID(), set, dbg)); 650 SetError (set, Read, -1); 651 return GetError(DBGRegSet, Write); 652 } 653 654 655 int 656 RegisterContextDarwin_arm64::ReadRegisterSet (uint32_t set, bool force) 657 { 658 switch (set) 659 { 660 case GPRRegSet: return ReadGPR(force); 661 case FPURegSet: return ReadFPU(force); 662 case EXCRegSet: return ReadEXC(force); 663 case DBGRegSet: return ReadDBG(force); 664 default: break; 665 } 666 return KERN_INVALID_ARGUMENT; 667 } 668 669 int 670 RegisterContextDarwin_arm64::WriteRegisterSet (uint32_t set) 671 { 672 // Make sure we have a valid context to set. 673 if (RegisterSetIsCached(set)) 674 { 675 switch (set) 676 { 677 case GPRRegSet: return WriteGPR(); 678 case FPURegSet: return WriteFPU(); 679 case EXCRegSet: return WriteEXC(); 680 case DBGRegSet: return WriteDBG(); 681 default: break; 682 } 683 } 684 return KERN_INVALID_ARGUMENT; 685 } 686 687 void 688 RegisterContextDarwin_arm64::LogDBGRegisters (Log *log, const DBG& dbg) 689 { 690 if (log) 691 { 692 for (uint32_t i=0; i<16; i++) 693 log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8llx, 0x%8.8llx } WVR%-2u/WCR%-2u = { 0x%8.8llx, 0x%8.8llx }", 694 i, i, dbg.bvr[i], dbg.bcr[i], 695 i, i, dbg.wvr[i], dbg.wcr[i]); 696 } 697 } 698 699 700 bool 701 RegisterContextDarwin_arm64::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) 702 { 703 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 704 int set = RegisterContextDarwin_arm64::GetSetForNativeRegNum (reg); 705 706 if (set == -1) 707 return false; 708 709 if (ReadRegisterSet(set, false) != KERN_SUCCESS) 710 return false; 711 712 switch (reg) 713 { 714 case gpr_x0: 715 case gpr_x1: 716 case gpr_x2: 717 case gpr_x3: 718 case gpr_x4: 719 case gpr_x5: 720 case gpr_x6: 721 case gpr_x7: 722 case gpr_x8: 723 case gpr_x9: 724 case gpr_x10: 725 case gpr_x11: 726 case gpr_x12: 727 case gpr_x13: 728 case gpr_x14: 729 case gpr_x15: 730 case gpr_x16: 731 case gpr_x17: 732 case gpr_x18: 733 case gpr_x19: 734 case gpr_x20: 735 case gpr_x21: 736 case gpr_x22: 737 case gpr_x23: 738 case gpr_x24: 739 case gpr_x25: 740 case gpr_x26: 741 case gpr_x27: 742 case gpr_x28: 743 case gpr_fp: 744 case gpr_sp: 745 case gpr_lr: 746 case gpr_pc: 747 case gpr_cpsr: 748 value.SetUInt64 (gpr.x[reg - gpr_x0]); 749 break; 750 751 case fpu_v0: 752 case fpu_v1: 753 case fpu_v2: 754 case fpu_v3: 755 case fpu_v4: 756 case fpu_v5: 757 case fpu_v6: 758 case fpu_v7: 759 case fpu_v8: 760 case fpu_v9: 761 case fpu_v10: 762 case fpu_v11: 763 case fpu_v12: 764 case fpu_v13: 765 case fpu_v14: 766 case fpu_v15: 767 case fpu_v16: 768 case fpu_v17: 769 case fpu_v18: 770 case fpu_v19: 771 case fpu_v20: 772 case fpu_v21: 773 case fpu_v22: 774 case fpu_v23: 775 case fpu_v24: 776 case fpu_v25: 777 case fpu_v26: 778 case fpu_v27: 779 case fpu_v28: 780 case fpu_v29: 781 case fpu_v30: 782 case fpu_v31: 783 value.SetBytes(fpu.v[reg].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder()); 784 break; 785 786 case fpu_fpsr: 787 value.SetUInt32 (fpu.fpsr); 788 break; 789 790 case fpu_fpcr: 791 value.SetUInt32 (fpu.fpcr); 792 break; 793 794 case exc_exception: 795 value.SetUInt32 (exc.exception); 796 break; 797 case exc_esr: 798 value.SetUInt32 (exc.esr); 799 break; 800 case exc_far: 801 value.SetUInt64 (exc.far); 802 break; 803 804 default: 805 value.SetValueToInvalid(); 806 return false; 807 808 } 809 return true; 810 } 811 812 813 bool 814 RegisterContextDarwin_arm64::WriteRegister (const RegisterInfo *reg_info, 815 const RegisterValue &value) 816 { 817 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 818 int set = GetSetForNativeRegNum (reg); 819 820 if (set == -1) 821 return false; 822 823 if (ReadRegisterSet(set, false) != KERN_SUCCESS) 824 return false; 825 826 switch (reg) 827 { 828 case gpr_x0: 829 case gpr_x1: 830 case gpr_x2: 831 case gpr_x3: 832 case gpr_x4: 833 case gpr_x5: 834 case gpr_x6: 835 case gpr_x7: 836 case gpr_x8: 837 case gpr_x9: 838 case gpr_x10: 839 case gpr_x11: 840 case gpr_x12: 841 case gpr_x13: 842 case gpr_x14: 843 case gpr_x15: 844 case gpr_x16: 845 case gpr_x17: 846 case gpr_x18: 847 case gpr_x19: 848 case gpr_x20: 849 case gpr_x21: 850 case gpr_x22: 851 case gpr_x23: 852 case gpr_x24: 853 case gpr_x25: 854 case gpr_x26: 855 case gpr_x27: 856 case gpr_x28: 857 case gpr_fp: 858 case gpr_sp: 859 case gpr_lr: 860 case gpr_pc: 861 case gpr_cpsr: 862 gpr.x[reg - gpr_x0] = value.GetAsUInt64(); 863 break; 864 865 case fpu_v0: 866 case fpu_v1: 867 case fpu_v2: 868 case fpu_v3: 869 case fpu_v4: 870 case fpu_v5: 871 case fpu_v6: 872 case fpu_v7: 873 case fpu_v8: 874 case fpu_v9: 875 case fpu_v10: 876 case fpu_v11: 877 case fpu_v12: 878 case fpu_v13: 879 case fpu_v14: 880 case fpu_v15: 881 case fpu_v16: 882 case fpu_v17: 883 case fpu_v18: 884 case fpu_v19: 885 case fpu_v20: 886 case fpu_v21: 887 case fpu_v22: 888 case fpu_v23: 889 case fpu_v24: 890 case fpu_v25: 891 case fpu_v26: 892 case fpu_v27: 893 case fpu_v28: 894 case fpu_v29: 895 case fpu_v30: 896 case fpu_v31: 897 ::memcpy (fpu.v[reg].bytes, value.GetBytes(), value.GetByteSize()); 898 break; 899 900 case fpu_fpsr: 901 fpu.fpsr = value.GetAsUInt32(); 902 break; 903 904 case fpu_fpcr: 905 fpu.fpcr = value.GetAsUInt32(); 906 break; 907 908 case exc_exception: 909 exc.exception = value.GetAsUInt32(); 910 break; 911 case exc_esr: 912 exc.esr = value.GetAsUInt32(); 913 break; 914 case exc_far: 915 exc.far = value.GetAsUInt64(); 916 break; 917 918 default: 919 return false; 920 921 } 922 return WriteRegisterSet(set) == KERN_SUCCESS; 923 } 924 925 bool 926 RegisterContextDarwin_arm64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) 927 { 928 data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0)); 929 if (data_sp && 930 ReadGPR (false) == KERN_SUCCESS && 931 ReadFPU (false) == KERN_SUCCESS && 932 ReadEXC (false) == KERN_SUCCESS) 933 { 934 uint8_t *dst = data_sp->GetBytes(); 935 ::memcpy (dst, &gpr, sizeof(gpr)); 936 dst += sizeof(gpr); 937 938 ::memcpy (dst, &fpu, sizeof(fpu)); 939 dst += sizeof(gpr); 940 941 ::memcpy (dst, &exc, sizeof(exc)); 942 return true; 943 } 944 return false; 945 } 946 947 bool 948 RegisterContextDarwin_arm64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) 949 { 950 if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) 951 { 952 const uint8_t *src = data_sp->GetBytes(); 953 ::memcpy (&gpr, src, sizeof(gpr)); 954 src += sizeof(gpr); 955 956 ::memcpy (&fpu, src, sizeof(fpu)); 957 src += sizeof(gpr); 958 959 ::memcpy (&exc, src, sizeof(exc)); 960 uint32_t success_count = 0; 961 if (WriteGPR() == KERN_SUCCESS) 962 ++success_count; 963 if (WriteFPU() == KERN_SUCCESS) 964 ++success_count; 965 if (WriteEXC() == KERN_SUCCESS) 966 ++success_count; 967 return success_count == 3; 968 } 969 return false; 970 } 971 972 uint32_t 973 RegisterContextDarwin_arm64::ConvertRegisterKindToRegisterNumber (RegisterKind kind, uint32_t reg) 974 { 975 if (kind == eRegisterKindGeneric) 976 { 977 switch (reg) 978 { 979 case LLDB_REGNUM_GENERIC_PC: return gpr_pc; 980 case LLDB_REGNUM_GENERIC_SP: return gpr_sp; 981 case LLDB_REGNUM_GENERIC_FP: return gpr_fp; 982 case LLDB_REGNUM_GENERIC_RA: return gpr_lr; 983 case LLDB_REGNUM_GENERIC_FLAGS: return gpr_cpsr; 984 default: 985 break; 986 } 987 } 988 else if (kind == eRegisterKindDWARF) 989 { 990 switch (reg) 991 { 992 case arm64_dwarf::x0: return gpr_x0; 993 case arm64_dwarf::x1: return gpr_x1; 994 case arm64_dwarf::x2: return gpr_x2; 995 case arm64_dwarf::x3: return gpr_x3; 996 case arm64_dwarf::x4: return gpr_x4; 997 case arm64_dwarf::x5: return gpr_x5; 998 case arm64_dwarf::x6: return gpr_x6; 999 case arm64_dwarf::x7: return gpr_x7; 1000 case arm64_dwarf::x8: return gpr_x8; 1001 case arm64_dwarf::x9: return gpr_x9; 1002 case arm64_dwarf::x10: return gpr_x10; 1003 case arm64_dwarf::x11: return gpr_x11; 1004 case arm64_dwarf::x12: return gpr_x12; 1005 case arm64_dwarf::x13: return gpr_x13; 1006 case arm64_dwarf::x14: return gpr_x14; 1007 case arm64_dwarf::x15: return gpr_x15; 1008 case arm64_dwarf::x16: return gpr_x16; 1009 case arm64_dwarf::x17: return gpr_x17; 1010 case arm64_dwarf::x18: return gpr_x18; 1011 case arm64_dwarf::x19: return gpr_x19; 1012 case arm64_dwarf::x20: return gpr_x20; 1013 case arm64_dwarf::x21: return gpr_x21; 1014 case arm64_dwarf::x22: return gpr_x22; 1015 case arm64_dwarf::x23: return gpr_x23; 1016 case arm64_dwarf::x24: return gpr_x24; 1017 case arm64_dwarf::x25: return gpr_x25; 1018 case arm64_dwarf::x26: return gpr_x26; 1019 case arm64_dwarf::x27: return gpr_x27; 1020 case arm64_dwarf::x28: return gpr_x28; 1021 1022 case arm64_dwarf::fp: return gpr_fp; 1023 case arm64_dwarf::sp: return gpr_sp; 1024 case arm64_dwarf::lr: return gpr_lr; 1025 case arm64_dwarf::pc: return gpr_pc; 1026 case arm64_dwarf::cpsr: return gpr_cpsr; 1027 1028 case arm64_dwarf::v0: return fpu_v0; 1029 case arm64_dwarf::v1: return fpu_v1; 1030 case arm64_dwarf::v2: return fpu_v2; 1031 case arm64_dwarf::v3: return fpu_v3; 1032 case arm64_dwarf::v4: return fpu_v4; 1033 case arm64_dwarf::v5: return fpu_v5; 1034 case arm64_dwarf::v6: return fpu_v6; 1035 case arm64_dwarf::v7: return fpu_v7; 1036 case arm64_dwarf::v8: return fpu_v8; 1037 case arm64_dwarf::v9: return fpu_v9; 1038 case arm64_dwarf::v10: return fpu_v10; 1039 case arm64_dwarf::v11: return fpu_v11; 1040 case arm64_dwarf::v12: return fpu_v12; 1041 case arm64_dwarf::v13: return fpu_v13; 1042 case arm64_dwarf::v14: return fpu_v14; 1043 case arm64_dwarf::v15: return fpu_v15; 1044 case arm64_dwarf::v16: return fpu_v16; 1045 case arm64_dwarf::v17: return fpu_v17; 1046 case arm64_dwarf::v18: return fpu_v18; 1047 case arm64_dwarf::v19: return fpu_v19; 1048 case arm64_dwarf::v20: return fpu_v20; 1049 case arm64_dwarf::v21: return fpu_v21; 1050 case arm64_dwarf::v22: return fpu_v22; 1051 case arm64_dwarf::v23: return fpu_v23; 1052 case arm64_dwarf::v24: return fpu_v24; 1053 case arm64_dwarf::v25: return fpu_v25; 1054 case arm64_dwarf::v26: return fpu_v26; 1055 case arm64_dwarf::v27: return fpu_v27; 1056 case arm64_dwarf::v28: return fpu_v28; 1057 case arm64_dwarf::v29: return fpu_v29; 1058 case arm64_dwarf::v30: return fpu_v30; 1059 case arm64_dwarf::v31: return fpu_v31; 1060 1061 default: 1062 break; 1063 } 1064 } 1065 else if (kind == eRegisterKindGCC) 1066 { 1067 switch (reg) 1068 { 1069 case arm64_gcc::x0: return gpr_x0; 1070 case arm64_gcc::x1: return gpr_x1; 1071 case arm64_gcc::x2: return gpr_x2; 1072 case arm64_gcc::x3: return gpr_x3; 1073 case arm64_gcc::x4: return gpr_x4; 1074 case arm64_gcc::x5: return gpr_x5; 1075 case arm64_gcc::x6: return gpr_x6; 1076 case arm64_gcc::x7: return gpr_x7; 1077 case arm64_gcc::x8: return gpr_x8; 1078 case arm64_gcc::x9: return gpr_x9; 1079 case arm64_gcc::x10: return gpr_x10; 1080 case arm64_gcc::x11: return gpr_x11; 1081 case arm64_gcc::x12: return gpr_x12; 1082 case arm64_gcc::x13: return gpr_x13; 1083 case arm64_gcc::x14: return gpr_x14; 1084 case arm64_gcc::x15: return gpr_x15; 1085 case arm64_gcc::x16: return gpr_x16; 1086 case arm64_gcc::x17: return gpr_x17; 1087 case arm64_gcc::x18: return gpr_x18; 1088 case arm64_gcc::x19: return gpr_x19; 1089 case arm64_gcc::x20: return gpr_x20; 1090 case arm64_gcc::x21: return gpr_x21; 1091 case arm64_gcc::x22: return gpr_x22; 1092 case arm64_gcc::x23: return gpr_x23; 1093 case arm64_gcc::x24: return gpr_x24; 1094 case arm64_gcc::x25: return gpr_x25; 1095 case arm64_gcc::x26: return gpr_x26; 1096 case arm64_gcc::x27: return gpr_x27; 1097 case arm64_gcc::x28: return gpr_x28; 1098 case arm64_gcc::fp: return gpr_fp; 1099 case arm64_gcc::sp: return gpr_sp; 1100 case arm64_gcc::lr: return gpr_lr; 1101 case arm64_gcc::pc: return gpr_pc; 1102 case arm64_gcc::cpsr: return gpr_cpsr; 1103 } 1104 } 1105 else if (kind == eRegisterKindLLDB) 1106 { 1107 return reg; 1108 } 1109 return LLDB_INVALID_REGNUM; 1110 } 1111 1112 1113 uint32_t 1114 RegisterContextDarwin_arm64::NumSupportedHardwareWatchpoints () 1115 { 1116 #if defined (__arm64__) || defined (__aarch64__) 1117 // autodetect how many watchpoints are supported dynamically... 1118 static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX; 1119 if (g_num_supported_hw_watchpoints == UINT32_MAX) 1120 { 1121 size_t len; 1122 uint32_t n = 0; 1123 len = sizeof (n); 1124 if (::sysctlbyname("hw.optional.watchpoint", &n, &len, NULL, 0) == 0) 1125 { 1126 g_num_supported_hw_watchpoints = n; 1127 } 1128 } 1129 return g_num_supported_hw_watchpoints; 1130 #else 1131 // TODO: figure out remote case here! 1132 return 2; 1133 #endif 1134 } 1135 1136 1137 uint32_t 1138 RegisterContextDarwin_arm64::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write) 1139 { 1140 // if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(addr = %8.8p, size = %u, read = %u, write = %u)", addr, size, read, write); 1141 1142 const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); 1143 1144 // Can't watch zero bytes 1145 if (size == 0) 1146 return LLDB_INVALID_INDEX32; 1147 1148 // We must watch for either read or write 1149 if (read == false && write == false) 1150 return LLDB_INVALID_INDEX32; 1151 1152 // Can't watch more than 4 bytes per WVR/WCR pair 1153 if (size > 4) 1154 return LLDB_INVALID_INDEX32; 1155 1156 // We can only watch up to four bytes that follow a 4 byte aligned address 1157 // per watchpoint register pair. Since we have at most so we can only watch 1158 // until the next 4 byte boundary and we need to make sure we can properly 1159 // encode this. 1160 uint32_t addr_word_offset = addr % 4; 1161 // if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset); 1162 1163 uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset; 1164 // if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask); 1165 if (byte_mask > 0xfu) 1166 return LLDB_INVALID_INDEX32; 1167 1168 // Read the debug state 1169 int kret = ReadDBG (false); 1170 1171 if (kret == KERN_SUCCESS) 1172 { 1173 // Check to make sure we have the needed hardware support 1174 uint32_t i = 0; 1175 1176 for (i=0; i<num_hw_watchpoints; ++i) 1177 { 1178 if ((dbg.wcr[i] & WCR_ENABLE) == 0) 1179 break; // We found an available hw breakpoint slot (in i) 1180 } 1181 1182 // See if we found an available hw breakpoint slot above 1183 if (i < num_hw_watchpoints) 1184 { 1185 // Make the byte_mask into a valid Byte Address Select mask 1186 uint32_t byte_address_select = byte_mask << 5; 1187 // Make sure bits 1:0 are clear in our address 1188 dbg.wvr[i] = addr & ~((lldb::addr_t)3); 1189 dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA that we will watch 1190 S_USER | // Stop only in user mode 1191 (read ? WCR_LOAD : 0) | // Stop on read access? 1192 (write ? WCR_STORE : 0) | // Stop on write access? 1193 WCR_ENABLE; // Enable this watchpoint; 1194 1195 kret = WriteDBG(); 1196 // if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint() WriteDBG() => 0x%8.8x.", kret); 1197 1198 if (kret == KERN_SUCCESS) 1199 return i; 1200 } 1201 else 1202 { 1203 // if (log) log->Printf ("RegisterContextDarwin_arm64::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints); 1204 } 1205 } 1206 return LLDB_INVALID_INDEX32; 1207 } 1208 1209 bool 1210 RegisterContextDarwin_arm64::ClearHardwareWatchpoint (uint32_t hw_index) 1211 { 1212 int kret = ReadDBG (false); 1213 1214 const uint32_t num_hw_points = NumSupportedHardwareWatchpoints(); 1215 if (kret == KERN_SUCCESS) 1216 { 1217 if (hw_index < num_hw_points) 1218 { 1219 dbg.wcr[hw_index] = 0; 1220 // if (log) log->Printf ("RegisterContextDarwin_arm64::ClearHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x WCR%u = 0x%8.8x", 1221 // hw_index, 1222 // hw_index, 1223 // dbg.wvr[hw_index], 1224 // hw_index, 1225 // dbg.wcr[hw_index]); 1226 1227 kret = WriteDBG(); 1228 1229 if (kret == KERN_SUCCESS) 1230 return true; 1231 } 1232 } 1233 return false; 1234 } 1235 1236 #endif 1237