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