1 //===-- DNBArchImpl.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 // Created by Greg Clayton on 6/25/07. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #if defined (__arm__) 15 16 #include "MacOSX/arm/DNBArchImpl.h" 17 #include "MacOSX/MachProcess.h" 18 #include "MacOSX/MachThread.h" 19 #include "DNBBreakpoint.h" 20 #include "DNBLog.h" 21 #include "DNBRegisterInfo.h" 22 #include "DNB.h" 23 #include "ARM_GCC_Registers.h" 24 #include "ARM_DWARF_Registers.h" 25 26 #include <sys/sysctl.h> 27 28 // BCR address match type 29 #define BCR_M_IMVA_MATCH ((uint32_t)(0u << 21)) 30 #define BCR_M_CONTEXT_ID_MATCH ((uint32_t)(1u << 21)) 31 #define BCR_M_IMVA_MISMATCH ((uint32_t)(2u << 21)) 32 #define BCR_M_RESERVED ((uint32_t)(3u << 21)) 33 34 // Link a BVR/BCR or WVR/WCR pair to another 35 #define E_ENABLE_LINKING ((uint32_t)(1u << 20)) 36 37 // Byte Address Select 38 #define BAS_IMVA_PLUS_0 ((uint32_t)(1u << 5)) 39 #define BAS_IMVA_PLUS_1 ((uint32_t)(1u << 6)) 40 #define BAS_IMVA_PLUS_2 ((uint32_t)(1u << 7)) 41 #define BAS_IMVA_PLUS_3 ((uint32_t)(1u << 8)) 42 #define BAS_IMVA_0_1 ((uint32_t)(3u << 5)) 43 #define BAS_IMVA_2_3 ((uint32_t)(3u << 7)) 44 #define BAS_IMVA_ALL ((uint32_t)(0xfu << 5)) 45 46 // Break only in priveleged or user mode 47 #define S_RSVD ((uint32_t)(0u << 1)) 48 #define S_PRIV ((uint32_t)(1u << 1)) 49 #define S_USER ((uint32_t)(2u << 1)) 50 #define S_PRIV_USER ((S_PRIV) | (S_USER)) 51 52 #define BCR_ENABLE ((uint32_t)(1u)) 53 #define WCR_ENABLE ((uint32_t)(1u)) 54 55 // Watchpoint load/store 56 #define WCR_LOAD ((uint32_t)(1u << 3)) 57 #define WCR_STORE ((uint32_t)(1u << 4)) 58 59 // Definitions for the Debug Status and Control Register fields: 60 // [5:2] => Method of debug entry 61 //#define WATCHPOINT_OCCURRED ((uint32_t)(2u)) 62 // I'm seeing this, instead. 63 #define WATCHPOINT_OCCURRED ((uint32_t)(10u)) 64 65 static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 }; 66 static const uint8_t g_thumb_breakpoint_opcode[] = { 0xFE, 0xDE }; 67 68 // ARM constants used during decoding 69 #define REG_RD 0 70 #define LDM_REGLIST 1 71 #define PC_REG 15 72 #define PC_REGLIST_BIT 0x8000 73 74 // ARM conditions 75 #define COND_EQ 0x0 76 #define COND_NE 0x1 77 #define COND_CS 0x2 78 #define COND_HS 0x2 79 #define COND_CC 0x3 80 #define COND_LO 0x3 81 #define COND_MI 0x4 82 #define COND_PL 0x5 83 #define COND_VS 0x6 84 #define COND_VC 0x7 85 #define COND_HI 0x8 86 #define COND_LS 0x9 87 #define COND_GE 0xA 88 #define COND_LT 0xB 89 #define COND_GT 0xC 90 #define COND_LE 0xD 91 #define COND_AL 0xE 92 #define COND_UNCOND 0xF 93 94 #define MASK_CPSR_T (1u << 5) 95 #define MASK_CPSR_J (1u << 24) 96 97 #define MNEMONIC_STRING_SIZE 32 98 #define OPERAND_STRING_SIZE 128 99 100 101 void 102 DNBArchMachARM::Initialize() 103 { 104 DNBArchPluginInfo arch_plugin_info = 105 { 106 CPU_TYPE_ARM, 107 DNBArchMachARM::Create, 108 DNBArchMachARM::GetRegisterSetInfo, 109 DNBArchMachARM::SoftwareBreakpointOpcode 110 }; 111 112 // Register this arch plug-in with the main protocol class 113 DNBArchProtocol::RegisterArchPlugin (arch_plugin_info); 114 } 115 116 117 DNBArchProtocol * 118 DNBArchMachARM::Create (MachThread *thread) 119 { 120 DNBArchMachARM *obj = new DNBArchMachARM (thread); 121 return obj; 122 } 123 124 const uint8_t * const 125 DNBArchMachARM::SoftwareBreakpointOpcode (nub_size_t byte_size) 126 { 127 switch (byte_size) 128 { 129 case 2: return g_thumb_breakpoint_opcode; 130 case 4: return g_arm_breakpoint_opcode; 131 } 132 return NULL; 133 } 134 135 uint32_t 136 DNBArchMachARM::GetCPUType() 137 { 138 return CPU_TYPE_ARM; 139 } 140 141 uint64_t 142 DNBArchMachARM::GetPC(uint64_t failValue) 143 { 144 // Get program counter 145 if (GetGPRState(false) == KERN_SUCCESS) 146 return m_state.context.gpr.__pc; 147 return failValue; 148 } 149 150 kern_return_t 151 DNBArchMachARM::SetPC(uint64_t value) 152 { 153 // Get program counter 154 kern_return_t err = GetGPRState(false); 155 if (err == KERN_SUCCESS) 156 { 157 m_state.context.gpr.__pc = (uint32_t) value; 158 err = SetGPRState(); 159 } 160 return err == KERN_SUCCESS; 161 } 162 163 uint64_t 164 DNBArchMachARM::GetSP(uint64_t failValue) 165 { 166 // Get stack pointer 167 if (GetGPRState(false) == KERN_SUCCESS) 168 return m_state.context.gpr.__sp; 169 return failValue; 170 } 171 172 kern_return_t 173 DNBArchMachARM::GetGPRState(bool force) 174 { 175 int set = e_regSetGPR; 176 // Check if we have valid cached registers 177 if (!force && m_state.GetError(set, Read) == KERN_SUCCESS) 178 return KERN_SUCCESS; 179 180 // Read the registers from our thread 181 mach_msg_type_number_t count = ARM_THREAD_STATE_COUNT; 182 kern_return_t kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_THREAD_STATE, (thread_state_t)&m_state.context.gpr, &count); 183 uint32_t *r = &m_state.context.gpr.__r[0]; 184 DNBLogThreadedIf(LOG_THREAD, "thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x (count = %u) regs r0=%8.8x r1=%8.8x r2=%8.8x r3=%8.8x r4=%8.8x r5=%8.8x r6=%8.8x r7=%8.8x r8=%8.8x r9=%8.8x r10=%8.8x r11=%8.8x s12=%8.8x sp=%8.8x lr=%8.8x pc=%8.8x cpsr=%8.8x", 185 m_thread->MachPortNumber(), 186 ARM_THREAD_STATE, 187 ARM_THREAD_STATE_COUNT, 188 kret, 189 count, 190 r[0], 191 r[1], 192 r[2], 193 r[3], 194 r[4], 195 r[5], 196 r[6], 197 r[7], 198 r[8], 199 r[9], 200 r[10], 201 r[11], 202 r[12], 203 r[13], 204 r[14], 205 r[15], 206 r[16]); 207 m_state.SetError(set, Read, kret); 208 return kret; 209 } 210 211 kern_return_t 212 DNBArchMachARM::GetVFPState(bool force) 213 { 214 int set = e_regSetVFP; 215 // Check if we have valid cached registers 216 if (!force && m_state.GetError(set, Read) == KERN_SUCCESS) 217 return KERN_SUCCESS; 218 219 // Read the registers from our thread 220 mach_msg_type_number_t count = ARM_VFP_STATE_COUNT; 221 kern_return_t kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, &count); 222 if (DNBLogEnabledForAny (LOG_THREAD)) 223 { 224 uint32_t *r = &m_state.context.vfp.__r[0]; 225 DNBLogThreaded ("thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x (count => %u)", 226 m_thread->MachPortNumber(), 227 ARM_THREAD_STATE, 228 ARM_THREAD_STATE_COUNT, 229 kret, 230 count); 231 DNBLogThreaded(" s0=%8.8x s1=%8.8x s2=%8.8x s3=%8.8x s4=%8.8x s5=%8.8x s6=%8.8x s7=%8.8x",r[ 0],r[ 1],r[ 2],r[ 3],r[ 4],r[ 5],r[ 6],r[ 7]); 232 DNBLogThreaded(" s8=%8.8x s9=%8.8x s10=%8.8x s11=%8.8x s12=%8.8x s13=%8.8x s14=%8.8x s15=%8.8x",r[ 8],r[ 9],r[10],r[11],r[12],r[13],r[14],r[15]); 233 DNBLogThreaded(" s16=%8.8x s17=%8.8x s18=%8.8x s19=%8.8x s20=%8.8x s21=%8.8x s22=%8.8x s23=%8.8x",r[16],r[17],r[18],r[19],r[20],r[21],r[22],r[23]); 234 DNBLogThreaded(" s24=%8.8x s25=%8.8x s26=%8.8x s27=%8.8x s28=%8.8x s29=%8.8x s30=%8.8x s31=%8.8x",r[24],r[25],r[26],r[27],r[28],r[29],r[30],r[31]); 235 DNBLogThreaded(" s32=%8.8x s33=%8.8x s34=%8.8x s35=%8.8x s36=%8.8x s37=%8.8x s38=%8.8x s39=%8.8x",r[32],r[33],r[34],r[35],r[36],r[37],r[38],r[39]); 236 DNBLogThreaded(" s40=%8.8x s41=%8.8x s42=%8.8x s43=%8.8x s44=%8.8x s45=%8.8x s46=%8.8x s47=%8.8x",r[40],r[41],r[42],r[43],r[44],r[45],r[46],r[47]); 237 DNBLogThreaded(" s48=%8.8x s49=%8.8x s50=%8.8x s51=%8.8x s52=%8.8x s53=%8.8x s54=%8.8x s55=%8.8x",r[48],r[49],r[50],r[51],r[52],r[53],r[54],r[55]); 238 DNBLogThreaded(" s56=%8.8x s57=%8.8x s58=%8.8x s59=%8.8x s60=%8.8x s61=%8.8x s62=%8.8x s63=%8.8x fpscr=%8.8x",r[56],r[57],r[58],r[59],r[60],r[61],r[62],r[63],r[64]); 239 } 240 m_state.SetError(set, Read, kret); 241 return kret; 242 } 243 244 kern_return_t 245 DNBArchMachARM::GetEXCState(bool force) 246 { 247 int set = e_regSetEXC; 248 // Check if we have valid cached registers 249 if (!force && m_state.GetError(set, Read) == KERN_SUCCESS) 250 return KERN_SUCCESS; 251 252 // Read the registers from our thread 253 mach_msg_type_number_t count = ARM_EXCEPTION_STATE_COUNT; 254 kern_return_t kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, &count); 255 m_state.SetError(set, Read, kret); 256 return kret; 257 } 258 259 static void 260 DumpDBGState(const DNBArchMachARM::DBG& dbg) 261 { 262 uint32_t i = 0; 263 for (i=0; i<16; i++) 264 { 265 DNBLogThreadedIf(LOG_STEP, "BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { 0x%8.8x, 0x%8.8x }", 266 i, i, dbg.__bvr[i], dbg.__bcr[i], 267 i, i, dbg.__wvr[i], dbg.__wcr[i]); 268 } 269 } 270 271 kern_return_t 272 DNBArchMachARM::GetDBGState(bool force) 273 { 274 int set = e_regSetDBG; 275 276 // Check if we have valid cached registers 277 if (!force && m_state.GetError(set, Read) == KERN_SUCCESS) 278 return KERN_SUCCESS; 279 280 // Read the registers from our thread 281 mach_msg_type_number_t count = ARM_DEBUG_STATE_COUNT; 282 kern_return_t kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, &count); 283 m_state.SetError(set, Read, kret); 284 return kret; 285 } 286 287 kern_return_t 288 DNBArchMachARM::SetGPRState() 289 { 290 int set = e_regSetGPR; 291 kern_return_t kret = ::thread_set_state(m_thread->MachPortNumber(), ARM_THREAD_STATE, (thread_state_t)&m_state.context.gpr, ARM_THREAD_STATE_COUNT); 292 m_state.SetError(set, Write, kret); // Set the current write error for this register set 293 m_state.InvalidateRegisterSetState(set); // Invalidate the current register state in case registers are read back differently 294 return kret; // Return the error code 295 } 296 297 kern_return_t 298 DNBArchMachARM::SetVFPState() 299 { 300 int set = e_regSetVFP; 301 kern_return_t kret = ::thread_set_state (m_thread->MachPortNumber(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, ARM_VFP_STATE_COUNT); 302 m_state.SetError(set, Write, kret); // Set the current write error for this register set 303 m_state.InvalidateRegisterSetState(set); // Invalidate the current register state in case registers are read back differently 304 return kret; // Return the error code 305 } 306 307 kern_return_t 308 DNBArchMachARM::SetEXCState() 309 { 310 int set = e_regSetEXC; 311 kern_return_t kret = ::thread_set_state (m_thread->MachPortNumber(), ARM_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, ARM_EXCEPTION_STATE_COUNT); 312 m_state.SetError(set, Write, kret); // Set the current write error for this register set 313 m_state.InvalidateRegisterSetState(set); // Invalidate the current register state in case registers are read back differently 314 return kret; // Return the error code 315 } 316 317 kern_return_t 318 DNBArchMachARM::SetDBGState(bool also_set_on_task) 319 { 320 int set = e_regSetDBG; 321 kern_return_t kret = ::thread_set_state (m_thread->MachPortNumber(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, ARM_DEBUG_STATE_COUNT); 322 if (also_set_on_task) 323 { 324 kern_return_t task_kret = ::task_set_state (m_thread->Process()->Task().TaskPort(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, ARM_DEBUG_STATE_COUNT); 325 if (task_kret != KERN_SUCCESS) 326 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::SetDBGState failed to set debug control register state: 0x%8.8x.", kret); 327 } 328 329 m_state.SetError(set, Write, kret); // Set the current write error for this register set 330 m_state.InvalidateRegisterSetState(set); // Invalidate the current register state in case registers are read back differently 331 return kret; // Return the error code 332 } 333 334 void 335 DNBArchMachARM::ThreadWillResume() 336 { 337 // Do we need to step this thread? If so, let the mach thread tell us so. 338 if (m_thread->IsStepping()) 339 { 340 // This is the primary thread, let the arch do anything it needs 341 if (NumSupportedHardwareBreakpoints() > 0) 342 { 343 if (EnableHardwareSingleStep(true) != KERN_SUCCESS) 344 { 345 DNBLogThreaded("DNBArchMachARM::ThreadWillResume() failed to enable hardware single step"); 346 } 347 } 348 } 349 350 // Disable the triggered watchpoint temporarily before we resume. 351 // Plus, we try to enable hardware single step to execute past the instruction which triggered our watchpoint. 352 if (m_watchpoint_did_occur) 353 { 354 if (m_watchpoint_hw_index >= 0) 355 { 356 kern_return_t kret = GetDBGState(false); 357 if (kret == KERN_SUCCESS && !IsWatchpointEnabled(m_state.dbg, m_watchpoint_hw_index)) { 358 // The watchpoint might have been disabled by the user. We don't need to do anything at all 359 // to enable hardware single stepping. 360 m_watchpoint_did_occur = false; 361 m_watchpoint_hw_index = -1; 362 return; 363 } 364 365 DisableHardwareWatchpoint0(m_watchpoint_hw_index, true, false); 366 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::ThreadWillResume() DisableHardwareWatchpoint(%d) called", 367 m_watchpoint_hw_index); 368 369 // Enable hardware single step to move past the watchpoint-triggering instruction. 370 m_watchpoint_resume_single_step_enabled = (EnableHardwareSingleStep(true) == KERN_SUCCESS); 371 372 // If we are not able to enable single step to move past the watchpoint-triggering instruction, 373 // at least we should reset the two watchpoint member variables so that the next time around 374 // this callback function is invoked, the enclosing logical branch is skipped. 375 if (!m_watchpoint_resume_single_step_enabled) { 376 // Reset the two watchpoint member variables. 377 m_watchpoint_did_occur = false; 378 m_watchpoint_hw_index = -1; 379 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::ThreadWillResume() failed to enable single step"); 380 } 381 else 382 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::ThreadWillResume() succeeded to enable single step"); 383 } 384 } 385 } 386 387 bool 388 DNBArchMachARM::ThreadDidStop() 389 { 390 bool success = true; 391 392 m_state.InvalidateRegisterSetState (e_regSetALL); 393 394 if (m_watchpoint_resume_single_step_enabled) 395 { 396 // Great! We now disable the hardware single step as well as re-enable the hardware watchpoint. 397 // See also ThreadWillResume(). 398 if (EnableHardwareSingleStep(false) == KERN_SUCCESS) 399 { 400 if (m_watchpoint_did_occur && m_watchpoint_hw_index >= 0) 401 { 402 EnableHardwareWatchpoint0(m_watchpoint_hw_index, true, false); 403 m_watchpoint_resume_single_step_enabled = false; 404 m_watchpoint_did_occur = false; 405 m_watchpoint_hw_index = -1; 406 } 407 else 408 { 409 DNBLogError("internal error detected: m_watchpoint_resume_step_enabled is true but (m_watchpoint_did_occur && m_watchpoint_hw_index >= 0) does not hold!"); 410 } 411 } 412 else 413 { 414 DNBLogError("internal error detected: m_watchpoint_resume_step_enabled is true but unable to disable single step!"); 415 } 416 } 417 418 // Are we stepping a single instruction? 419 if (GetGPRState(true) == KERN_SUCCESS) 420 { 421 // We are single stepping, was this the primary thread? 422 if (m_thread->IsStepping()) 423 { 424 success = EnableHardwareSingleStep(false) == KERN_SUCCESS; 425 } 426 else 427 { 428 // The MachThread will automatically restore the suspend count 429 // in ThreadDidStop(), so we don't need to do anything here if 430 // we weren't the primary thread the last time 431 } 432 } 433 return success; 434 } 435 436 bool 437 DNBArchMachARM::NotifyException(MachException::Data& exc) 438 { 439 switch (exc.exc_type) 440 { 441 default: 442 break; 443 case EXC_BREAKPOINT: 444 if (exc.exc_data.size() == 2 && exc.exc_data[0] == EXC_ARM_DA_DEBUG) 445 { 446 // exc_code = EXC_ARM_DA_DEBUG 447 // 448 // Check whether this corresponds to a watchpoint hit event. 449 // If yes, retrieve the exc_sub_code as the data break address. 450 if (!HasWatchpointOccurred()) 451 break; 452 453 // The data break address is passed as exc_data[1]. 454 nub_addr_t addr = exc.exc_data[1]; 455 // Find the hardware index with the side effect of possibly massaging the 456 // addr to return the starting address as seen from the debugger side. 457 uint32_t hw_index = GetHardwareWatchpointHit(addr); 458 if (hw_index != INVALID_NUB_HW_INDEX) 459 { 460 m_watchpoint_did_occur = true; 461 m_watchpoint_hw_index = hw_index; 462 exc.exc_data[1] = addr; 463 // Piggyback the hw_index in the exc.data. 464 exc.exc_data.push_back(hw_index); 465 } 466 467 return true; 468 } 469 break; 470 } 471 return false; 472 } 473 474 bool 475 DNBArchMachARM::StepNotComplete () 476 { 477 if (m_hw_single_chained_step_addr != INVALID_NUB_ADDRESS) 478 { 479 kern_return_t kret = KERN_INVALID_ARGUMENT; 480 kret = GetGPRState(false); 481 if (kret == KERN_SUCCESS) 482 { 483 if (m_state.context.gpr.__pc == m_hw_single_chained_step_addr) 484 { 485 DNBLogThreadedIf(LOG_STEP, "Need to step some more at 0x%8.8llx", (uint64_t) m_hw_single_chained_step_addr); 486 return true; 487 } 488 } 489 } 490 491 m_hw_single_chained_step_addr = INVALID_NUB_ADDRESS; 492 return false; 493 } 494 495 496 // Set the single step bit in the processor status register. 497 kern_return_t 498 DNBArchMachARM::EnableHardwareSingleStep (bool enable) 499 { 500 DNBError err; 501 DNBLogThreadedIf(LOG_STEP, "%s( enable = %d )", __FUNCTION__, enable); 502 503 err = GetGPRState(false); 504 505 if (err.Fail()) 506 { 507 err.LogThreaded("%s: failed to read the GPR registers", __FUNCTION__); 508 return err.Error(); 509 } 510 511 err = GetDBGState(false); 512 513 if (err.Fail()) 514 { 515 err.LogThreaded("%s: failed to read the DBG registers", __FUNCTION__); 516 return err.Error(); 517 } 518 519 const uint32_t i = 0; 520 if (enable) 521 { 522 m_hw_single_chained_step_addr = INVALID_NUB_ADDRESS; 523 524 // Save our previous state 525 m_dbg_save = m_state.dbg; 526 // Set a breakpoint that will stop when the PC doesn't match the current one! 527 m_state.dbg.__bvr[i] = m_state.context.gpr.__pc & 0xFFFFFFFCu; // Set the current PC as the breakpoint address 528 m_state.dbg.__bcr[i] = BCR_M_IMVA_MISMATCH | // Stop on address mismatch 529 S_USER | // Stop only in user mode 530 BCR_ENABLE; // Enable this breakpoint 531 if (m_state.context.gpr.__cpsr & 0x20) 532 { 533 // Thumb breakpoint 534 if (m_state.context.gpr.__pc & 2) 535 m_state.dbg.__bcr[i] |= BAS_IMVA_2_3; 536 else 537 m_state.dbg.__bcr[i] |= BAS_IMVA_0_1; 538 539 uint16_t opcode; 540 if (sizeof(opcode) == m_thread->Process()->Task().ReadMemory(m_state.context.gpr.__pc, sizeof(opcode), &opcode)) 541 { 542 if (((opcode & 0xE000) == 0xE000) && opcode & 0x1800) 543 { 544 // 32 bit thumb opcode... 545 if (m_state.context.gpr.__pc & 2) 546 { 547 // We can't take care of a 32 bit thumb instruction single step 548 // with just IVA mismatching. We will need to chain an extra 549 // hardware single step in order to complete this single step... 550 m_hw_single_chained_step_addr = m_state.context.gpr.__pc + 2; 551 } 552 else 553 { 554 // Extend the number of bits to ignore for the mismatch 555 m_state.dbg.__bcr[i] |= BAS_IMVA_ALL; 556 } 557 } 558 } 559 } 560 else 561 { 562 // ARM breakpoint 563 m_state.dbg.__bcr[i] |= BAS_IMVA_ALL; // Stop when any address bits change 564 } 565 566 DNBLogThreadedIf(LOG_STEP, "%s: BVR%u=0x%8.8x BCR%u=0x%8.8x", __FUNCTION__, i, m_state.dbg.__bvr[i], i, m_state.dbg.__bcr[i]); 567 568 for (uint32_t j=i+1; j<16; ++j) 569 { 570 // Disable all others 571 m_state.dbg.__bvr[j] = 0; 572 m_state.dbg.__bcr[j] = 0; 573 } 574 } 575 else 576 { 577 // Just restore the state we had before we did single stepping 578 m_state.dbg = m_dbg_save; 579 } 580 581 return SetDBGState(false); 582 } 583 584 // return 1 if bit "BIT" is set in "value" 585 static inline uint32_t bit(uint32_t value, uint32_t bit) 586 { 587 return (value >> bit) & 1u; 588 } 589 590 // return the bitfield "value[msbit:lsbit]". 591 static inline uint32_t bits(uint32_t value, uint32_t msbit, uint32_t lsbit) 592 { 593 assert(msbit >= lsbit); 594 uint32_t shift_left = sizeof(value) * 8 - 1 - msbit; 595 value <<= shift_left; // shift anything above the msbit off of the unsigned edge 596 value >>= (shift_left + lsbit); // shift it back again down to the lsbit (including undoing any shift from above) 597 return value; // return our result 598 } 599 600 bool 601 DNBArchMachARM::ConditionPassed(uint8_t condition, uint32_t cpsr) 602 { 603 uint32_t cpsr_n = bit(cpsr, 31); // Negative condition code flag 604 uint32_t cpsr_z = bit(cpsr, 30); // Zero condition code flag 605 uint32_t cpsr_c = bit(cpsr, 29); // Carry condition code flag 606 uint32_t cpsr_v = bit(cpsr, 28); // Overflow condition code flag 607 608 switch (condition) { 609 case COND_EQ: // (0x0) 610 if (cpsr_z == 1) return true; 611 break; 612 case COND_NE: // (0x1) 613 if (cpsr_z == 0) return true; 614 break; 615 case COND_CS: // (0x2) 616 if (cpsr_c == 1) return true; 617 break; 618 case COND_CC: // (0x3) 619 if (cpsr_c == 0) return true; 620 break; 621 case COND_MI: // (0x4) 622 if (cpsr_n == 1) return true; 623 break; 624 case COND_PL: // (0x5) 625 if (cpsr_n == 0) return true; 626 break; 627 case COND_VS: // (0x6) 628 if (cpsr_v == 1) return true; 629 break; 630 case COND_VC: // (0x7) 631 if (cpsr_v == 0) return true; 632 break; 633 case COND_HI: // (0x8) 634 if ((cpsr_c == 1) && (cpsr_z == 0)) return true; 635 break; 636 case COND_LS: // (0x9) 637 if ((cpsr_c == 0) || (cpsr_z == 1)) return true; 638 break; 639 case COND_GE: // (0xA) 640 if (cpsr_n == cpsr_v) return true; 641 break; 642 case COND_LT: // (0xB) 643 if (cpsr_n != cpsr_v) return true; 644 break; 645 case COND_GT: // (0xC) 646 if ((cpsr_z == 0) && (cpsr_n == cpsr_v)) return true; 647 break; 648 case COND_LE: // (0xD) 649 if ((cpsr_z == 1) || (cpsr_n != cpsr_v)) return true; 650 break; 651 default: 652 return true; 653 break; 654 } 655 656 return false; 657 } 658 659 uint32_t 660 DNBArchMachARM::NumSupportedHardwareBreakpoints() 661 { 662 // Set the init value to something that will let us know that we need to 663 // autodetect how many breakpoints are supported dynamically... 664 static uint32_t g_num_supported_hw_breakpoints = UINT_MAX; 665 if (g_num_supported_hw_breakpoints == UINT_MAX) 666 { 667 // Set this to zero in case we can't tell if there are any HW breakpoints 668 g_num_supported_hw_breakpoints = 0; 669 670 size_t len; 671 uint32_t n = 0; 672 len = sizeof (n); 673 if (::sysctlbyname("hw.optional.breakpoint", &n, &len, NULL, 0) == 0) 674 { 675 g_num_supported_hw_breakpoints = n; 676 DNBLogThreadedIf(LOG_THREAD, "hw.optional.breakpoint=%u", n); 677 } 678 else 679 { 680 // Read the DBGDIDR to get the number of available hardware breakpoints 681 // However, in some of our current armv7 processors, hardware 682 // breakpoints/watchpoints were not properly connected. So detect those 683 // cases using a field in a sysctl. For now we are using "hw.cpusubtype" 684 // field to distinguish CPU architectures. This is a hack until we can 685 // get <rdar://problem/6372672> fixed, at which point we will switch to 686 // using a different sysctl string that will tell us how many BRPs 687 // are available to us directly without having to read DBGDIDR. 688 uint32_t register_DBGDIDR; 689 690 asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR)); 691 uint32_t numBRPs = bits(register_DBGDIDR, 27, 24); 692 // Zero is reserved for the BRP count, so don't increment it if it is zero 693 if (numBRPs > 0) 694 numBRPs++; 695 DNBLogThreadedIf(LOG_THREAD, "DBGDIDR=0x%8.8x (number BRP pairs = %u)", register_DBGDIDR, numBRPs); 696 697 if (numBRPs > 0) 698 { 699 uint32_t cpusubtype; 700 len = sizeof(cpusubtype); 701 // TODO: remove this hack and change to using hw.optional.xx when implmented 702 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0) 703 { 704 DNBLogThreadedIf(LOG_THREAD, "hw.cpusubtype=%d", cpusubtype); 705 if (cpusubtype == CPU_SUBTYPE_ARM_V7) 706 DNBLogThreadedIf(LOG_THREAD, "Hardware breakpoints disabled for armv7 (rdar://problem/6372672)"); 707 else 708 g_num_supported_hw_breakpoints = numBRPs; 709 } 710 } 711 } 712 } 713 return g_num_supported_hw_breakpoints; 714 } 715 716 717 uint32_t 718 DNBArchMachARM::NumSupportedHardwareWatchpoints() 719 { 720 // Set the init value to something that will let us know that we need to 721 // autodetect how many watchpoints are supported dynamically... 722 static uint32_t g_num_supported_hw_watchpoints = UINT_MAX; 723 if (g_num_supported_hw_watchpoints == UINT_MAX) 724 { 725 // Set this to zero in case we can't tell if there are any HW breakpoints 726 g_num_supported_hw_watchpoints = 0; 727 728 729 size_t len; 730 uint32_t n = 0; 731 len = sizeof (n); 732 if (::sysctlbyname("hw.optional.watchpoint", &n, &len, NULL, 0) == 0) 733 { 734 g_num_supported_hw_watchpoints = n; 735 DNBLogThreadedIf(LOG_THREAD, "hw.optional.watchpoint=%u", n); 736 } 737 else 738 { 739 // Read the DBGDIDR to get the number of available hardware breakpoints 740 // However, in some of our current armv7 processors, hardware 741 // breakpoints/watchpoints were not properly connected. So detect those 742 // cases using a field in a sysctl. For now we are using "hw.cpusubtype" 743 // field to distinguish CPU architectures. This is a hack until we can 744 // get <rdar://problem/6372672> fixed, at which point we will switch to 745 // using a different sysctl string that will tell us how many WRPs 746 // are available to us directly without having to read DBGDIDR. 747 748 uint32_t register_DBGDIDR; 749 asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR)); 750 uint32_t numWRPs = bits(register_DBGDIDR, 31, 28) + 1; 751 DNBLogThreadedIf(LOG_THREAD, "DBGDIDR=0x%8.8x (number WRP pairs = %u)", register_DBGDIDR, numWRPs); 752 753 if (numWRPs > 0) 754 { 755 uint32_t cpusubtype; 756 size_t len; 757 len = sizeof(cpusubtype); 758 // TODO: remove this hack and change to using hw.optional.xx when implmented 759 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0) 760 { 761 DNBLogThreadedIf(LOG_THREAD, "hw.cpusubtype=0x%d", cpusubtype); 762 763 if (cpusubtype == CPU_SUBTYPE_ARM_V7) 764 DNBLogThreadedIf(LOG_THREAD, "Hardware watchpoints disabled for armv7 (rdar://problem/6372672)"); 765 else 766 g_num_supported_hw_watchpoints = numWRPs; 767 } 768 } 769 } 770 } 771 return g_num_supported_hw_watchpoints; 772 } 773 774 775 uint32_t 776 DNBArchMachARM::EnableHardwareBreakpoint (nub_addr_t addr, nub_size_t size) 777 { 778 // Make sure our address isn't bogus 779 if (addr & 1) 780 return INVALID_NUB_HW_INDEX; 781 782 kern_return_t kret = GetDBGState(false); 783 784 if (kret == KERN_SUCCESS) 785 { 786 const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints(); 787 uint32_t i; 788 for (i=0; i<num_hw_breakpoints; ++i) 789 { 790 if ((m_state.dbg.__bcr[i] & BCR_ENABLE) == 0) 791 break; // We found an available hw breakpoint slot (in i) 792 } 793 794 // See if we found an available hw breakpoint slot above 795 if (i < num_hw_breakpoints) 796 { 797 // Make sure bits 1:0 are clear in our address 798 m_state.dbg.__bvr[i] = addr & ~((nub_addr_t)3); 799 800 if (size == 2 || addr & 2) 801 { 802 uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1; 803 804 // We have a thumb breakpoint 805 // We have an ARM breakpoint 806 m_state.dbg.__bcr[i] = BCR_M_IMVA_MATCH | // Stop on address mismatch 807 byte_addr_select | // Set the correct byte address select so we only trigger on the correct opcode 808 S_USER | // Which modes should this breakpoint stop in? 809 BCR_ENABLE; // Enable this hardware breakpoint 810 DNBLogThreadedIf (LOG_BREAKPOINTS, "DNBArchMachARM::EnableHardwareBreakpoint( addr = 0x%8.8llx, size = %llu ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (Thumb)", 811 (uint64_t)addr, 812 (uint64_t)size, 813 i, 814 i, 815 m_state.dbg.__bvr[i], 816 m_state.dbg.__bcr[i]); 817 } 818 else if (size == 4) 819 { 820 // We have an ARM breakpoint 821 m_state.dbg.__bcr[i] = BCR_M_IMVA_MATCH | // Stop on address mismatch 822 BAS_IMVA_ALL | // Stop on any of the four bytes following the IMVA 823 S_USER | // Which modes should this breakpoint stop in? 824 BCR_ENABLE; // Enable this hardware breakpoint 825 DNBLogThreadedIf (LOG_BREAKPOINTS, "DNBArchMachARM::EnableHardwareBreakpoint( addr = 0x%8.8llx, size = %llu ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (ARM)", 826 (uint64_t)addr, 827 (uint64_t)size, 828 i, 829 i, 830 m_state.dbg.__bvr[i], 831 m_state.dbg.__bcr[i]); 832 } 833 834 kret = SetDBGState(false); 835 DNBLogThreadedIf(LOG_BREAKPOINTS, "DNBArchMachARM::EnableHardwareBreakpoint() SetDBGState() => 0x%8.8x.", kret); 836 837 if (kret == KERN_SUCCESS) 838 return i; 839 } 840 else 841 { 842 DNBLogThreadedIf (LOG_BREAKPOINTS, "DNBArchMachARM::EnableHardwareBreakpoint(addr = 0x%8.8llx, size = %llu) => all hardware breakpoint resources are being used.", (uint64_t)addr, (uint64_t)size); 843 } 844 } 845 846 return INVALID_NUB_HW_INDEX; 847 } 848 849 bool 850 DNBArchMachARM::DisableHardwareBreakpoint (uint32_t hw_index) 851 { 852 kern_return_t kret = GetDBGState(false); 853 854 const uint32_t num_hw_points = NumSupportedHardwareBreakpoints(); 855 if (kret == KERN_SUCCESS) 856 { 857 if (hw_index < num_hw_points) 858 { 859 m_state.dbg.__bcr[hw_index] = 0; 860 DNBLogThreadedIf(LOG_BREAKPOINTS, "DNBArchMachARM::SetHardwareBreakpoint( %u ) - BVR%u = 0x%8.8x BCR%u = 0x%8.8x", 861 hw_index, 862 hw_index, 863 m_state.dbg.__bvr[hw_index], 864 hw_index, 865 m_state.dbg.__bcr[hw_index]); 866 867 kret = SetDBGState(false); 868 869 if (kret == KERN_SUCCESS) 870 return true; 871 } 872 } 873 return false; 874 } 875 876 // This stores the lo->hi mappings. It's safe to initialize to all 0's 877 // since hi > lo and therefore LoHi[i] cannot be 0. 878 static uint32_t LoHi[16] = { 0 }; 879 880 uint32_t 881 DNBArchMachARM::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write, bool also_set_on_task) 882 { 883 884 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint(addr = 0x%8.8llx, size = %zu, read = %u, write = %u)", (uint64_t)addr, size, read, write); 885 886 const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); 887 888 // Can't watch zero bytes 889 if (size == 0) 890 return INVALID_NUB_HW_INDEX; 891 892 // We must watch for either read or write 893 if (read == false && write == false) 894 return INVALID_NUB_HW_INDEX; 895 896 // Divide-and-conquer for size == 8. 897 if (size == 8) 898 { 899 uint32_t lo = EnableHardwareWatchpoint(addr, 4, read, write, also_set_on_task); 900 if (lo == INVALID_NUB_HW_INDEX) 901 return INVALID_NUB_HW_INDEX; 902 uint32_t hi = EnableHardwareWatchpoint(addr+4, 4, read, write, also_set_on_task); 903 if (hi == INVALID_NUB_HW_INDEX) 904 { 905 DisableHardwareWatchpoint(lo, also_set_on_task); 906 return INVALID_NUB_HW_INDEX; 907 } 908 // Tag this lo->hi mapping in our database. 909 LoHi[lo] = hi; 910 return lo; 911 } 912 913 // Otherwise, can't watch more than 4 bytes per WVR/WCR pair 914 if (size > 4) 915 return INVALID_NUB_HW_INDEX; 916 917 // We can only watch up to four bytes that follow a 4 byte aligned address 918 // per watchpoint register pair. Since we can only watch until the next 4 919 // byte boundary, we need to make sure we can properly encode this. 920 921 // addr_word_offset = addr % 4, i.e, is in set([0, 1, 2, 3]) 922 // 923 // +---+---+---+---+ 924 // | 0 | 1 | 2 | 3 | 925 // +---+---+---+---+ 926 // ^ 927 // | 928 // word address (4-byte aligned) = addr & 0xFFFFFFFC => goes into WVR 929 // 930 // examples: 931 // 1. addr_word_offset = 1, size = 1 to watch a uint_8 => byte_mask = (0b0001 << 1) = 0b0010 932 // 2. addr_word_offset = 2, size = 2 to watch a uint_16 => byte_mask = (0b0011 << 2) = 0b1100 933 // 934 // where byte_mask goes into WCR[8:5] 935 936 uint32_t addr_word_offset = addr % 4; 937 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset); 938 939 uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset; 940 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask); 941 if (byte_mask > 0xfu) 942 return INVALID_NUB_HW_INDEX; 943 944 // Read the debug state 945 kern_return_t kret = GetDBGState(true); 946 947 if (kret == KERN_SUCCESS) 948 { 949 // Check to make sure we have the needed hardware support 950 uint32_t i = 0; 951 952 for (i=0; i<num_hw_watchpoints; ++i) 953 { 954 if ((m_state.dbg.__wcr[i] & WCR_ENABLE) == 0) 955 break; // We found an available hw watchpoint slot (in i) 956 } 957 958 // See if we found an available hw watchpoint slot above 959 if (i < num_hw_watchpoints) 960 { 961 //DumpDBGState(m_state.dbg); 962 963 // Make the byte_mask into a valid Byte Address Select mask 964 uint32_t byte_address_select = byte_mask << 5; 965 // Make sure bits 1:0 are clear in our address 966 m_state.dbg.__wvr[i] = addr & ~((nub_addr_t)3); // DVA (Data Virtual Address) 967 m_state.dbg.__wcr[i] = byte_address_select | // Which bytes that follow the DVA that we will watch 968 S_USER | // Stop only in user mode 969 (read ? WCR_LOAD : 0) | // Stop on read access? 970 (write ? WCR_STORE : 0) | // Stop on write access? 971 WCR_ENABLE; // Enable this watchpoint; 972 973 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() adding watchpoint on address 0x%llx with control register value 0x%x", (uint64_t) m_state.dbg.__wvr[i], (uint32_t) m_state.dbg.__wcr[i]); 974 975 kret = SetDBGState(also_set_on_task); 976 //DumpDBGState(m_state.dbg); 977 978 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() SetDBGState() => 0x%8.8x.", kret); 979 980 if (kret == KERN_SUCCESS) 981 return i; 982 } 983 else 984 { 985 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints); 986 } 987 } 988 return INVALID_NUB_HW_INDEX; 989 } 990 991 bool 992 DNBArchMachARM::EnableHardwareWatchpoint0 (uint32_t hw_index, bool Delegate, bool also_set_on_task) 993 { 994 kern_return_t kret = GetDBGState(false); 995 if (kret != KERN_SUCCESS) 996 return false; 997 998 const uint32_t num_hw_points = NumSupportedHardwareWatchpoints(); 999 if (hw_index >= num_hw_points) 1000 return false; 1001 1002 if (Delegate && LoHi[hw_index]) { 1003 // Enable lo and hi watchpoint hardware indexes. 1004 return EnableHardwareWatchpoint0(hw_index, false, also_set_on_task) && 1005 EnableHardwareWatchpoint0(LoHi[hw_index], false, also_set_on_task); 1006 } 1007 1008 m_state.dbg.__wcr[hw_index] |= (nub_addr_t)WCR_ENABLE; 1009 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x WCR%u = 0x%8.8x", 1010 hw_index, 1011 hw_index, 1012 m_state.dbg.__wvr[hw_index], 1013 hw_index, 1014 m_state.dbg.__wcr[hw_index]); 1015 1016 kret = SetDBGState(false); 1017 1018 return (kret == KERN_SUCCESS); 1019 } 1020 1021 bool 1022 DNBArchMachARM::DisableHardwareWatchpoint (uint32_t hw_index, bool also_set_on_task) 1023 { 1024 return DisableHardwareWatchpoint0(hw_index, true, also_set_on_task); 1025 } 1026 bool 1027 DNBArchMachARM::DisableHardwareWatchpoint0 (uint32_t hw_index, bool Delegate, bool also_set_on_task) 1028 { 1029 kern_return_t kret = GetDBGState(false); 1030 if (kret != KERN_SUCCESS) 1031 return false; 1032 1033 const uint32_t num_hw_points = NumSupportedHardwareWatchpoints(); 1034 if (hw_index >= num_hw_points) 1035 return false; 1036 1037 if (Delegate && LoHi[hw_index]) { 1038 // Disable lo and hi watchpoint hardware indexes. 1039 return DisableHardwareWatchpoint0(hw_index, false, also_set_on_task) && 1040 DisableHardwareWatchpoint0(LoHi[hw_index], false, also_set_on_task); 1041 } 1042 1043 m_state.dbg.__wcr[hw_index] &= ~((nub_addr_t)WCR_ENABLE); 1044 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::DisableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x WCR%u = 0x%8.8x", 1045 hw_index, 1046 hw_index, 1047 m_state.dbg.__wvr[hw_index], 1048 hw_index, 1049 m_state.dbg.__wcr[hw_index]); 1050 1051 kret = SetDBGState(also_set_on_task); 1052 1053 return (kret == KERN_SUCCESS); 1054 } 1055 1056 // Returns -1 if the trailing bit patterns are not one of: 1057 // { 0b???1, 0b??10, 0b?100, 0b1000 }. 1058 static inline 1059 int32_t 1060 LowestBitSet(uint32_t val) 1061 { 1062 for (unsigned i = 0; i < 4; ++i) { 1063 if (bit(val, i)) 1064 return i; 1065 } 1066 return -1; 1067 } 1068 1069 // Iterate through the debug registers; return the index of the first watchpoint whose address matches. 1070 // As a side effect, the starting address as understood by the debugger is returned which could be 1071 // different from 'addr' passed as an in/out argument. 1072 uint32_t 1073 DNBArchMachARM::GetHardwareWatchpointHit(nub_addr_t &addr) 1074 { 1075 // Read the debug state 1076 kern_return_t kret = GetDBGState(true); 1077 //DumpDBGState(m_state.dbg); 1078 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::GetHardwareWatchpointHit() GetDBGState() => 0x%8.8x.", kret); 1079 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::GetHardwareWatchpointHit() addr = 0x%llx", (uint64_t)addr); 1080 1081 // This is the watchpoint value to match against, i.e., word address. 1082 nub_addr_t wp_val = addr & ~((nub_addr_t)3); 1083 if (kret == KERN_SUCCESS) 1084 { 1085 DBG &debug_state = m_state.dbg; 1086 uint32_t i, num = NumSupportedHardwareWatchpoints(); 1087 for (i = 0; i < num; ++i) 1088 { 1089 nub_addr_t wp_addr = GetWatchAddress(debug_state, i); 1090 DNBLogThreadedIf(LOG_WATCHPOINTS, 1091 "DNBArchMachARM::GetHardwareWatchpointHit() slot: %u (addr = 0x%llx).", 1092 i, (uint64_t)wp_addr); 1093 if (wp_val == wp_addr) { 1094 uint32_t byte_mask = bits(debug_state.__wcr[i], 8, 5); 1095 1096 // Sanity check the byte_mask, first. 1097 if (LowestBitSet(byte_mask) < 0) 1098 continue; 1099 1100 // Compute the starting address (from the point of view of the debugger). 1101 addr = wp_addr + LowestBitSet(byte_mask); 1102 return i; 1103 } 1104 } 1105 } 1106 return INVALID_NUB_HW_INDEX; 1107 } 1108 1109 // ThreadWillResume() calls this to clear bits[5:2] (Method of entry bits) of 1110 // the Debug Status and Control Register (DSCR). 1111 // 1112 // b0010 = a watchpoint occurred 1113 // b0000 is the reset value 1114 void 1115 DNBArchMachARM::ClearWatchpointOccurred() 1116 { 1117 uint32_t register_DBGDSCR; 1118 asm("mrc p14, 0, %0, c0, c1, 0" : "=r" (register_DBGDSCR)); 1119 if (bits(register_DBGDSCR, 5, 2) == WATCHPOINT_OCCURRED) 1120 { 1121 uint32_t mask = ~(0xF << 2); 1122 register_DBGDSCR &= mask; 1123 asm("mcr p14, 0, %0, c0, c1, 0" : "=r" (register_DBGDSCR)); 1124 } 1125 return; 1126 } 1127 1128 // NotifyException() calls this to double check that a watchpoint has occurred 1129 // by inspecting the bits[5:2] field of the Debug Status and Control Register 1130 // (DSCR). 1131 // 1132 // b0010 = a watchpoint occurred 1133 bool 1134 DNBArchMachARM::HasWatchpointOccurred() 1135 { 1136 uint32_t register_DBGDSCR; 1137 asm("mrc p14, 0, %0, c0, c1, 0" : "=r" (register_DBGDSCR)); 1138 return (bits(register_DBGDSCR, 5, 2) == WATCHPOINT_OCCURRED); 1139 } 1140 1141 bool 1142 DNBArchMachARM::IsWatchpointEnabled(const DBG &debug_state, uint32_t hw_index) 1143 { 1144 // Watchpoint Control Registers, bitfield definitions 1145 // ... 1146 // Bits Value Description 1147 // [0] 0 Watchpoint disabled 1148 // 1 Watchpoint enabled. 1149 return (debug_state.__wcr[hw_index] & 1u); 1150 } 1151 1152 nub_addr_t 1153 DNBArchMachARM::GetWatchAddress(const DBG &debug_state, uint32_t hw_index) 1154 { 1155 // Watchpoint Value Registers, bitfield definitions 1156 // Bits Description 1157 // [31:2] Watchpoint value (word address, i.e., 4-byte aligned) 1158 // [1:0] RAZ/SBZP 1159 return bits(debug_state.__wvr[hw_index], 31, 0); 1160 } 1161 1162 //---------------------------------------------------------------------- 1163 // Register information defintions for 32 bit ARMV7. 1164 //---------------------------------------------------------------------- 1165 enum gpr_regnums 1166 { 1167 gpr_r0 = 0, 1168 gpr_r1, 1169 gpr_r2, 1170 gpr_r3, 1171 gpr_r4, 1172 gpr_r5, 1173 gpr_r6, 1174 gpr_r7, 1175 gpr_r8, 1176 gpr_r9, 1177 gpr_r10, 1178 gpr_r11, 1179 gpr_r12, 1180 gpr_sp, 1181 gpr_lr, 1182 gpr_pc, 1183 gpr_cpsr 1184 }; 1185 1186 enum 1187 { 1188 vfp_s0 = 0, 1189 vfp_s1, 1190 vfp_s2, 1191 vfp_s3, 1192 vfp_s4, 1193 vfp_s5, 1194 vfp_s6, 1195 vfp_s7, 1196 vfp_s8, 1197 vfp_s9, 1198 vfp_s10, 1199 vfp_s11, 1200 vfp_s12, 1201 vfp_s13, 1202 vfp_s14, 1203 vfp_s15, 1204 vfp_s16, 1205 vfp_s17, 1206 vfp_s18, 1207 vfp_s19, 1208 vfp_s20, 1209 vfp_s21, 1210 vfp_s22, 1211 vfp_s23, 1212 vfp_s24, 1213 vfp_s25, 1214 vfp_s26, 1215 vfp_s27, 1216 vfp_s28, 1217 vfp_s29, 1218 vfp_s30, 1219 vfp_s31, 1220 vfp_d0, 1221 vfp_d1, 1222 vfp_d2, 1223 vfp_d3, 1224 vfp_d4, 1225 vfp_d5, 1226 vfp_d6, 1227 vfp_d7, 1228 vfp_d8, 1229 vfp_d9, 1230 vfp_d10, 1231 vfp_d11, 1232 vfp_d12, 1233 vfp_d13, 1234 vfp_d14, 1235 vfp_d15, 1236 vfp_d16, 1237 vfp_d17, 1238 vfp_d18, 1239 vfp_d19, 1240 vfp_d20, 1241 vfp_d21, 1242 vfp_d22, 1243 vfp_d23, 1244 vfp_d24, 1245 vfp_d25, 1246 vfp_d26, 1247 vfp_d27, 1248 vfp_d28, 1249 vfp_d29, 1250 vfp_d30, 1251 vfp_d31, 1252 vfp_q0, 1253 vfp_q1, 1254 vfp_q2, 1255 vfp_q3, 1256 vfp_q4, 1257 vfp_q5, 1258 vfp_q6, 1259 vfp_q7, 1260 vfp_q8, 1261 vfp_q9, 1262 vfp_q10, 1263 vfp_q11, 1264 vfp_q12, 1265 vfp_q13, 1266 vfp_q14, 1267 vfp_q15, 1268 vfp_fpscr 1269 }; 1270 1271 enum 1272 { 1273 exc_exception, 1274 exc_fsr, 1275 exc_far, 1276 }; 1277 1278 #define GPR_OFFSET_IDX(idx) (offsetof (DNBArchMachARM::GPR, __r[idx])) 1279 #define GPR_OFFSET_NAME(reg) (offsetof (DNBArchMachARM::GPR, __##reg)) 1280 1281 #define EXC_OFFSET(reg) (offsetof (DNBArchMachARM::EXC, __##reg) + offsetof (DNBArchMachARM::Context, exc)) 1282 1283 // These macros will auto define the register name, alt name, register size, 1284 // register offset, encoding, format and native register. This ensures that 1285 // the register state structures are defined correctly and have the correct 1286 // sizes and offsets. 1287 #define DEFINE_GPR_IDX(idx, reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 4, GPR_OFFSET_IDX(idx), gcc_##reg, dwarf_##reg, gen, INVALID_NUB_REGNUM, NULL, NULL} 1288 #define DEFINE_GPR_NAME(reg, alt, gen, inval) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 4, GPR_OFFSET_NAME(reg), gcc_##reg, dwarf_##reg, gen, INVALID_NUB_REGNUM, NULL, inval} 1289 1290 // In case we are debugging to a debug target that the ability to 1291 // change into the protected modes with folded registers (ABT, IRQ, 1292 // FIQ, SYS, USR, etc..), we should invalidate r8-r14 if the CPSR 1293 // gets modified. 1294 1295 const char * g_invalidate_cpsr[] = { "r8", "r9", "r10", "r11", "r12", "sp", "lr", NULL }; 1296 1297 // General purpose registers 1298 const DNBRegisterInfo 1299 DNBArchMachARM::g_gpr_registers[] = 1300 { 1301 DEFINE_GPR_IDX ( 0, r0,"arg1", GENERIC_REGNUM_ARG1 ), 1302 DEFINE_GPR_IDX ( 1, r1,"arg2", GENERIC_REGNUM_ARG2 ), 1303 DEFINE_GPR_IDX ( 2, r2,"arg3", GENERIC_REGNUM_ARG3 ), 1304 DEFINE_GPR_IDX ( 3, r3,"arg4", GENERIC_REGNUM_ARG4 ), 1305 DEFINE_GPR_IDX ( 4, r4, NULL, INVALID_NUB_REGNUM ), 1306 DEFINE_GPR_IDX ( 5, r5, NULL, INVALID_NUB_REGNUM ), 1307 DEFINE_GPR_IDX ( 6, r6, NULL, INVALID_NUB_REGNUM ), 1308 DEFINE_GPR_IDX ( 7, r7, "fp", GENERIC_REGNUM_FP ), 1309 DEFINE_GPR_IDX ( 8, r8, NULL, INVALID_NUB_REGNUM ), 1310 DEFINE_GPR_IDX ( 9, r9, NULL, INVALID_NUB_REGNUM ), 1311 DEFINE_GPR_IDX (10, r10, NULL, INVALID_NUB_REGNUM ), 1312 DEFINE_GPR_IDX (11, r11, NULL, INVALID_NUB_REGNUM ), 1313 DEFINE_GPR_IDX (12, r12, NULL, INVALID_NUB_REGNUM ), 1314 DEFINE_GPR_NAME (sp, "r13", GENERIC_REGNUM_SP, NULL), 1315 DEFINE_GPR_NAME (lr, "r14", GENERIC_REGNUM_RA, NULL), 1316 DEFINE_GPR_NAME (pc, "r15", GENERIC_REGNUM_PC, NULL), 1317 DEFINE_GPR_NAME (cpsr, "flags", GENERIC_REGNUM_FLAGS, g_invalidate_cpsr) 1318 }; 1319 1320 const char *g_contained_q0 [] { "q0", NULL }; 1321 const char *g_contained_q1 [] { "q1", NULL }; 1322 const char *g_contained_q2 [] { "q2", NULL }; 1323 const char *g_contained_q3 [] { "q3", NULL }; 1324 const char *g_contained_q4 [] { "q4", NULL }; 1325 const char *g_contained_q5 [] { "q5", NULL }; 1326 const char *g_contained_q6 [] { "q6", NULL }; 1327 const char *g_contained_q7 [] { "q7", NULL }; 1328 const char *g_contained_q8 [] { "q8", NULL }; 1329 const char *g_contained_q9 [] { "q9", NULL }; 1330 const char *g_contained_q10[] { "q10", NULL }; 1331 const char *g_contained_q11[] { "q11", NULL }; 1332 const char *g_contained_q12[] { "q12", NULL }; 1333 const char *g_contained_q13[] { "q13", NULL }; 1334 const char *g_contained_q14[] { "q14", NULL }; 1335 const char *g_contained_q15[] { "q15", NULL }; 1336 1337 const char *g_invalidate_q0[] { "q0", "d0" , "d1" , "s0" , "s1" , "s2" , "s3" , NULL }; 1338 const char *g_invalidate_q1[] { "q1", "d2" , "d3" , "s4" , "s5" , "s6" , "s7" , NULL }; 1339 const char *g_invalidate_q2[] { "q2", "d4" , "d5" , "s8" , "s9" , "s10", "s11", NULL }; 1340 const char *g_invalidate_q3[] { "q3", "d6" , "d7" , "s12", "s13", "s14", "s15", NULL }; 1341 const char *g_invalidate_q4[] { "q4", "d8" , "d9" , "s16", "s17", "s18", "s19", NULL }; 1342 const char *g_invalidate_q5[] { "q5", "d10", "d11", "s20", "s21", "s22", "s23", NULL }; 1343 const char *g_invalidate_q6[] { "q6", "d12", "d13", "s24", "s25", "s26", "s27", NULL }; 1344 const char *g_invalidate_q7[] { "q7", "d14", "d15", "s28", "s29", "s30", "s31", NULL }; 1345 const char *g_invalidate_q8[] { "q8", "d16", "d17", NULL }; 1346 const char *g_invalidate_q9[] { "q9", "d18", "d19", NULL }; 1347 const char *g_invalidate_q10[] { "q10", "d20", "d21", NULL }; 1348 const char *g_invalidate_q11[] { "q11", "d22", "d23", NULL }; 1349 const char *g_invalidate_q12[] { "q12", "d24", "d25", NULL }; 1350 const char *g_invalidate_q13[] { "q13", "d26", "d27", NULL }; 1351 const char *g_invalidate_q14[] { "q14", "d28", "d29", NULL }; 1352 const char *g_invalidate_q15[] { "q15", "d30", "d31", NULL }; 1353 1354 #define VFP_S_OFFSET_IDX(idx) (offsetof (DNBArchMachARM::FPU, __r[(idx)]) + offsetof (DNBArchMachARM::Context, vfp)) 1355 #define VFP_D_OFFSET_IDX(idx) (VFP_S_OFFSET_IDX ((idx) * 2)) 1356 #define VFP_Q_OFFSET_IDX(idx) (VFP_S_OFFSET_IDX ((idx) * 4)) 1357 1358 #define VFP_OFFSET_NAME(reg) (offsetof (DNBArchMachARM::FPU, __##reg) + offsetof (DNBArchMachARM::Context, vfp)) 1359 1360 #define FLOAT_FORMAT Float 1361 1362 #define DEFINE_VFP_S_IDX(idx) e_regSetVFP, vfp_s##idx, "s" #idx, NULL, IEEE754, FLOAT_FORMAT, 4, 0, INVALID_NUB_REGNUM, dwarf_s##idx, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM 1363 #define DEFINE_VFP_D_IDX(idx) e_regSetVFP, vfp_d##idx, "d" #idx, NULL, IEEE754, FLOAT_FORMAT, 8, 0, INVALID_NUB_REGNUM, dwarf_d##idx, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM 1364 #define DEFINE_VFP_Q_IDX(idx) e_regSetVFP, vfp_q##idx, "q" #idx, NULL, Vector, VectorOfUInt8, 16, VFP_Q_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_q##idx, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM 1365 1366 // Floating point registers 1367 const DNBRegisterInfo 1368 DNBArchMachARM::g_vfp_registers[] = 1369 { 1370 { DEFINE_VFP_S_IDX ( 0), g_contained_q0, g_invalidate_q0 }, 1371 { DEFINE_VFP_S_IDX ( 1), g_contained_q0, g_invalidate_q0 }, 1372 { DEFINE_VFP_S_IDX ( 2), g_contained_q0, g_invalidate_q0 }, 1373 { DEFINE_VFP_S_IDX ( 3), g_contained_q0, g_invalidate_q0 }, 1374 { DEFINE_VFP_S_IDX ( 4), g_contained_q1, g_invalidate_q1 }, 1375 { DEFINE_VFP_S_IDX ( 5), g_contained_q1, g_invalidate_q1 }, 1376 { DEFINE_VFP_S_IDX ( 6), g_contained_q1, g_invalidate_q1 }, 1377 { DEFINE_VFP_S_IDX ( 7), g_contained_q1, g_invalidate_q1 }, 1378 { DEFINE_VFP_S_IDX ( 8), g_contained_q2, g_invalidate_q2 }, 1379 { DEFINE_VFP_S_IDX ( 9), g_contained_q2, g_invalidate_q2 }, 1380 { DEFINE_VFP_S_IDX (10), g_contained_q2, g_invalidate_q2 }, 1381 { DEFINE_VFP_S_IDX (11), g_contained_q2, g_invalidate_q2 }, 1382 { DEFINE_VFP_S_IDX (12), g_contained_q3, g_invalidate_q3 }, 1383 { DEFINE_VFP_S_IDX (13), g_contained_q3, g_invalidate_q3 }, 1384 { DEFINE_VFP_S_IDX (14), g_contained_q3, g_invalidate_q3 }, 1385 { DEFINE_VFP_S_IDX (15), g_contained_q3, g_invalidate_q3 }, 1386 { DEFINE_VFP_S_IDX (16), g_contained_q4, g_invalidate_q4 }, 1387 { DEFINE_VFP_S_IDX (17), g_contained_q4, g_invalidate_q4 }, 1388 { DEFINE_VFP_S_IDX (18), g_contained_q4, g_invalidate_q4 }, 1389 { DEFINE_VFP_S_IDX (19), g_contained_q4, g_invalidate_q4 }, 1390 { DEFINE_VFP_S_IDX (20), g_contained_q5, g_invalidate_q5 }, 1391 { DEFINE_VFP_S_IDX (21), g_contained_q5, g_invalidate_q5 }, 1392 { DEFINE_VFP_S_IDX (22), g_contained_q5, g_invalidate_q5 }, 1393 { DEFINE_VFP_S_IDX (23), g_contained_q5, g_invalidate_q5 }, 1394 { DEFINE_VFP_S_IDX (24), g_contained_q6, g_invalidate_q6 }, 1395 { DEFINE_VFP_S_IDX (25), g_contained_q6, g_invalidate_q6 }, 1396 { DEFINE_VFP_S_IDX (26), g_contained_q6, g_invalidate_q6 }, 1397 { DEFINE_VFP_S_IDX (27), g_contained_q6, g_invalidate_q6 }, 1398 { DEFINE_VFP_S_IDX (28), g_contained_q7, g_invalidate_q7 }, 1399 { DEFINE_VFP_S_IDX (29), g_contained_q7, g_invalidate_q7 }, 1400 { DEFINE_VFP_S_IDX (30), g_contained_q7, g_invalidate_q7 }, 1401 { DEFINE_VFP_S_IDX (31), g_contained_q7, g_invalidate_q7 }, 1402 1403 { DEFINE_VFP_D_IDX (0), g_contained_q0, g_invalidate_q0 }, 1404 { DEFINE_VFP_D_IDX (1), g_contained_q0, g_invalidate_q0 }, 1405 { DEFINE_VFP_D_IDX (2), g_contained_q1, g_invalidate_q1 }, 1406 { DEFINE_VFP_D_IDX (3), g_contained_q1, g_invalidate_q1 }, 1407 { DEFINE_VFP_D_IDX (4), g_contained_q2, g_invalidate_q2 }, 1408 { DEFINE_VFP_D_IDX (5), g_contained_q2, g_invalidate_q2 }, 1409 { DEFINE_VFP_D_IDX (6), g_contained_q3, g_invalidate_q3 }, 1410 { DEFINE_VFP_D_IDX (7), g_contained_q3, g_invalidate_q3 }, 1411 { DEFINE_VFP_D_IDX (8), g_contained_q4, g_invalidate_q4 }, 1412 { DEFINE_VFP_D_IDX (9), g_contained_q4, g_invalidate_q4 }, 1413 { DEFINE_VFP_D_IDX (10), g_contained_q5, g_invalidate_q5 }, 1414 { DEFINE_VFP_D_IDX (11), g_contained_q5, g_invalidate_q5 }, 1415 { DEFINE_VFP_D_IDX (12), g_contained_q6, g_invalidate_q6 }, 1416 { DEFINE_VFP_D_IDX (13), g_contained_q6, g_invalidate_q6 }, 1417 { DEFINE_VFP_D_IDX (14), g_contained_q7, g_invalidate_q7 }, 1418 { DEFINE_VFP_D_IDX (15), g_contained_q7, g_invalidate_q7 }, 1419 { DEFINE_VFP_D_IDX (16), g_contained_q8, g_invalidate_q8 }, 1420 { DEFINE_VFP_D_IDX (17), g_contained_q8, g_invalidate_q8 }, 1421 { DEFINE_VFP_D_IDX (18), g_contained_q9, g_invalidate_q9 }, 1422 { DEFINE_VFP_D_IDX (19), g_contained_q9, g_invalidate_q9 }, 1423 { DEFINE_VFP_D_IDX (20), g_contained_q10, g_invalidate_q10 }, 1424 { DEFINE_VFP_D_IDX (21), g_contained_q10, g_invalidate_q10 }, 1425 { DEFINE_VFP_D_IDX (22), g_contained_q11, g_invalidate_q11 }, 1426 { DEFINE_VFP_D_IDX (23), g_contained_q11, g_invalidate_q11 }, 1427 { DEFINE_VFP_D_IDX (24), g_contained_q12, g_invalidate_q12 }, 1428 { DEFINE_VFP_D_IDX (25), g_contained_q12, g_invalidate_q12 }, 1429 { DEFINE_VFP_D_IDX (26), g_contained_q13, g_invalidate_q13 }, 1430 { DEFINE_VFP_D_IDX (27), g_contained_q13, g_invalidate_q13 }, 1431 { DEFINE_VFP_D_IDX (28), g_contained_q14, g_invalidate_q14 }, 1432 { DEFINE_VFP_D_IDX (29), g_contained_q14, g_invalidate_q14 }, 1433 { DEFINE_VFP_D_IDX (30), g_contained_q15, g_invalidate_q15 }, 1434 { DEFINE_VFP_D_IDX (31), g_contained_q15, g_invalidate_q15 }, 1435 1436 { DEFINE_VFP_Q_IDX (0), NULL, g_invalidate_q0 }, 1437 { DEFINE_VFP_Q_IDX (1), NULL, g_invalidate_q1 }, 1438 { DEFINE_VFP_Q_IDX (2), NULL, g_invalidate_q2 }, 1439 { DEFINE_VFP_Q_IDX (3), NULL, g_invalidate_q3 }, 1440 { DEFINE_VFP_Q_IDX (4), NULL, g_invalidate_q4 }, 1441 { DEFINE_VFP_Q_IDX (5), NULL, g_invalidate_q5 }, 1442 { DEFINE_VFP_Q_IDX (6), NULL, g_invalidate_q6 }, 1443 { DEFINE_VFP_Q_IDX (7), NULL, g_invalidate_q7 }, 1444 { DEFINE_VFP_Q_IDX (8), NULL, g_invalidate_q8 }, 1445 { DEFINE_VFP_Q_IDX (9), NULL, g_invalidate_q9 }, 1446 { DEFINE_VFP_Q_IDX (10), NULL, g_invalidate_q10 }, 1447 { DEFINE_VFP_Q_IDX (11), NULL, g_invalidate_q11 }, 1448 { DEFINE_VFP_Q_IDX (12), NULL, g_invalidate_q12 }, 1449 { DEFINE_VFP_Q_IDX (13), NULL, g_invalidate_q13 }, 1450 { DEFINE_VFP_Q_IDX (14), NULL, g_invalidate_q14 }, 1451 { DEFINE_VFP_Q_IDX (15), NULL, g_invalidate_q15 }, 1452 1453 { e_regSetVFP, vfp_fpscr, "fpscr", NULL, Uint, Hex, 4, VFP_OFFSET_NAME(fpscr), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL } 1454 }; 1455 1456 // Exception registers 1457 1458 const DNBRegisterInfo 1459 DNBArchMachARM::g_exc_registers[] = 1460 { 1461 { e_regSetVFP, exc_exception , "exception" , NULL, Uint, Hex, 4, EXC_OFFSET(exception) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM }, 1462 { e_regSetVFP, exc_fsr , "fsr" , NULL, Uint, Hex, 4, EXC_OFFSET(fsr) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM }, 1463 { e_regSetVFP, exc_far , "far" , NULL, Uint, Hex, 4, EXC_OFFSET(far) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM } 1464 }; 1465 1466 // Number of registers in each register set 1467 const size_t DNBArchMachARM::k_num_gpr_registers = sizeof(g_gpr_registers)/sizeof(DNBRegisterInfo); 1468 const size_t DNBArchMachARM::k_num_vfp_registers = sizeof(g_vfp_registers)/sizeof(DNBRegisterInfo); 1469 const size_t DNBArchMachARM::k_num_exc_registers = sizeof(g_exc_registers)/sizeof(DNBRegisterInfo); 1470 const size_t DNBArchMachARM::k_num_all_registers = k_num_gpr_registers + k_num_vfp_registers + k_num_exc_registers; 1471 1472 //---------------------------------------------------------------------- 1473 // Register set definitions. The first definitions at register set index 1474 // of zero is for all registers, followed by other registers sets. The 1475 // register information for the all register set need not be filled in. 1476 //---------------------------------------------------------------------- 1477 const DNBRegisterSetInfo 1478 DNBArchMachARM::g_reg_sets[] = 1479 { 1480 { "ARM Registers", NULL, k_num_all_registers }, 1481 { "General Purpose Registers", g_gpr_registers, k_num_gpr_registers }, 1482 { "Floating Point Registers", g_vfp_registers, k_num_vfp_registers }, 1483 { "Exception State Registers", g_exc_registers, k_num_exc_registers } 1484 }; 1485 // Total number of register sets for this architecture 1486 const size_t DNBArchMachARM::k_num_register_sets = sizeof(g_reg_sets)/sizeof(DNBRegisterSetInfo); 1487 1488 1489 const DNBRegisterSetInfo * 1490 DNBArchMachARM::GetRegisterSetInfo(nub_size_t *num_reg_sets) 1491 { 1492 *num_reg_sets = k_num_register_sets; 1493 return g_reg_sets; 1494 } 1495 1496 bool 1497 DNBArchMachARM::GetRegisterValue(int set, int reg, DNBRegisterValue *value) 1498 { 1499 if (set == REGISTER_SET_GENERIC) 1500 { 1501 switch (reg) 1502 { 1503 case GENERIC_REGNUM_PC: // Program Counter 1504 set = e_regSetGPR; 1505 reg = gpr_pc; 1506 break; 1507 1508 case GENERIC_REGNUM_SP: // Stack Pointer 1509 set = e_regSetGPR; 1510 reg = gpr_sp; 1511 break; 1512 1513 case GENERIC_REGNUM_FP: // Frame Pointer 1514 set = e_regSetGPR; 1515 reg = gpr_r7; // is this the right reg? 1516 break; 1517 1518 case GENERIC_REGNUM_RA: // Return Address 1519 set = e_regSetGPR; 1520 reg = gpr_lr; 1521 break; 1522 1523 case GENERIC_REGNUM_FLAGS: // Processor flags register 1524 set = e_regSetGPR; 1525 reg = gpr_cpsr; 1526 break; 1527 1528 default: 1529 return false; 1530 } 1531 } 1532 1533 if (GetRegisterState(set, false) != KERN_SUCCESS) 1534 return false; 1535 1536 const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg); 1537 if (regInfo) 1538 { 1539 value->info = *regInfo; 1540 switch (set) 1541 { 1542 case e_regSetGPR: 1543 if (reg < k_num_gpr_registers) 1544 { 1545 value->value.uint32 = m_state.context.gpr.__r[reg]; 1546 return true; 1547 } 1548 break; 1549 1550 case e_regSetVFP: 1551 // "reg" is an index into the floating point register set at this point. 1552 // We need to translate it up so entry 0 in the fp reg set is the same as vfp_s0 1553 // in the enumerated values for case statement below. 1554 if (reg >= vfp_s0 && reg <= vfp_s31) 1555 { 1556 value->value.uint32 = m_state.context.vfp.__r[reg]; 1557 return true; 1558 } 1559 else if (reg >= vfp_d0 && reg <= vfp_d31) 1560 { 1561 uint32_t d_reg_idx = reg - vfp_d0; 1562 uint32_t s_reg_idx = d_reg_idx * 2; 1563 value->value.v_sint32[0] = m_state.context.vfp.__r[s_reg_idx + 0]; 1564 value->value.v_sint32[1] = m_state.context.vfp.__r[s_reg_idx + 1]; 1565 return true; 1566 } 1567 else if (reg >= vfp_q0 && reg <= vfp_q15) 1568 { 1569 uint32_t s_reg_idx = (reg - vfp_q0) * 4; 1570 memcpy (&value->value.v_uint8, (uint8_t *) &m_state.context.vfp.__r[s_reg_idx], 16); 1571 return true; 1572 } 1573 else if (reg == vfp_fpscr) 1574 { 1575 value->value.uint32 = m_state.context.vfp.__fpscr; 1576 return true; 1577 } 1578 break; 1579 1580 case e_regSetEXC: 1581 if (reg < k_num_exc_registers) 1582 { 1583 value->value.uint32 = (&m_state.context.exc.__exception)[reg]; 1584 return true; 1585 } 1586 break; 1587 } 1588 } 1589 return false; 1590 } 1591 1592 bool 1593 DNBArchMachARM::SetRegisterValue(int set, int reg, const DNBRegisterValue *value) 1594 { 1595 if (set == REGISTER_SET_GENERIC) 1596 { 1597 switch (reg) 1598 { 1599 case GENERIC_REGNUM_PC: // Program Counter 1600 set = e_regSetGPR; 1601 reg = gpr_pc; 1602 break; 1603 1604 case GENERIC_REGNUM_SP: // Stack Pointer 1605 set = e_regSetGPR; 1606 reg = gpr_sp; 1607 break; 1608 1609 case GENERIC_REGNUM_FP: // Frame Pointer 1610 set = e_regSetGPR; 1611 reg = gpr_r7; 1612 break; 1613 1614 case GENERIC_REGNUM_RA: // Return Address 1615 set = e_regSetGPR; 1616 reg = gpr_lr; 1617 break; 1618 1619 case GENERIC_REGNUM_FLAGS: // Processor flags register 1620 set = e_regSetGPR; 1621 reg = gpr_cpsr; 1622 break; 1623 1624 default: 1625 return false; 1626 } 1627 } 1628 1629 if (GetRegisterState(set, false) != KERN_SUCCESS) 1630 return false; 1631 1632 bool success = false; 1633 const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg); 1634 if (regInfo) 1635 { 1636 switch (set) 1637 { 1638 case e_regSetGPR: 1639 if (reg < k_num_gpr_registers) 1640 { 1641 m_state.context.gpr.__r[reg] = value->value.uint32; 1642 success = true; 1643 } 1644 break; 1645 1646 case e_regSetVFP: 1647 // "reg" is an index into the floating point register set at this point. 1648 // We need to translate it up so entry 0 in the fp reg set is the same as vfp_s0 1649 // in the enumerated values for case statement below. 1650 if (reg >= vfp_s0 && reg <= vfp_s31) 1651 { 1652 m_state.context.vfp.__r[reg] = value->value.uint32; 1653 success = true; 1654 } 1655 else if (reg >= vfp_d0 && reg <= vfp_d31) 1656 { 1657 uint32_t d_reg_idx = reg - vfp_d0; 1658 uint32_t s_reg_idx = d_reg_idx * 2; 1659 m_state.context.vfp.__r[s_reg_idx + 0] = value->value.v_sint32[0]; 1660 m_state.context.vfp.__r[s_reg_idx + 1] = value->value.v_sint32[1]; 1661 success = true; 1662 } 1663 else if (reg >= vfp_q0 && reg <= vfp_q15) 1664 { 1665 uint32_t s_reg_idx = (reg - vfp_q0) * 4; 1666 memcpy ((uint8_t *) &m_state.context.vfp.__r[s_reg_idx], &value->value.v_uint8, 16); 1667 return true; 1668 } 1669 else if (reg == vfp_fpscr) 1670 { 1671 m_state.context.vfp.__fpscr = value->value.uint32; 1672 success = true; 1673 } 1674 break; 1675 1676 case e_regSetEXC: 1677 if (reg < k_num_exc_registers) 1678 { 1679 (&m_state.context.exc.__exception)[reg] = value->value.uint32; 1680 success = true; 1681 } 1682 break; 1683 } 1684 1685 } 1686 if (success) 1687 return SetRegisterState(set) == KERN_SUCCESS; 1688 return false; 1689 } 1690 1691 kern_return_t 1692 DNBArchMachARM::GetRegisterState(int set, bool force) 1693 { 1694 switch (set) 1695 { 1696 case e_regSetALL: return GetGPRState(force) | 1697 GetVFPState(force) | 1698 GetEXCState(force) | 1699 GetDBGState(force); 1700 case e_regSetGPR: return GetGPRState(force); 1701 case e_regSetVFP: return GetVFPState(force); 1702 case e_regSetEXC: return GetEXCState(force); 1703 case e_regSetDBG: return GetDBGState(force); 1704 default: break; 1705 } 1706 return KERN_INVALID_ARGUMENT; 1707 } 1708 1709 kern_return_t 1710 DNBArchMachARM::SetRegisterState(int set) 1711 { 1712 // Make sure we have a valid context to set. 1713 kern_return_t err = GetRegisterState(set, false); 1714 if (err != KERN_SUCCESS) 1715 return err; 1716 1717 switch (set) 1718 { 1719 case e_regSetALL: return SetGPRState() | 1720 SetVFPState() | 1721 SetEXCState() | 1722 SetDBGState(false); 1723 case e_regSetGPR: return SetGPRState(); 1724 case e_regSetVFP: return SetVFPState(); 1725 case e_regSetEXC: return SetEXCState(); 1726 case e_regSetDBG: return SetDBGState(false); 1727 default: break; 1728 } 1729 return KERN_INVALID_ARGUMENT; 1730 } 1731 1732 bool 1733 DNBArchMachARM::RegisterSetStateIsValid (int set) const 1734 { 1735 return m_state.RegsAreValid(set); 1736 } 1737 1738 1739 nub_size_t 1740 DNBArchMachARM::GetRegisterContext (void *buf, nub_size_t buf_len) 1741 { 1742 nub_size_t size = sizeof (m_state.context.gpr) + 1743 sizeof (m_state.context.vfp) + 1744 sizeof (m_state.context.exc); 1745 1746 if (buf && buf_len) 1747 { 1748 if (size > buf_len) 1749 size = buf_len; 1750 1751 bool force = false; 1752 if (GetGPRState(force) | GetVFPState(force) | GetEXCState(force)) 1753 return 0; 1754 1755 // Copy each struct individually to avoid any padding that might be between the structs in m_state.context 1756 uint8_t *p = (uint8_t *)buf; 1757 ::memcpy (p, &m_state.context.gpr, sizeof(m_state.context.gpr)); 1758 p += sizeof(m_state.context.gpr); 1759 ::memcpy (p, &m_state.context.vfp, sizeof(m_state.context.vfp)); 1760 p += sizeof(m_state.context.vfp); 1761 ::memcpy (p, &m_state.context.exc, sizeof(m_state.context.exc)); 1762 p += sizeof(m_state.context.exc); 1763 1764 size_t bytes_written = p - (uint8_t *)buf; 1765 assert (bytes_written == size); 1766 1767 } 1768 DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM::GetRegisterContext (buf = %p, len = %llu) => %llu", buf, (uint64_t)buf_len, (uint64_t)size); 1769 // Return the size of the register context even if NULL was passed in 1770 return size; 1771 } 1772 1773 nub_size_t 1774 DNBArchMachARM::SetRegisterContext (const void *buf, nub_size_t buf_len) 1775 { 1776 nub_size_t size = sizeof (m_state.context.gpr) + 1777 sizeof (m_state.context.vfp) + 1778 sizeof (m_state.context.exc); 1779 1780 if (buf == NULL || buf_len == 0) 1781 size = 0; 1782 1783 if (size) 1784 { 1785 if (size > buf_len) 1786 size = buf_len; 1787 1788 // Copy each struct individually to avoid any padding that might be between the structs in m_state.context 1789 uint8_t *p = (uint8_t *)buf; 1790 ::memcpy (&m_state.context.gpr, p, sizeof(m_state.context.gpr)); 1791 p += sizeof(m_state.context.gpr); 1792 ::memcpy (&m_state.context.vfp, p, sizeof(m_state.context.vfp)); 1793 p += sizeof(m_state.context.vfp); 1794 ::memcpy (&m_state.context.exc, p, sizeof(m_state.context.exc)); 1795 p += sizeof(m_state.context.exc); 1796 1797 size_t bytes_written = p - (uint8_t *)buf; 1798 assert (bytes_written == size); 1799 1800 if (SetGPRState() | SetVFPState() | SetEXCState()) 1801 return 0; 1802 } 1803 DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM::SetRegisterContext (buf = %p, len = %llu) => %llu", buf, (uint64_t)buf_len, (uint64_t)size); 1804 return size; 1805 } 1806 1807 1808 uint32_t 1809 DNBArchMachARM::SaveRegisterState () 1810 { 1811 kern_return_t kret = ::thread_abort_safely(m_thread->MachPortNumber()); 1812 DNBLogThreadedIf (LOG_THREAD, "thread = 0x%4.4x calling thread_abort_safely (tid) => %u (SetGPRState() for stop_count = %u)", m_thread->MachPortNumber(), kret, m_thread->Process()->StopCount()); 1813 1814 // Always re-read the registers because above we call thread_abort_safely(); 1815 bool force = true; 1816 1817 if ((kret = GetGPRState(force)) != KERN_SUCCESS) 1818 { 1819 DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM::SaveRegisterState () error: GPR regs failed to read: %u ", kret); 1820 } 1821 else if ((kret = GetVFPState(force)) != KERN_SUCCESS) 1822 { 1823 DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM::SaveRegisterState () error: %s regs failed to read: %u", "VFP", kret); 1824 } 1825 else 1826 { 1827 const uint32_t save_id = GetNextRegisterStateSaveID (); 1828 m_saved_register_states[save_id] = m_state.context; 1829 return save_id; 1830 } 1831 return UINT32_MAX; 1832 } 1833 1834 bool 1835 DNBArchMachARM::RestoreRegisterState (uint32_t save_id) 1836 { 1837 SaveRegisterStates::iterator pos = m_saved_register_states.find(save_id); 1838 if (pos != m_saved_register_states.end()) 1839 { 1840 m_state.context.gpr = pos->second.gpr; 1841 m_state.context.vfp = pos->second.vfp; 1842 kern_return_t kret; 1843 bool success = true; 1844 if ((kret = SetGPRState()) != KERN_SUCCESS) 1845 { 1846 DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM::RestoreRegisterState (save_id = %u) error: GPR regs failed to write: %u", save_id, kret); 1847 success = false; 1848 } 1849 else if ((kret = SetVFPState()) != KERN_SUCCESS) 1850 { 1851 DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM::RestoreRegisterState (save_id = %u) error: %s regs failed to write: %u", save_id, "VFP", kret); 1852 success = false; 1853 } 1854 m_saved_register_states.erase(pos); 1855 return success; 1856 } 1857 return false; 1858 } 1859 1860 1861 #endif // #if defined (__arm__) 1862 1863