RegisterContextDarwin_arm.cpp revision 296417
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_DWARF_Registers.h" 38#include "Utility/ARM_ehframe_Registers.h" 39 40#include "llvm/ADT/STLExtras.h" 41 42using namespace lldb; 43using namespace lldb_private; 44 45enum 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#define GPR_OFFSET(idx) ((idx) * 4) 176#define FPU_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextDarwin_arm::GPR)) 177#define EXC_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU)) 178#define DBG_OFFSET(reg) ((LLVM_EXTENSION offsetof (RegisterContextDarwin_arm::DBG, reg) + sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU) + sizeof (RegisterContextDarwin_arm::EXC))) 179 180#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, LLDB_INVALID_REGNUM }, NULL, NULL 181#define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU) + sizeof (RegisterContextDarwin_arm::EXC)) 182 183static RegisterInfo g_register_infos[] = { 184// General purpose registers 185// NAME ALT SZ OFFSET ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB NATIVE VALUE REGS INVALIDATE REGS 186// ====== ======= == ============= ============= ============ =============== =============== ========================= ===================== ============= ========== =============== 187{ "r0", NULL, 4, GPR_OFFSET(0), eEncodingUint, eFormatHex, { ehframe_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r0 }, NULL, NULL}, 188{ "r1", NULL, 4, GPR_OFFSET(1), eEncodingUint, eFormatHex, { ehframe_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r1 }, NULL, NULL}, 189{ "r2", NULL, 4, GPR_OFFSET(2), eEncodingUint, eFormatHex, { ehframe_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r2 }, NULL, NULL}, 190{ "r3", NULL, 4, GPR_OFFSET(3), eEncodingUint, eFormatHex, { ehframe_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r3 }, NULL, NULL}, 191{ "r4", NULL, 4, GPR_OFFSET(4), eEncodingUint, eFormatHex, { ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r4 }, NULL, NULL}, 192{ "r5", NULL, 4, GPR_OFFSET(5), eEncodingUint, eFormatHex, { ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r5 }, NULL, NULL}, 193{ "r6", NULL, 4, GPR_OFFSET(6), eEncodingUint, eFormatHex, { ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r6 }, NULL, NULL}, 194{ "r7", NULL, 4, GPR_OFFSET(7), eEncodingUint, eFormatHex, { ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, gpr_r7 }, NULL, NULL}, 195{ "r8", NULL, 4, GPR_OFFSET(8), eEncodingUint, eFormatHex, { ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8 }, NULL, NULL}, 196{ "r9", NULL, 4, GPR_OFFSET(9), eEncodingUint, eFormatHex, { ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9 }, NULL, NULL}, 197{ "r10", NULL, 4, GPR_OFFSET(10), eEncodingUint, eFormatHex, { ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r10 }, NULL, NULL}, 198{ "r11", NULL, 4, GPR_OFFSET(11), eEncodingUint, eFormatHex, { ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r11 }, NULL, NULL}, 199{ "r12", NULL, 4, GPR_OFFSET(12), eEncodingUint, eFormatHex, { ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r12 }, NULL, NULL}, 200{ "sp", "r13", 4, GPR_OFFSET(13), eEncodingUint, eFormatHex, { ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, gpr_sp }, NULL, NULL}, 201{ "lr", "r14", 4, GPR_OFFSET(14), eEncodingUint, eFormatHex, { ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, gpr_lr }, NULL, NULL}, 202{ "pc", "r15", 4, GPR_OFFSET(15), eEncodingUint, eFormatHex, { ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, gpr_pc }, NULL, NULL}, 203{ "cpsr", "psr", 4, GPR_OFFSET(16), eEncodingUint, eFormatHex, { ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, gpr_cpsr }, NULL, NULL}, 204 205{ "s0", NULL, 4, FPU_OFFSET(0), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s0 }, NULL, NULL}, 206{ "s1", NULL, 4, FPU_OFFSET(1), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s1 }, NULL, NULL}, 207{ "s2", NULL, 4, FPU_OFFSET(2), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s2 }, NULL, NULL}, 208{ "s3", NULL, 4, FPU_OFFSET(3), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s3 }, NULL, NULL}, 209{ "s4", NULL, 4, FPU_OFFSET(4), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s4 }, NULL, NULL}, 210{ "s5", NULL, 4, FPU_OFFSET(5), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s5 }, NULL, NULL}, 211{ "s6", NULL, 4, FPU_OFFSET(6), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s6 }, NULL, NULL}, 212{ "s7", NULL, 4, FPU_OFFSET(7), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s7 }, NULL, NULL}, 213{ "s8", NULL, 4, FPU_OFFSET(8), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s8 }, NULL, NULL}, 214{ "s9", NULL, 4, FPU_OFFSET(9), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s9 }, NULL, NULL}, 215{ "s10", NULL, 4, FPU_OFFSET(10), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s10 }, NULL, NULL}, 216{ "s11", NULL, 4, FPU_OFFSET(11), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s11 }, NULL, NULL}, 217{ "s12", NULL, 4, FPU_OFFSET(12), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s12 }, NULL, NULL}, 218{ "s13", NULL, 4, FPU_OFFSET(13), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s13 }, NULL, NULL}, 219{ "s14", NULL, 4, FPU_OFFSET(14), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s14 }, NULL, NULL}, 220{ "s15", NULL, 4, FPU_OFFSET(15), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s15 }, NULL, NULL}, 221{ "s16", NULL, 4, FPU_OFFSET(16), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s16 }, NULL, NULL}, 222{ "s17", NULL, 4, FPU_OFFSET(17), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s17 }, NULL, NULL}, 223{ "s18", NULL, 4, FPU_OFFSET(18), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s18 }, NULL, NULL}, 224{ "s19", NULL, 4, FPU_OFFSET(19), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s19 }, NULL, NULL}, 225{ "s20", NULL, 4, FPU_OFFSET(20), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s20 }, NULL, NULL}, 226{ "s21", NULL, 4, FPU_OFFSET(21), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s21 }, NULL, NULL}, 227{ "s22", NULL, 4, FPU_OFFSET(22), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s22 }, NULL, NULL}, 228{ "s23", NULL, 4, FPU_OFFSET(23), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s23 }, NULL, NULL}, 229{ "s24", NULL, 4, FPU_OFFSET(24), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s24 }, NULL, NULL}, 230{ "s25", NULL, 4, FPU_OFFSET(25), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s25 }, NULL, NULL}, 231{ "s26", NULL, 4, FPU_OFFSET(26), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s26 }, NULL, NULL}, 232{ "s27", NULL, 4, FPU_OFFSET(27), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s27 }, NULL, NULL}, 233{ "s28", NULL, 4, FPU_OFFSET(28), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s28 }, NULL, NULL}, 234{ "s29", NULL, 4, FPU_OFFSET(29), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s29 }, NULL, NULL}, 235{ "s30", NULL, 4, FPU_OFFSET(30), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s30 }, NULL, NULL}, 236{ "s31", NULL, 4, FPU_OFFSET(31), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_s31 }, NULL, NULL}, 237{ "fpscr", NULL, 4, FPU_OFFSET(32), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fpscr }, NULL, NULL}, 238 239{ "exception",NULL, 4, EXC_OFFSET(0), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_exception }, NULL, NULL}, 240{ "fsr", NULL, 4, EXC_OFFSET(1), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_fsr }, NULL, NULL}, 241{ "far", NULL, 4, EXC_OFFSET(2), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_far }, NULL, NULL}, 242 243{ DEFINE_DBG (bvr, 0) }, 244{ DEFINE_DBG (bvr, 1) }, 245{ DEFINE_DBG (bvr, 2) }, 246{ DEFINE_DBG (bvr, 3) }, 247{ DEFINE_DBG (bvr, 4) }, 248{ DEFINE_DBG (bvr, 5) }, 249{ DEFINE_DBG (bvr, 6) }, 250{ DEFINE_DBG (bvr, 7) }, 251{ DEFINE_DBG (bvr, 8) }, 252{ DEFINE_DBG (bvr, 9) }, 253{ DEFINE_DBG (bvr, 10) }, 254{ DEFINE_DBG (bvr, 11) }, 255{ DEFINE_DBG (bvr, 12) }, 256{ DEFINE_DBG (bvr, 13) }, 257{ DEFINE_DBG (bvr, 14) }, 258{ DEFINE_DBG (bvr, 15) }, 259 260{ DEFINE_DBG (bcr, 0) }, 261{ DEFINE_DBG (bcr, 1) }, 262{ DEFINE_DBG (bcr, 2) }, 263{ DEFINE_DBG (bcr, 3) }, 264{ DEFINE_DBG (bcr, 4) }, 265{ DEFINE_DBG (bcr, 5) }, 266{ DEFINE_DBG (bcr, 6) }, 267{ DEFINE_DBG (bcr, 7) }, 268{ DEFINE_DBG (bcr, 8) }, 269{ DEFINE_DBG (bcr, 9) }, 270{ DEFINE_DBG (bcr, 10) }, 271{ DEFINE_DBG (bcr, 11) }, 272{ DEFINE_DBG (bcr, 12) }, 273{ DEFINE_DBG (bcr, 13) }, 274{ DEFINE_DBG (bcr, 14) }, 275{ DEFINE_DBG (bcr, 15) }, 276 277{ DEFINE_DBG (wvr, 0) }, 278{ DEFINE_DBG (wvr, 1) }, 279{ DEFINE_DBG (wvr, 2) }, 280{ DEFINE_DBG (wvr, 3) }, 281{ DEFINE_DBG (wvr, 4) }, 282{ DEFINE_DBG (wvr, 5) }, 283{ DEFINE_DBG (wvr, 6) }, 284{ DEFINE_DBG (wvr, 7) }, 285{ DEFINE_DBG (wvr, 8) }, 286{ DEFINE_DBG (wvr, 9) }, 287{ DEFINE_DBG (wvr, 10) }, 288{ DEFINE_DBG (wvr, 11) }, 289{ DEFINE_DBG (wvr, 12) }, 290{ DEFINE_DBG (wvr, 13) }, 291{ DEFINE_DBG (wvr, 14) }, 292{ DEFINE_DBG (wvr, 15) }, 293 294{ DEFINE_DBG (wcr, 0) }, 295{ DEFINE_DBG (wcr, 1) }, 296{ DEFINE_DBG (wcr, 2) }, 297{ DEFINE_DBG (wcr, 3) }, 298{ DEFINE_DBG (wcr, 4) }, 299{ DEFINE_DBG (wcr, 5) }, 300{ DEFINE_DBG (wcr, 6) }, 301{ DEFINE_DBG (wcr, 7) }, 302{ DEFINE_DBG (wcr, 8) }, 303{ DEFINE_DBG (wcr, 9) }, 304{ DEFINE_DBG (wcr, 10) }, 305{ DEFINE_DBG (wcr, 11) }, 306{ DEFINE_DBG (wcr, 12) }, 307{ DEFINE_DBG (wcr, 13) }, 308{ DEFINE_DBG (wcr, 14) }, 309{ DEFINE_DBG (wcr, 15) } 310}; 311 312// General purpose registers 313static uint32_t 314g_gpr_regnums[] = 315{ 316 gpr_r0, 317 gpr_r1, 318 gpr_r2, 319 gpr_r3, 320 gpr_r4, 321 gpr_r5, 322 gpr_r6, 323 gpr_r7, 324 gpr_r8, 325 gpr_r9, 326 gpr_r10, 327 gpr_r11, 328 gpr_r12, 329 gpr_sp, 330 gpr_lr, 331 gpr_pc, 332 gpr_cpsr 333}; 334 335// Floating point registers 336static uint32_t 337g_fpu_regnums[] = 338{ 339 fpu_s0, 340 fpu_s1, 341 fpu_s2, 342 fpu_s3, 343 fpu_s4, 344 fpu_s5, 345 fpu_s6, 346 fpu_s7, 347 fpu_s8, 348 fpu_s9, 349 fpu_s10, 350 fpu_s11, 351 fpu_s12, 352 fpu_s13, 353 fpu_s14, 354 fpu_s15, 355 fpu_s16, 356 fpu_s17, 357 fpu_s18, 358 fpu_s19, 359 fpu_s20, 360 fpu_s21, 361 fpu_s22, 362 fpu_s23, 363 fpu_s24, 364 fpu_s25, 365 fpu_s26, 366 fpu_s27, 367 fpu_s28, 368 fpu_s29, 369 fpu_s30, 370 fpu_s31, 371 fpu_fpscr, 372}; 373 374// Exception registers 375 376static uint32_t 377g_exc_regnums[] = 378{ 379 exc_exception, 380 exc_fsr, 381 exc_far, 382}; 383 384static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos); 385 386RegisterContextDarwin_arm::RegisterContextDarwin_arm(Thread &thread, uint32_t concrete_frame_idx) : 387 RegisterContext(thread, concrete_frame_idx), 388 gpr(), 389 fpu(), 390 exc() 391{ 392 uint32_t i; 393 for (i=0; i<kNumErrors; i++) 394 { 395 gpr_errs[i] = -1; 396 fpu_errs[i] = -1; 397 exc_errs[i] = -1; 398 } 399} 400 401RegisterContextDarwin_arm::~RegisterContextDarwin_arm() 402{ 403} 404 405 406void 407RegisterContextDarwin_arm::InvalidateAllRegisters () 408{ 409 InvalidateAllRegisterStates(); 410} 411 412 413size_t 414RegisterContextDarwin_arm::GetRegisterCount () 415{ 416 assert(k_num_register_infos == k_num_registers); 417 return k_num_registers; 418} 419 420const RegisterInfo * 421RegisterContextDarwin_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 429size_t 430RegisterContextDarwin_arm::GetRegisterInfosCount () 431{ 432 return k_num_register_infos; 433} 434 435const RegisterInfo * 436RegisterContextDarwin_arm::GetRegisterInfos () 437{ 438 return g_register_infos; 439} 440 441 442// Number of registers in each register set 443const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums); 444const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums); 445const 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//---------------------------------------------------------------------- 452static 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 459const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets); 460 461 462size_t 463RegisterContextDarwin_arm::GetRegisterSetCount () 464{ 465 return k_num_regsets; 466} 467 468const RegisterSet * 469RegisterContextDarwin_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//---------------------------------------------------------------------- 480int 481RegisterContextDarwin_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 492int 493RegisterContextDarwin_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 503int 504RegisterContextDarwin_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 514int 515RegisterContextDarwin_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 525int 526RegisterContextDarwin_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 536int 537RegisterContextDarwin_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 550int 551RegisterContextDarwin_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 564int 565RegisterContextDarwin_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 578int 579RegisterContextDarwin_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 593int 594RegisterContextDarwin_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 607int 608RegisterContextDarwin_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 625void 626RegisterContextDarwin_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 638bool 639RegisterContextDarwin_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 730bool 731RegisterContextDarwin_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 821bool 822RegisterContextDarwin_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 843bool 844RegisterContextDarwin_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 868uint32_t 869RegisterContextDarwin_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 == eRegisterKindEHFrame) 944 { 945 switch (reg) 946 { 947 case ehframe_r0: return gpr_r0; 948 case ehframe_r1: return gpr_r1; 949 case ehframe_r2: return gpr_r2; 950 case ehframe_r3: return gpr_r3; 951 case ehframe_r4: return gpr_r4; 952 case ehframe_r5: return gpr_r5; 953 case ehframe_r6: return gpr_r6; 954 case ehframe_r7: return gpr_r7; 955 case ehframe_r8: return gpr_r8; 956 case ehframe_r9: return gpr_r9; 957 case ehframe_r10: return gpr_r10; 958 case ehframe_r11: return gpr_r11; 959 case ehframe_r12: return gpr_r12; 960 case ehframe_sp: return gpr_sp; 961 case ehframe_lr: return gpr_lr; 962 case ehframe_pc: return gpr_pc; 963 case ehframe_cpsr: return gpr_cpsr; 964 } 965 } 966 else if (kind == eRegisterKindLLDB) 967 { 968 return reg; 969 } 970 return LLDB_INVALID_REGNUM; 971} 972 973 974uint32_t 975RegisterContextDarwin_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 1003uint32_t 1004RegisterContextDarwin_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 1077bool 1078RegisterContextDarwin_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 1104uint32_t 1105RegisterContextDarwin_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 1129uint32_t 1130RegisterContextDarwin_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 1201bool 1202RegisterContextDarwin_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