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