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