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