DNBArchImpl.cpp revision 9a725f0e1d0589254d5e96fa3516d56a30799950
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//#define DNB_ARCH_MACH_ARM_DEBUG_SW_STEP 1 66 67static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 }; 68static const uint8_t g_thumb_breakpooint_opcode[] = { 0xFE, 0xDE }; 69 70// ARM constants used during decoding 71#define REG_RD 0 72#define LDM_REGLIST 1 73#define PC_REG 15 74#define PC_REGLIST_BIT 0x8000 75 76// ARM conditions 77#define COND_EQ 0x0 78#define COND_NE 0x1 79#define COND_CS 0x2 80#define COND_HS 0x2 81#define COND_CC 0x3 82#define COND_LO 0x3 83#define COND_MI 0x4 84#define COND_PL 0x5 85#define COND_VS 0x6 86#define COND_VC 0x7 87#define COND_HI 0x8 88#define COND_LS 0x9 89#define COND_GE 0xA 90#define COND_LT 0xB 91#define COND_GT 0xC 92#define COND_LE 0xD 93#define COND_AL 0xE 94#define COND_UNCOND 0xF 95 96#define MASK_CPSR_T (1u << 5) 97#define MASK_CPSR_J (1u << 24) 98 99#define MNEMONIC_STRING_SIZE 32 100#define OPERAND_STRING_SIZE 128 101 102 103void 104DNBArchMachARM::Initialize() 105{ 106 DNBArchPluginInfo arch_plugin_info = 107 { 108 CPU_TYPE_ARM, 109 DNBArchMachARM::Create, 110 DNBArchMachARM::GetRegisterSetInfo, 111 DNBArchMachARM::SoftwareBreakpointOpcode 112 }; 113 114 // Register this arch plug-in with the main protocol class 115 DNBArchProtocol::RegisterArchPlugin (arch_plugin_info); 116} 117 118 119DNBArchProtocol * 120DNBArchMachARM::Create (MachThread *thread) 121{ 122 DNBArchMachARM *obj = new DNBArchMachARM (thread); 123 124 // When new thread comes along, it tries to inherit from the global debug state, if it is valid. 125 if (Valid_Global_Debug_State) 126 { 127 obj->m_state.dbg = Global_Debug_State; 128 kern_return_t kret = obj->SetDBGState(); 129 DNBLogThreadedIf(LOG_WATCHPOINTS, 130 "DNBArchMachARM::Create() Inherit and SetDBGState() => 0x%8.8x.", kret); 131 } 132 return obj; 133} 134 135const uint8_t * const 136DNBArchMachARM::SoftwareBreakpointOpcode (nub_size_t byte_size) 137{ 138 switch (byte_size) 139 { 140 case 2: return g_thumb_breakpooint_opcode; 141 case 4: return g_arm_breakpoint_opcode; 142 } 143 return NULL; 144} 145 146uint32_t 147DNBArchMachARM::GetCPUType() 148{ 149 return CPU_TYPE_ARM; 150} 151 152uint64_t 153DNBArchMachARM::GetPC(uint64_t failValue) 154{ 155 // Get program counter 156 if (GetGPRState(false) == KERN_SUCCESS) 157 return m_state.context.gpr.__pc; 158 return failValue; 159} 160 161kern_return_t 162DNBArchMachARM::SetPC(uint64_t value) 163{ 164 // Get program counter 165 kern_return_t err = GetGPRState(false); 166 if (err == KERN_SUCCESS) 167 { 168 m_state.context.gpr.__pc = value; 169 err = SetGPRState(); 170 } 171 return err == KERN_SUCCESS; 172} 173 174uint64_t 175DNBArchMachARM::GetSP(uint64_t failValue) 176{ 177 // Get stack pointer 178 if (GetGPRState(false) == KERN_SUCCESS) 179 return m_state.context.gpr.__sp; 180 return failValue; 181} 182 183kern_return_t 184DNBArchMachARM::GetGPRState(bool force) 185{ 186 int set = e_regSetGPR; 187 // Check if we have valid cached registers 188 if (!force && m_state.GetError(set, Read) == KERN_SUCCESS) 189 return KERN_SUCCESS; 190 191 // Read the registers from our thread 192 mach_msg_type_number_t count = ARM_THREAD_STATE_COUNT; 193 kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_THREAD_STATE, (thread_state_t)&m_state.context.gpr, &count); 194 uint32_t *r = &m_state.context.gpr.__r[0]; 195 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", 196 m_thread->ThreadID(), 197 ARM_THREAD_STATE, 198 ARM_THREAD_STATE_COUNT, 199 kret, 200 count, 201 r[0], 202 r[1], 203 r[2], 204 r[3], 205 r[4], 206 r[5], 207 r[6], 208 r[7], 209 r[8], 210 r[9], 211 r[10], 212 r[11], 213 r[12], 214 r[13], 215 r[14], 216 r[15], 217 r[16]); 218 m_state.SetError(set, Read, kret); 219 return kret; 220} 221 222kern_return_t 223DNBArchMachARM::GetVFPState(bool force) 224{ 225 int set = e_regSetVFP; 226 // Check if we have valid cached registers 227 if (!force && m_state.GetError(set, Read) == KERN_SUCCESS) 228 return KERN_SUCCESS; 229 230 // Read the registers from our thread 231 mach_msg_type_number_t count = ARM_VFP_STATE_COUNT; 232 kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, &count); 233 if (DNBLogEnabledForAny (LOG_THREAD)) 234 { 235 uint32_t *r = &m_state.context.vfp.__r[0]; 236 DNBLogThreaded ("thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x (count => %u)", 237 m_thread->ThreadID(), 238 ARM_THREAD_STATE, 239 ARM_THREAD_STATE_COUNT, 240 kret, 241 count); 242 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]); 243 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]); 244 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]); 245 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]); 246 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]); 247 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]); 248 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]); 249 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]); 250 } 251 m_state.SetError(set, Read, kret); 252 return kret; 253} 254 255kern_return_t 256DNBArchMachARM::GetEXCState(bool force) 257{ 258 int set = e_regSetEXC; 259 // Check if we have valid cached registers 260 if (!force && m_state.GetError(set, Read) == KERN_SUCCESS) 261 return KERN_SUCCESS; 262 263 // Read the registers from our thread 264 mach_msg_type_number_t count = ARM_EXCEPTION_STATE_COUNT; 265 kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, &count); 266 m_state.SetError(set, Read, kret); 267 return kret; 268} 269 270static void 271DumpDBGState(const DNBArchMachARM::DBG& dbg) 272{ 273 uint32_t i = 0; 274 for (i=0; i<16; i++) { 275 DNBLogThreadedIf(LOG_STEP, "BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { 0x%8.8x, 0x%8.8x }", 276 i, i, dbg.__bvr[i], dbg.__bcr[i], 277 i, i, dbg.__wvr[i], dbg.__wcr[i]); 278 } 279} 280 281kern_return_t 282DNBArchMachARM::GetDBGState(bool force) 283{ 284 int set = e_regSetDBG; 285 286 // Check if we have valid cached registers 287 if (!force && m_state.GetError(set, Read) == KERN_SUCCESS) 288 return KERN_SUCCESS; 289 290 // Read the registers from our thread 291 mach_msg_type_number_t count = ARM_DEBUG_STATE_COUNT; 292 kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, &count); 293 m_state.SetError(set, Read, kret); 294 return kret; 295} 296 297kern_return_t 298DNBArchMachARM::SetGPRState() 299{ 300 int set = e_regSetGPR; 301 kern_return_t kret = ::thread_set_state(m_thread->ThreadID(), ARM_THREAD_STATE, (thread_state_t)&m_state.context.gpr, ARM_THREAD_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 307kern_return_t 308DNBArchMachARM::SetVFPState() 309{ 310 int set = e_regSetVFP; 311 kern_return_t kret = ::thread_set_state (m_thread->ThreadID(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, ARM_VFP_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 317kern_return_t 318DNBArchMachARM::SetEXCState() 319{ 320 int set = e_regSetEXC; 321 kern_return_t kret = ::thread_set_state (m_thread->ThreadID(), ARM_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, ARM_EXCEPTION_STATE_COUNT); 322 m_state.SetError(set, Write, kret); // Set the current write error for this register set 323 m_state.InvalidateRegisterSetState(set); // Invalidate the current register state in case registers are read back differently 324 return kret; // Return the error code 325} 326 327kern_return_t 328DNBArchMachARM::SetDBGState() 329{ 330 int set = e_regSetDBG; 331 kern_return_t kret = ::thread_set_state (m_thread->ThreadID(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, ARM_DEBUG_STATE_COUNT); 332 m_state.SetError(set, Write, kret); // Set the current write error for this register set 333 m_state.InvalidateRegisterSetState(set); // Invalidate the current register state in case registers are read back differently 334 return kret; // Return the error code 335} 336 337void 338DNBArchMachARM::ThreadWillResume() 339{ 340 // Do we need to step this thread? If so, let the mach thread tell us so. 341 if (m_thread->IsStepping()) 342 { 343 bool step_handled = false; 344 // This is the primary thread, let the arch do anything it needs 345 if (NumSupportedHardwareBreakpoints() > 0) 346 { 347#if defined (DNB_ARCH_MACH_ARM_DEBUG_SW_STEP) 348 bool half_step = m_hw_single_chained_step_addr != INVALID_NUB_ADDRESS; 349#endif 350 step_handled = EnableHardwareSingleStep(true) == KERN_SUCCESS; 351#if defined (DNB_ARCH_MACH_ARM_DEBUG_SW_STEP) 352 if (!half_step) 353 step_handled = false; 354#endif 355 } 356 357 if (!step_handled) 358 { 359 SetSingleStepSoftwareBreakpoints(); 360 } 361 } 362 363 // Disable the triggered watchpoint temporarily before we resume. 364 // Plus, we try to enable hardware single step to execute past the instruction which triggered our watchpoint. 365 if (m_watchpoint_did_occur) 366 { 367 if (m_watchpoint_hw_index >= 0) 368 { 369 kern_return_t kret = GetDBGState(false); 370 if (kret == KERN_SUCCESS && !IsWatchpointEnabled(m_state.dbg, m_watchpoint_hw_index)) { 371 // The watchpoint might have been disabled by the user. We don't need to do anything at all 372 // to enable hardware single stepping. 373 m_watchpoint_did_occur = false; 374 m_watchpoint_hw_index = -1; 375 return; 376 } 377 378 DisableHardwareWatchpoint0(m_watchpoint_hw_index, true); 379 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::ThreadWillResume() DisableHardwareWatchpoint(%d) called", 380 m_watchpoint_hw_index); 381 382 // Enable hardware single step to move past the watchpoint-triggering instruction. 383 m_watchpoint_resume_single_step_enabled = (EnableHardwareSingleStep(true) == KERN_SUCCESS); 384 385 // If we are not able to enable single step to move past the watchpoint-triggering instruction, 386 // at least we should reset the two watchpoint member variables so that the next time around 387 // this callback function is invoked, the enclosing logical branch is skipped. 388 if (!m_watchpoint_resume_single_step_enabled) { 389 // Reset the two watchpoint member variables. 390 m_watchpoint_did_occur = false; 391 m_watchpoint_hw_index = -1; 392 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::ThreadWillResume() failed to enable single step"); 393 } 394 else 395 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::ThreadWillResume() succeeded to enable single step"); 396 } 397 } 398} 399 400bool 401DNBArchMachARM::ThreadDidStop() 402{ 403 bool success = true; 404 405 m_state.InvalidateRegisterSetState (e_regSetALL); 406 407 if (m_watchpoint_resume_single_step_enabled) 408 { 409 // Great! We now disable the hardware single step as well as re-enable the hardware watchpoint. 410 // See also ThreadWillResume(). 411 if (EnableHardwareSingleStep(false) == KERN_SUCCESS) 412 { 413 if (m_watchpoint_did_occur && m_watchpoint_hw_index >= 0) 414 { 415 EnableHardwareWatchpoint0(m_watchpoint_hw_index, true); 416 m_watchpoint_resume_single_step_enabled = false; 417 m_watchpoint_did_occur = false; 418 m_watchpoint_hw_index = -1; 419 } 420 else 421 { 422 DNBLogError("internal error detected: m_watchpoint_resume_step_enabled is true but (m_watchpoint_did_occur && m_watchpoint_hw_index >= 0) does not hold!"); 423 } 424 } 425 else 426 { 427 DNBLogError("internal error detected: m_watchpoint_resume_step_enabled is true but unable to disable single step!"); 428 } 429 } 430 431 // Are we stepping a single instruction? 432 if (GetGPRState(true) == KERN_SUCCESS) 433 { 434 // We are single stepping, was this the primary thread? 435 if (m_thread->IsStepping()) 436 { 437#if defined (DNB_ARCH_MACH_ARM_DEBUG_SW_STEP) 438 success = EnableHardwareSingleStep(false) == KERN_SUCCESS; 439 // Hardware single step must work if we are going to test software 440 // single step functionality 441 assert(success); 442 if (m_hw_single_chained_step_addr == INVALID_NUB_ADDRESS && m_sw_single_step_next_pc != INVALID_NUB_ADDRESS) 443 { 444 uint32_t sw_step_next_pc = m_sw_single_step_next_pc & 0xFFFFFFFEu; 445 bool sw_step_next_pc_is_thumb = (m_sw_single_step_next_pc & 1) != 0; 446 bool actual_next_pc_is_thumb = (m_state.context.gpr.__cpsr & 0x20) != 0; 447 if (m_state.context.gpr.__pc != sw_step_next_pc) 448 { 449 DNBLogError("curr pc = 0x%8.8x - calculated single step target PC was incorrect: 0x%8.8x != 0x%8.8x", m_state.context.gpr.__pc, sw_step_next_pc, m_state.context.gpr.__pc); 450 exit(1); 451 } 452 if (actual_next_pc_is_thumb != sw_step_next_pc_is_thumb) 453 { 454 DNBLogError("curr pc = 0x%8.8x - calculated single step calculated mode mismatch: sw single mode = %s != %s", 455 m_state.context.gpr.__pc, 456 actual_next_pc_is_thumb ? "Thumb" : "ARM", 457 sw_step_next_pc_is_thumb ? "Thumb" : "ARM"); 458 exit(1); 459 } 460 m_sw_single_step_next_pc = INVALID_NUB_ADDRESS; 461 } 462#else 463 // Are we software single stepping? 464 if (NUB_BREAK_ID_IS_VALID(m_sw_single_step_break_id) || m_sw_single_step_itblock_break_count) 465 { 466 // Remove any software single stepping breakpoints that we have set 467 468 // Do we have a normal software single step breakpoint? 469 if (NUB_BREAK_ID_IS_VALID(m_sw_single_step_break_id)) 470 { 471 DNBLogThreadedIf(LOG_STEP, "%s: removing software single step breakpoint (breakID=%d)", __FUNCTION__, m_sw_single_step_break_id); 472 success = m_thread->Process()->DisableBreakpoint(m_sw_single_step_break_id, true); 473 m_sw_single_step_break_id = INVALID_NUB_BREAK_ID; 474 } 475 476 // Do we have any Thumb IT breakpoints? 477 if (m_sw_single_step_itblock_break_count > 0) 478 { 479 // See if we hit one of our Thumb IT breakpoints? 480 DNBBreakpoint *step_bp = m_thread->Process()->Breakpoints().FindByAddress(m_state.context.gpr.__pc); 481 482 if (step_bp) 483 { 484 // We did hit our breakpoint, tell the breakpoint it was 485 // hit so that it can run its callback routine and fixup 486 // the PC. 487 DNBLogThreadedIf(LOG_STEP, "%s: IT software single step breakpoint hit (breakID=%u)", __FUNCTION__, step_bp->GetID()); 488 step_bp->BreakpointHit(m_thread->Process()->ProcessID(), m_thread->ThreadID()); 489 } 490 491 // Remove all Thumb IT breakpoints 492 for (int i = 0; i < m_sw_single_step_itblock_break_count; i++) 493 { 494 if (NUB_BREAK_ID_IS_VALID(m_sw_single_step_itblock_break_id[i])) 495 { 496 DNBLogThreadedIf(LOG_STEP, "%s: removing IT software single step breakpoint (breakID=%d)", __FUNCTION__, m_sw_single_step_itblock_break_id[i]); 497 success = m_thread->Process()->DisableBreakpoint(m_sw_single_step_itblock_break_id[i], true); 498 m_sw_single_step_itblock_break_id[i] = INVALID_NUB_BREAK_ID; 499 } 500 } 501 m_sw_single_step_itblock_break_count = 0; 502 503#if defined (USE_ARM_DISASSEMBLER_FRAMEWORK) 504 505 // Decode instructions up to the current PC to ensure the internal decoder state is valid for the IT block 506 // The decoder has to decode each instruction in the IT block even if it is not executed so that 507 // the fields are correctly updated 508 DecodeITBlockInstructions(m_state.context.gpr.__pc); 509#endif 510 } 511 512 } 513 else 514 success = EnableHardwareSingleStep(false) == KERN_SUCCESS; 515#endif 516 } 517 else 518 { 519 // The MachThread will automatically restore the suspend count 520 // in ThreadDidStop(), so we don't need to do anything here if 521 // we weren't the primary thread the last time 522 } 523 } 524 return success; 525} 526 527bool 528DNBArchMachARM::NotifyException(MachException::Data& exc) 529{ 530 switch (exc.exc_type) 531 { 532 default: 533 break; 534 case EXC_BREAKPOINT: 535 if (exc.exc_data.size() == 2 && exc.exc_data[0] == EXC_ARM_DA_DEBUG) 536 { 537 // exc_code = EXC_ARM_DA_DEBUG 538 // 539 // Check whether this corresponds to a watchpoint hit event. 540 // If yes, retrieve the exc_sub_code as the data break address. 541 if (!HasWatchpointOccurred()) 542 break; 543 544 // The data break address is passed as exc_data[1]. 545 nub_addr_t addr = exc.exc_data[1]; 546 // Find the hardware index with the side effect of possibly massaging the 547 // addr to return the starting address as seen from the debugger side. 548 uint32_t hw_index = GetHardwareWatchpointHit(addr); 549 if (hw_index != INVALID_NUB_HW_INDEX) 550 { 551 m_watchpoint_did_occur = true; 552 m_watchpoint_hw_index = hw_index; 553 exc.exc_data[1] = addr; 554 // Piggyback the hw_index in the exc.data. 555 exc.exc_data.push_back(hw_index); 556 } 557 558 return true; 559 } 560 break; 561 } 562 return false; 563} 564 565bool 566DNBArchMachARM::StepNotComplete () 567{ 568 if (m_hw_single_chained_step_addr != INVALID_NUB_ADDRESS) 569 { 570 kern_return_t kret = KERN_INVALID_ARGUMENT; 571 kret = GetGPRState(false); 572 if (kret == KERN_SUCCESS) 573 { 574 if (m_state.context.gpr.__pc == m_hw_single_chained_step_addr) 575 { 576 DNBLogThreadedIf(LOG_STEP, "Need to step some more at 0x%8.8x", m_hw_single_chained_step_addr); 577 return true; 578 } 579 } 580 } 581 582 m_hw_single_chained_step_addr = INVALID_NUB_ADDRESS; 583 return false; 584} 585 586 587#if defined (USE_ARM_DISASSEMBLER_FRAMEWORK) 588 589void 590DNBArchMachARM::DecodeITBlockInstructions(nub_addr_t curr_pc) 591 592{ 593 uint16_t opcode16; 594 uint32_t opcode32; 595 nub_addr_t next_pc_in_itblock; 596 nub_addr_t pc_in_itblock = m_last_decode_pc; 597 598 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: last_decode_pc=0x%8.8x", __FUNCTION__, m_last_decode_pc); 599 600 // Decode IT block instruction from the instruction following the m_last_decoded_instruction at 601 // PC m_last_decode_pc upto and including the instruction at curr_pc 602 if (m_thread->Process()->Task().ReadMemory(pc_in_itblock, 2, &opcode16) == 2) 603 { 604 opcode32 = opcode16; 605 pc_in_itblock += 2; 606 // Check for 32 bit thumb opcode and read the upper 16 bits if needed 607 if (((opcode32 & 0xE000) == 0xE000) && opcode32 & 0x1800) 608 { 609 // Adjust 'next_pc_in_itblock' to point to the default next Thumb instruction for 610 // a 32 bit Thumb opcode 611 // Read bits 31:16 of a 32 bit Thumb opcode 612 if (m_thread->Process()->Task().ReadMemory(pc_in_itblock, 2, &opcode16) == 2) 613 { 614 pc_in_itblock += 2; 615 // 32 bit thumb opcode 616 opcode32 = (opcode32 << 16) | opcode16; 617 } 618 else 619 { 620 DNBLogError("%s: Unable to read opcode bits 31:16 for a 32 bit thumb opcode at pc=0x%8.8llx", __FUNCTION__, (uint64_t)pc_in_itblock); 621 } 622 } 623 } 624 else 625 { 626 DNBLogError("%s: Error reading 16-bit Thumb instruction at pc=0x%8.8x", __FUNCTION__, pc_in_itblock); 627 } 628 629 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: pc_in_itblock=0x%8.8x, curr_pc=0x%8.8x", __FUNCTION__, pc_in_itblock, curr_pc); 630 631 next_pc_in_itblock = pc_in_itblock; 632 while (next_pc_in_itblock <= curr_pc) 633 { 634 arm_error_t decodeError; 635 636 m_last_decode_pc = pc_in_itblock; 637 decodeError = DecodeInstructionUsingDisassembler(pc_in_itblock, m_state.context.gpr.__cpsr, &m_last_decode_arm, &m_last_decode_thumb, &next_pc_in_itblock); 638 639 pc_in_itblock = next_pc_in_itblock; 640 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: next_pc_in_itblock=0x%8.8x", __FUNCTION__, next_pc_in_itblock); 641 } 642} 643#endif 644 645// Set the single step bit in the processor status register. 646kern_return_t 647DNBArchMachARM::EnableHardwareSingleStep (bool enable) 648{ 649 DNBError err; 650 DNBLogThreadedIf(LOG_STEP, "%s( enable = %d )", __FUNCTION__, enable); 651 652 err = GetGPRState(false); 653 654 if (err.Fail()) 655 { 656 err.LogThreaded("%s: failed to read the GPR registers", __FUNCTION__); 657 return err.Error(); 658 } 659 660 err = GetDBGState(false); 661 662 if (err.Fail()) 663 { 664 err.LogThreaded("%s: failed to read the DBG registers", __FUNCTION__); 665 return err.Error(); 666 } 667 668 const uint32_t i = 0; 669 if (enable) 670 { 671 m_hw_single_chained_step_addr = INVALID_NUB_ADDRESS; 672 673 // Save our previous state 674 m_dbg_save = m_state.dbg; 675 // Set a breakpoint that will stop when the PC doesn't match the current one! 676 m_state.dbg.__bvr[i] = m_state.context.gpr.__pc & 0xFFFFFFFCu; // Set the current PC as the breakpoint address 677 m_state.dbg.__bcr[i] = BCR_M_IMVA_MISMATCH | // Stop on address mismatch 678 S_USER | // Stop only in user mode 679 BCR_ENABLE; // Enable this breakpoint 680 if (m_state.context.gpr.__cpsr & 0x20) 681 { 682 // Thumb breakpoint 683 if (m_state.context.gpr.__pc & 2) 684 m_state.dbg.__bcr[i] |= BAS_IMVA_2_3; 685 else 686 m_state.dbg.__bcr[i] |= BAS_IMVA_0_1; 687 688 uint16_t opcode; 689 if (sizeof(opcode) == m_thread->Process()->Task().ReadMemory(m_state.context.gpr.__pc, sizeof(opcode), &opcode)) 690 { 691 if (((opcode & 0xE000) == 0xE000) && opcode & 0x1800) 692 { 693 // 32 bit thumb opcode... 694 if (m_state.context.gpr.__pc & 2) 695 { 696 // We can't take care of a 32 bit thumb instruction single step 697 // with just IVA mismatching. We will need to chain an extra 698 // hardware single step in order to complete this single step... 699 m_hw_single_chained_step_addr = m_state.context.gpr.__pc + 2; 700 } 701 else 702 { 703 // Extend the number of bits to ignore for the mismatch 704 m_state.dbg.__bcr[i] |= BAS_IMVA_ALL; 705 } 706 } 707 } 708 } 709 else 710 { 711 // ARM breakpoint 712 m_state.dbg.__bcr[i] |= BAS_IMVA_ALL; // Stop when any address bits change 713 } 714 715 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]); 716 717 for (uint32_t j=i+1; j<16; ++j) 718 { 719 // Disable all others 720 m_state.dbg.__bvr[j] = 0; 721 m_state.dbg.__bcr[j] = 0; 722 } 723 } 724 else 725 { 726 // Just restore the state we had before we did single stepping 727 m_state.dbg = m_dbg_save; 728 } 729 730 return SetDBGState(); 731} 732 733// return 1 if bit "BIT" is set in "value" 734static inline uint32_t bit(uint32_t value, uint32_t bit) 735{ 736 return (value >> bit) & 1u; 737} 738 739// return the bitfield "value[msbit:lsbit]". 740static inline uint32_t bits(uint32_t value, uint32_t msbit, uint32_t lsbit) 741{ 742 assert(msbit >= lsbit); 743 uint32_t shift_left = sizeof(value) * 8 - 1 - msbit; 744 value <<= shift_left; // shift anything above the msbit off of the unsigned edge 745 value >>= (shift_left + lsbit); // shift it back again down to the lsbit (including undoing any shift from above) 746 return value; // return our result 747} 748 749bool 750DNBArchMachARM::ConditionPassed(uint8_t condition, uint32_t cpsr) 751{ 752 uint32_t cpsr_n = bit(cpsr, 31); // Negative condition code flag 753 uint32_t cpsr_z = bit(cpsr, 30); // Zero condition code flag 754 uint32_t cpsr_c = bit(cpsr, 29); // Carry condition code flag 755 uint32_t cpsr_v = bit(cpsr, 28); // Overflow condition code flag 756 757 switch (condition) { 758 case COND_EQ: // (0x0) 759 if (cpsr_z == 1) return true; 760 break; 761 case COND_NE: // (0x1) 762 if (cpsr_z == 0) return true; 763 break; 764 case COND_CS: // (0x2) 765 if (cpsr_c == 1) return true; 766 break; 767 case COND_CC: // (0x3) 768 if (cpsr_c == 0) return true; 769 break; 770 case COND_MI: // (0x4) 771 if (cpsr_n == 1) return true; 772 break; 773 case COND_PL: // (0x5) 774 if (cpsr_n == 0) return true; 775 break; 776 case COND_VS: // (0x6) 777 if (cpsr_v == 1) return true; 778 break; 779 case COND_VC: // (0x7) 780 if (cpsr_v == 0) return true; 781 break; 782 case COND_HI: // (0x8) 783 if ((cpsr_c == 1) && (cpsr_z == 0)) return true; 784 break; 785 case COND_LS: // (0x9) 786 if ((cpsr_c == 0) || (cpsr_z == 1)) return true; 787 break; 788 case COND_GE: // (0xA) 789 if (cpsr_n == cpsr_v) return true; 790 break; 791 case COND_LT: // (0xB) 792 if (cpsr_n != cpsr_v) return true; 793 break; 794 case COND_GT: // (0xC) 795 if ((cpsr_z == 0) && (cpsr_n == cpsr_v)) return true; 796 break; 797 case COND_LE: // (0xD) 798 if ((cpsr_z == 1) || (cpsr_n != cpsr_v)) return true; 799 break; 800 default: 801 return true; 802 break; 803 } 804 805 return false; 806} 807 808#if defined (USE_ARM_DISASSEMBLER_FRAMEWORK) 809 810bool 811DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t decodedInstruction, bool currentPCIsThumb, nub_addr_t *targetPC) 812{ 813 nub_addr_t myTargetPC, addressWherePCLives; 814 pid_t mypid; 815 816 uint32_t cpsr_c = bit(m_state.context.gpr.__cpsr, 29); // Carry condition code flag 817 818 uint32_t firstOperand=0, secondOperand=0, shiftAmount=0, secondOperandAfterShift=0, immediateValue=0; 819 uint32_t halfwords=0, baseAddress=0, immediateOffset=0, addressOffsetFromRegister=0, addressOffsetFromRegisterAfterShift; 820 uint32_t baseAddressIndex=INVALID_NUB_HW_INDEX; 821 uint32_t firstOperandIndex=INVALID_NUB_HW_INDEX; 822 uint32_t secondOperandIndex=INVALID_NUB_HW_INDEX; 823 uint32_t addressOffsetFromRegisterIndex=INVALID_NUB_HW_INDEX; 824 uint32_t shiftRegisterIndex=INVALID_NUB_HW_INDEX; 825 uint16_t registerList16, registerList16NoPC; 826 uint8_t registerList8; 827 uint32_t numRegistersToLoad=0; 828 829 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: instruction->code=%d", __FUNCTION__, decodedInstruction.instruction->code); 830 831 // Get the following in this switch statement: 832 // - firstOperand, secondOperand, immediateValue, shiftAmount: For arithmetic, logical and move instructions 833 // - baseAddress, immediateOffset, shiftAmount: For LDR 834 // - numRegistersToLoad: For LDM and POP instructions 835 switch (decodedInstruction.instruction->code) 836 { 837 // Arithmetic operations that can change the PC 838 case ARM_INST_ADC: 839 case ARM_INST_ADCS: 840 case ARM_INST_ADD: 841 case ARM_INST_ADDS: 842 case ARM_INST_AND: 843 case ARM_INST_ANDS: 844 case ARM_INST_ASR: 845 case ARM_INST_ASRS: 846 case ARM_INST_BIC: 847 case ARM_INST_BICS: 848 case ARM_INST_EOR: 849 case ARM_INST_EORS: 850 case ARM_INST_ORR: 851 case ARM_INST_ORRS: 852 case ARM_INST_RSB: 853 case ARM_INST_RSBS: 854 case ARM_INST_RSC: 855 case ARM_INST_RSCS: 856 case ARM_INST_SBC: 857 case ARM_INST_SBCS: 858 case ARM_INST_SUB: 859 case ARM_INST_SUBS: 860 switch (decodedInstruction.addressMode) 861 { 862 case ARM_ADDR_DATA_IMM: 863 if (decodedInstruction.numOperands != 3) 864 { 865 DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); 866 return false; 867 } 868 869 if (decodedInstruction.op[0].value != PC_REG) 870 { 871 DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); 872 return false; 873 } 874 875 // Get firstOperand register value (at index=1) 876 firstOperandIndex = decodedInstruction.op[1].value; // first operand register index 877 firstOperand = m_state.context.gpr.__r[firstOperandIndex]; 878 879 // Get immediateValue (at index=2) 880 immediateValue = decodedInstruction.op[2].value; 881 882 break; 883 884 case ARM_ADDR_DATA_REG: 885 if (decodedInstruction.numOperands != 3) 886 { 887 DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); 888 return false; 889 } 890 891 if (decodedInstruction.op[0].value != PC_REG) 892 { 893 DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); 894 return false; 895 } 896 897 // Get firstOperand register value (at index=1) 898 firstOperandIndex = decodedInstruction.op[1].value; // first operand register index 899 firstOperand = m_state.context.gpr.__r[firstOperandIndex]; 900 901 // Get secondOperand register value (at index=2) 902 secondOperandIndex = decodedInstruction.op[2].value; // second operand register index 903 secondOperand = m_state.context.gpr.__r[secondOperandIndex]; 904 905 break; 906 907 case ARM_ADDR_DATA_SCALED_IMM: 908 if (decodedInstruction.numOperands != 4) 909 { 910 DNBLogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); 911 return false; 912 } 913 914 if (decodedInstruction.op[0].value != PC_REG) 915 { 916 DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); 917 return false; 918 } 919 920 // Get firstOperand register value (at index=1) 921 firstOperandIndex = decodedInstruction.op[1].value; // first operand register index 922 firstOperand = m_state.context.gpr.__r[firstOperandIndex]; 923 924 // Get secondOperand register value (at index=2) 925 secondOperandIndex = decodedInstruction.op[2].value; // second operand register index 926 secondOperand = m_state.context.gpr.__r[secondOperandIndex]; 927 928 // Get shiftAmount as immediate value (at index=3) 929 shiftAmount = decodedInstruction.op[3].value; 930 931 break; 932 933 934 case ARM_ADDR_DATA_SCALED_REG: 935 if (decodedInstruction.numOperands != 4) 936 { 937 DNBLogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); 938 return false; 939 } 940 941 if (decodedInstruction.op[0].value != PC_REG) 942 { 943 DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); 944 return false; 945 } 946 947 // Get firstOperand register value (at index=1) 948 firstOperandIndex = decodedInstruction.op[1].value; // first operand register index 949 firstOperand = m_state.context.gpr.__r[firstOperandIndex]; 950 951 // Get secondOperand register value (at index=2) 952 secondOperandIndex = decodedInstruction.op[2].value; // second operand register index 953 secondOperand = m_state.context.gpr.__r[secondOperandIndex]; 954 955 // Get shiftAmount from register (at index=3) 956 shiftRegisterIndex = decodedInstruction.op[3].value; // second operand register index 957 shiftAmount = m_state.context.gpr.__r[shiftRegisterIndex]; 958 959 break; 960 961 case THUMB_ADDR_HR_HR: 962 if (decodedInstruction.numOperands != 2) 963 { 964 DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); 965 return false; 966 } 967 968 if (decodedInstruction.op[0].value != PC_REG) 969 { 970 DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); 971 return false; 972 } 973 974 // Get firstOperand register value (at index=0) 975 firstOperandIndex = decodedInstruction.op[0].value; // first operand register index 976 firstOperand = m_state.context.gpr.__r[firstOperandIndex]; 977 978 // Get secondOperand register value (at index=1) 979 secondOperandIndex = decodedInstruction.op[1].value; // second operand register index 980 secondOperand = m_state.context.gpr.__r[secondOperandIndex]; 981 982 break; 983 984 default: 985 break; 986 } 987 break; 988 989 // Logical shifts and move operations that can change the PC 990 case ARM_INST_LSL: 991 case ARM_INST_LSLS: 992 case ARM_INST_LSR: 993 case ARM_INST_LSRS: 994 case ARM_INST_MOV: 995 case ARM_INST_MOVS: 996 case ARM_INST_MVN: 997 case ARM_INST_MVNS: 998 case ARM_INST_ROR: 999 case ARM_INST_RORS: 1000 case ARM_INST_RRX: 1001 case ARM_INST_RRXS: 1002 // In these cases, the firstOperand is always 0, as if it does not exist 1003 switch (decodedInstruction.addressMode) 1004 { 1005 case ARM_ADDR_DATA_IMM: 1006 if (decodedInstruction.numOperands != 2) 1007 { 1008 DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); 1009 return false; 1010 } 1011 1012 if (decodedInstruction.op[0].value != PC_REG) 1013 { 1014 DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); 1015 return false; 1016 } 1017 1018 // Get immediateValue (at index=1) 1019 immediateValue = decodedInstruction.op[1].value; 1020 1021 break; 1022 1023 case ARM_ADDR_DATA_REG: 1024 if (decodedInstruction.numOperands != 2) 1025 { 1026 DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); 1027 return false; 1028 } 1029 1030 if (decodedInstruction.op[0].value != PC_REG) 1031 { 1032 DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); 1033 return false; 1034 } 1035 1036 // Get secondOperand register value (at index=1) 1037 secondOperandIndex = decodedInstruction.op[1].value; // second operand register index 1038 secondOperand = m_state.context.gpr.__r[secondOperandIndex]; 1039 1040 break; 1041 1042 case ARM_ADDR_DATA_SCALED_IMM: 1043 if (decodedInstruction.numOperands != 3) 1044 { 1045 DNBLogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); 1046 return false; 1047 } 1048 1049 if (decodedInstruction.op[0].value != PC_REG) 1050 { 1051 DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); 1052 return false; 1053 } 1054 1055 // Get secondOperand register value (at index=1) 1056 secondOperandIndex = decodedInstruction.op[2].value; // second operand register index 1057 secondOperand = m_state.context.gpr.__r[secondOperandIndex]; 1058 1059 // Get shiftAmount as immediate value (at index=2) 1060 shiftAmount = decodedInstruction.op[2].value; 1061 1062 break; 1063 1064 1065 case ARM_ADDR_DATA_SCALED_REG: 1066 if (decodedInstruction.numOperands != 3) 1067 { 1068 DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); 1069 return false; 1070 } 1071 1072 if (decodedInstruction.op[0].value != PC_REG) 1073 { 1074 DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); 1075 return false; 1076 } 1077 1078 // Get secondOperand register value (at index=1) 1079 secondOperandIndex = decodedInstruction.op[1].value; // second operand register index 1080 secondOperand = m_state.context.gpr.__r[secondOperandIndex]; 1081 1082 // Get shiftAmount from register (at index=2) 1083 shiftRegisterIndex = decodedInstruction.op[2].value; // second operand register index 1084 shiftAmount = m_state.context.gpr.__r[shiftRegisterIndex]; 1085 1086 break; 1087 1088 case THUMB_ADDR_HR_HR: 1089 if (decodedInstruction.numOperands != 2) 1090 { 1091 DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); 1092 return false; 1093 } 1094 1095 if (decodedInstruction.op[0].value != PC_REG) 1096 { 1097 DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); 1098 return false; 1099 } 1100 1101 // Get secondOperand register value (at index=1) 1102 secondOperandIndex = decodedInstruction.op[1].value; // second operand register index 1103 secondOperand = m_state.context.gpr.__r[secondOperandIndex]; 1104 1105 break; 1106 1107 default: 1108 break; 1109 } 1110 1111 break; 1112 1113 // Simple branches, used to hop around within a routine 1114 case ARM_INST_B: 1115 *targetPC = decodedInstruction.targetPC; // Known targetPC 1116 return true; 1117 break; 1118 1119 // Branch-and-link, used to call ARM subroutines 1120 case ARM_INST_BL: 1121 *targetPC = decodedInstruction.targetPC; // Known targetPC 1122 return true; 1123 break; 1124 1125 // Branch-and-link with exchange, used to call opposite-mode subroutines 1126 case ARM_INST_BLX: 1127 if ((decodedInstruction.addressMode == ARM_ADDR_BRANCH_IMM) || 1128 (decodedInstruction.addressMode == THUMB_ADDR_UNCOND)) 1129 { 1130 *targetPC = decodedInstruction.targetPC; // Known targetPC 1131 return true; 1132 } 1133 else // addressMode == ARM_ADDR_BRANCH_REG 1134 { 1135 // Unknown target unless we're branching to the PC itself, 1136 // although this may not work properly with BLX 1137 if (decodedInstruction.op[REG_RD].value == PC_REG) 1138 { 1139 // this should (almost) never happen 1140 *targetPC = decodedInstruction.targetPC; // Known targetPC 1141 return true; 1142 } 1143 1144 // Get the branch address and return 1145 if (decodedInstruction.numOperands != 1) 1146 { 1147 DNBLogError("Expected 1 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); 1148 return false; 1149 } 1150 1151 // Get branch address in register (at index=0) 1152 *targetPC = m_state.context.gpr.__r[decodedInstruction.op[0].value]; 1153 return true; 1154 } 1155 break; 1156 1157 // Branch with exchange, used to hop to opposite-mode code 1158 // Branch to Jazelle code, used to execute Java; included here since it 1159 // acts just like BX unless the Jazelle unit is active and JPC is 1160 // already loaded into it. 1161 case ARM_INST_BX: 1162 case ARM_INST_BXJ: 1163 // Unknown target unless we're branching to the PC itself, 1164 // although this can never switch to Thumb mode and is 1165 // therefore pretty much useless 1166 if (decodedInstruction.op[REG_RD].value == PC_REG) 1167 { 1168 // this should (almost) never happen 1169 *targetPC = decodedInstruction.targetPC; // Known targetPC 1170 return true; 1171 } 1172 1173 // Get the branch address and return 1174 if (decodedInstruction.numOperands != 1) 1175 { 1176 DNBLogError("Expected 1 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); 1177 return false; 1178 } 1179 1180 // Get branch address in register (at index=0) 1181 *targetPC = m_state.context.gpr.__r[decodedInstruction.op[0].value]; 1182 return true; 1183 break; 1184 1185 // Compare and branch on zero/non-zero (Thumb-16 only) 1186 // Unusual condition check built into the instruction 1187 case ARM_INST_CBZ: 1188 case ARM_INST_CBNZ: 1189 // Branch address is known at compile time 1190 // Get the branch address and return 1191 if (decodedInstruction.numOperands != 2) 1192 { 1193 DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); 1194 return false; 1195 } 1196 1197 // Get branch address as an immediate value (at index=1) 1198 *targetPC = decodedInstruction.op[1].value; 1199 return true; 1200 break; 1201 1202 // Load register can be used to load PC, usually with a function pointer 1203 case ARM_INST_LDR: 1204 if (decodedInstruction.op[REG_RD].value != PC_REG) 1205 { 1206 DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); 1207 return false; 1208 } 1209 switch (decodedInstruction.addressMode) 1210 { 1211 case ARM_ADDR_LSWUB_IMM: 1212 case ARM_ADDR_LSWUB_IMM_PRE: 1213 case ARM_ADDR_LSWUB_IMM_POST: 1214 if (decodedInstruction.numOperands != 3) 1215 { 1216 DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); 1217 return false; 1218 } 1219 1220 // Get baseAddress from register (at index=1) 1221 baseAddressIndex = decodedInstruction.op[1].value; 1222 baseAddress = m_state.context.gpr.__r[baseAddressIndex]; 1223 1224 // Get immediateOffset (at index=2) 1225 immediateOffset = decodedInstruction.op[2].value; 1226 break; 1227 1228 case ARM_ADDR_LSWUB_REG: 1229 case ARM_ADDR_LSWUB_REG_PRE: 1230 case ARM_ADDR_LSWUB_REG_POST: 1231 if (decodedInstruction.numOperands != 3) 1232 { 1233 DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); 1234 return false; 1235 } 1236 1237 // Get baseAddress from register (at index=1) 1238 baseAddressIndex = decodedInstruction.op[1].value; 1239 baseAddress = m_state.context.gpr.__r[baseAddressIndex]; 1240 1241 // Get immediateOffset from register (at index=2) 1242 addressOffsetFromRegisterIndex = decodedInstruction.op[2].value; 1243 addressOffsetFromRegister = m_state.context.gpr.__r[addressOffsetFromRegisterIndex]; 1244 1245 break; 1246 1247 case ARM_ADDR_LSWUB_SCALED: 1248 case ARM_ADDR_LSWUB_SCALED_PRE: 1249 case ARM_ADDR_LSWUB_SCALED_POST: 1250 if (decodedInstruction.numOperands != 4) 1251 { 1252 DNBLogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); 1253 return false; 1254 } 1255 1256 // Get baseAddress from register (at index=1) 1257 baseAddressIndex = decodedInstruction.op[1].value; 1258 baseAddress = m_state.context.gpr.__r[baseAddressIndex]; 1259 1260 // Get immediateOffset from register (at index=2) 1261 addressOffsetFromRegisterIndex = decodedInstruction.op[2].value; 1262 addressOffsetFromRegister = m_state.context.gpr.__r[addressOffsetFromRegisterIndex]; 1263 1264 // Get shiftAmount (at index=3) 1265 shiftAmount = decodedInstruction.op[3].value; 1266 1267 break; 1268 1269 default: 1270 break; 1271 } 1272 break; 1273 1274 // 32b load multiple operations can load the PC along with everything else, 1275 // usually to return from a function call 1276 case ARM_INST_LDMDA: 1277 case ARM_INST_LDMDB: 1278 case ARM_INST_LDMIA: 1279 case ARM_INST_LDMIB: 1280 if (decodedInstruction.op[LDM_REGLIST].value & PC_REGLIST_BIT) 1281 { 1282 if (decodedInstruction.numOperands != 2) 1283 { 1284 DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands); 1285 return false; 1286 } 1287 1288 // Get baseAddress from register (at index=0) 1289 baseAddressIndex = decodedInstruction.op[0].value; 1290 baseAddress = m_state.context.gpr.__r[baseAddressIndex]; 1291 1292 // Get registerList from register (at index=1) 1293 registerList16 = (uint16_t)decodedInstruction.op[1].value; 1294 1295 // Count number of registers to load in the multiple register list excluding the PC 1296 registerList16NoPC = registerList16&0x3FFF; // exclude the PC 1297 numRegistersToLoad=0; 1298 for (int i = 0; i < 16; i++) 1299 { 1300 if (registerList16NoPC & 0x1) numRegistersToLoad++; 1301 registerList16NoPC = registerList16NoPC >> 1; 1302 } 1303 } 1304 else 1305 { 1306 DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value); 1307 return false; 1308 } 1309 break; 1310 1311 // Normal 16-bit LD multiple can't touch R15, but POP can 1312 case ARM_INST_POP: // Can also get the PC & updates SP 1313 // Get baseAddress from SP (at index=0) 1314 baseAddress = m_state.context.gpr.__sp; 1315 1316 if (decodedInstruction.thumb16b) 1317 { 1318 // Get registerList from register (at index=0) 1319 registerList8 = (uint8_t)decodedInstruction.op[0].value; 1320 1321 // Count number of registers to load in the multiple register list 1322 numRegistersToLoad=0; 1323 for (int i = 0; i < 8; i++) 1324 { 1325 if (registerList8 & 0x1) numRegistersToLoad++; 1326 registerList8 = registerList8 >> 1; 1327 } 1328 } 1329 else 1330 { 1331 // Get registerList from register (at index=0) 1332 registerList16 = (uint16_t)decodedInstruction.op[0].value; 1333 1334 // Count number of registers to load in the multiple register list excluding the PC 1335 registerList16NoPC = registerList16&0x3FFF; // exclude the PC 1336 numRegistersToLoad=0; 1337 for (int i = 0; i < 16; i++) 1338 { 1339 if (registerList16NoPC & 0x1) numRegistersToLoad++; 1340 registerList16NoPC = registerList16NoPC >> 1; 1341 } 1342 } 1343 break; 1344 1345 // 16b TBB and TBH instructions load a jump address from a table 1346 case ARM_INST_TBB: 1347 case ARM_INST_TBH: 1348 // Get baseAddress from register (at index=0) 1349 baseAddressIndex = decodedInstruction.op[0].value; 1350 baseAddress = m_state.context.gpr.__r[baseAddressIndex]; 1351 1352 // Get immediateOffset from register (at index=1) 1353 addressOffsetFromRegisterIndex = decodedInstruction.op[1].value; 1354 addressOffsetFromRegister = m_state.context.gpr.__r[addressOffsetFromRegisterIndex]; 1355 break; 1356 1357 // ThumbEE branch-to-handler instructions: Jump to handlers at some offset 1358 // from a special base pointer register (which is unknown at disassembly time) 1359 case ARM_INST_HB: 1360 case ARM_INST_HBP: 1361// TODO: ARM_INST_HB, ARM_INST_HBP 1362 break; 1363 1364 case ARM_INST_HBL: 1365 case ARM_INST_HBLP: 1366// TODO: ARM_INST_HBL, ARM_INST_HBLP 1367 break; 1368 1369 // Breakpoint and software interrupt jump to interrupt handler (always ARM) 1370 case ARM_INST_BKPT: 1371 case ARM_INST_SMC: 1372 case ARM_INST_SVC: 1373 1374 // Return from exception, obviously modifies PC [interrupt only!] 1375 case ARM_INST_RFEDA: 1376 case ARM_INST_RFEDB: 1377 case ARM_INST_RFEIA: 1378 case ARM_INST_RFEIB: 1379 1380 // Other instructions either can't change R15 or are "undefined" if you do, 1381 // so no sane compiler should ever generate them & we don't care here. 1382 // Also, R15 can only legally be used in a read-only manner for the 1383 // various ARM addressing mode (to get PC-relative addressing of constants), 1384 // but can NOT be used with any of the update modes. 1385 default: 1386 DNBLogError("%s should not be called for instruction code %d!", __FUNCTION__, decodedInstruction.instruction->code); 1387 return false; 1388 break; 1389 } 1390 1391 // Adjust PC if PC is one of the input operands 1392 if (baseAddressIndex == PC_REG) 1393 { 1394 if (currentPCIsThumb) 1395 baseAddress += 4; 1396 else 1397 baseAddress += 8; 1398 } 1399 1400 if (firstOperandIndex == PC_REG) 1401 { 1402 if (currentPCIsThumb) 1403 firstOperand += 4; 1404 else 1405 firstOperand += 8; 1406 } 1407 1408 if (secondOperandIndex == PC_REG) 1409 { 1410 if (currentPCIsThumb) 1411 secondOperand += 4; 1412 else 1413 secondOperand += 8; 1414 } 1415 1416 if (addressOffsetFromRegisterIndex == PC_REG) 1417 { 1418 if (currentPCIsThumb) 1419 addressOffsetFromRegister += 4; 1420 else 1421 addressOffsetFromRegister += 8; 1422 } 1423 1424 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, 1425 "%s: firstOperand=%8.8x, secondOperand=%8.8x, immediateValue = %d, shiftAmount = %d, baseAddress = %8.8x, addressOffsetFromRegister = %8.8x, immediateOffset = %d, numRegistersToLoad = %d", 1426 __FUNCTION__, 1427 firstOperand, 1428 secondOperand, 1429 immediateValue, 1430 shiftAmount, 1431 baseAddress, 1432 addressOffsetFromRegister, 1433 immediateOffset, 1434 numRegistersToLoad); 1435 1436 1437 // Calculate following values after applying shiftAmount: 1438 // - immediateOffsetAfterShift, secondOperandAfterShift 1439 1440 switch (decodedInstruction.scaleMode) 1441 { 1442 case ARM_SCALE_NONE: 1443 addressOffsetFromRegisterAfterShift = addressOffsetFromRegister; 1444 secondOperandAfterShift = secondOperand; 1445 break; 1446 1447 case ARM_SCALE_LSL: // Logical shift left 1448 addressOffsetFromRegisterAfterShift = addressOffsetFromRegister << shiftAmount; 1449 secondOperandAfterShift = secondOperand << shiftAmount; 1450 break; 1451 1452 case ARM_SCALE_LSR: // Logical shift right 1453 addressOffsetFromRegisterAfterShift = addressOffsetFromRegister >> shiftAmount; 1454 secondOperandAfterShift = secondOperand >> shiftAmount; 1455 break; 1456 1457 case ARM_SCALE_ASR: // Arithmetic shift right 1458 asm("mov %0, %1, asr %2" : "=r" (addressOffsetFromRegisterAfterShift) : "r" (addressOffsetFromRegister), "r" (shiftAmount)); 1459 asm("mov %0, %1, asr %2" : "=r" (secondOperandAfterShift) : "r" (secondOperand), "r" (shiftAmount)); 1460 break; 1461 1462 case ARM_SCALE_ROR: // Rotate right 1463 asm("mov %0, %1, ror %2" : "=r" (addressOffsetFromRegisterAfterShift) : "r" (addressOffsetFromRegister), "r" (shiftAmount)); 1464 asm("mov %0, %1, ror %2" : "=r" (secondOperandAfterShift) : "r" (secondOperand), "r" (shiftAmount)); 1465 break; 1466 1467 case ARM_SCALE_RRX: // Rotate right, pulling in carry (1-bit shift only) 1468 asm("mov %0, %1, rrx" : "=r" (addressOffsetFromRegisterAfterShift) : "r" (addressOffsetFromRegister)); 1469 asm("mov %0, %1, rrx" : "=r" (secondOperandAfterShift) : "r" (secondOperand)); 1470 break; 1471 } 1472 1473 // Emulate instruction to calculate targetPC 1474 // All branches are already handled in the first switch statement. A branch should not reach this switch 1475 switch (decodedInstruction.instruction->code) 1476 { 1477 // Arithmetic operations that can change the PC 1478 case ARM_INST_ADC: 1479 case ARM_INST_ADCS: 1480 // Add with Carry 1481 *targetPC = firstOperand + (secondOperandAfterShift + immediateValue) + cpsr_c; 1482 break; 1483 1484 case ARM_INST_ADD: 1485 case ARM_INST_ADDS: 1486 *targetPC = firstOperand + (secondOperandAfterShift + immediateValue); 1487 break; 1488 1489 case ARM_INST_AND: 1490 case ARM_INST_ANDS: 1491 *targetPC = firstOperand & (secondOperandAfterShift + immediateValue); 1492 break; 1493 1494 case ARM_INST_ASR: 1495 case ARM_INST_ASRS: 1496 asm("mov %0, %1, asr %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue)); 1497 *targetPC = myTargetPC; 1498 break; 1499 1500 case ARM_INST_BIC: 1501 case ARM_INST_BICS: 1502 asm("bic %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue)); 1503 *targetPC = myTargetPC; 1504 break; 1505 1506 case ARM_INST_EOR: 1507 case ARM_INST_EORS: 1508 asm("eor %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue)); 1509 *targetPC = myTargetPC; 1510 break; 1511 1512 case ARM_INST_ORR: 1513 case ARM_INST_ORRS: 1514 asm("orr %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue)); 1515 *targetPC = myTargetPC; 1516 break; 1517 1518 case ARM_INST_RSB: 1519 case ARM_INST_RSBS: 1520 asm("rsb %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue)); 1521 *targetPC = myTargetPC; 1522 break; 1523 1524 case ARM_INST_RSC: 1525 case ARM_INST_RSCS: 1526 myTargetPC = secondOperandAfterShift - (firstOperand + !cpsr_c); 1527 *targetPC = myTargetPC; 1528 break; 1529 1530 case ARM_INST_SBC: 1531 case ARM_INST_SBCS: 1532 asm("sbc %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue + !cpsr_c)); 1533 *targetPC = myTargetPC; 1534 break; 1535 1536 case ARM_INST_SUB: 1537 case ARM_INST_SUBS: 1538 asm("sub %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue)); 1539 *targetPC = myTargetPC; 1540 break; 1541 1542 // Logical shifts and move operations that can change the PC 1543 case ARM_INST_LSL: 1544 case ARM_INST_LSLS: 1545 case ARM_INST_LSR: 1546 case ARM_INST_LSRS: 1547 case ARM_INST_MOV: 1548 case ARM_INST_MOVS: 1549 case ARM_INST_ROR: 1550 case ARM_INST_RORS: 1551 case ARM_INST_RRX: 1552 case ARM_INST_RRXS: 1553 myTargetPC = secondOperandAfterShift + immediateValue; 1554 *targetPC = myTargetPC; 1555 break; 1556 1557 case ARM_INST_MVN: 1558 case ARM_INST_MVNS: 1559 myTargetPC = !(secondOperandAfterShift + immediateValue); 1560 *targetPC = myTargetPC; 1561 break; 1562 1563 // Load register can be used to load PC, usually with a function pointer 1564 case ARM_INST_LDR: 1565 switch (decodedInstruction.addressMode) { 1566 case ARM_ADDR_LSWUB_IMM_POST: 1567 case ARM_ADDR_LSWUB_REG_POST: 1568 case ARM_ADDR_LSWUB_SCALED_POST: 1569 addressWherePCLives = baseAddress; 1570 break; 1571 1572 case ARM_ADDR_LSWUB_IMM: 1573 case ARM_ADDR_LSWUB_REG: 1574 case ARM_ADDR_LSWUB_SCALED: 1575 case ARM_ADDR_LSWUB_IMM_PRE: 1576 case ARM_ADDR_LSWUB_REG_PRE: 1577 case ARM_ADDR_LSWUB_SCALED_PRE: 1578 addressWherePCLives = baseAddress + (addressOffsetFromRegisterAfterShift + immediateOffset); 1579 break; 1580 1581 default: 1582 break; 1583 } 1584 1585 mypid = m_thread->ProcessID(); 1586 if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) != sizeof(nub_addr_t)) 1587 { 1588 DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives); 1589 return false; 1590 } 1591 1592 *targetPC = myTargetPC; 1593 break; 1594 1595 // 32b load multiple operations can load the PC along with everything else, 1596 // usually to return from a function call 1597 case ARM_INST_LDMDA: 1598 mypid = m_thread->ProcessID(); 1599 addressWherePCLives = baseAddress; 1600 if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) != sizeof(nub_addr_t)) 1601 { 1602 DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives); 1603 return false; 1604 } 1605 1606 *targetPC = myTargetPC; 1607 break; 1608 1609 case ARM_INST_LDMDB: 1610 mypid = m_thread->ProcessID(); 1611 addressWherePCLives = baseAddress - 4; 1612 if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) != sizeof(nub_addr_t)) 1613 { 1614 DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives); 1615 return false; 1616 } 1617 1618 *targetPC = myTargetPC; 1619 break; 1620 1621 case ARM_INST_LDMIB: 1622 mypid = m_thread->ProcessID(); 1623 addressWherePCLives = baseAddress + numRegistersToLoad*4 + 4; 1624 if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) != sizeof(nub_addr_t)) 1625 { 1626 DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives); 1627 return false; 1628 } 1629 1630 *targetPC = myTargetPC; 1631 break; 1632 1633 case ARM_INST_LDMIA: // same as pop 1634 // Normal 16-bit LD multiple can't touch R15, but POP can 1635 case ARM_INST_POP: // Can also get the PC & updates SP 1636 mypid = m_thread->ProcessID(); 1637 addressWherePCLives = baseAddress + numRegistersToLoad*4; 1638 if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) != sizeof(nub_addr_t)) 1639 { 1640 DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives); 1641 return false; 1642 } 1643 1644 *targetPC = myTargetPC; 1645 break; 1646 1647 // 16b TBB and TBH instructions load a jump address from a table 1648 case ARM_INST_TBB: 1649 mypid = m_thread->ProcessID(); 1650 addressWherePCLives = baseAddress + addressOffsetFromRegisterAfterShift; 1651 if (DNBProcessMemoryRead(mypid, addressWherePCLives, 1, &halfwords) != 1) 1652 { 1653 DNBLogError("Could not read memory at %8.8x to get targetPC when processing the TBB instruction!", addressWherePCLives); 1654 return false; 1655 } 1656 // add 4 to currentPC since we are in Thumb mode and then add 2*halfwords 1657 *targetPC = (currentPC + 4) + 2*halfwords; 1658 break; 1659 1660 case ARM_INST_TBH: 1661 mypid = m_thread->ProcessID(); 1662 addressWherePCLives = ((baseAddress + (addressOffsetFromRegisterAfterShift << 1)) & ~0x1); 1663 if (DNBProcessMemoryRead(mypid, addressWherePCLives, 2, &halfwords) != 2) 1664 { 1665 DNBLogError("Could not read memory at %8.8x to get targetPC when processing the TBH instruction!", addressWherePCLives); 1666 return false; 1667 } 1668 // add 4 to currentPC since we are in Thumb mode and then add 2*halfwords 1669 *targetPC = (currentPC + 4) + 2*halfwords; 1670 break; 1671 1672 // ThumbEE branch-to-handler instructions: Jump to handlers at some offset 1673 // from a special base pointer register (which is unknown at disassembly time) 1674 case ARM_INST_HB: 1675 case ARM_INST_HBP: 1676 // TODO: ARM_INST_HB, ARM_INST_HBP 1677 break; 1678 1679 case ARM_INST_HBL: 1680 case ARM_INST_HBLP: 1681 // TODO: ARM_INST_HBL, ARM_INST_HBLP 1682 break; 1683 1684 // Breakpoint and software interrupt jump to interrupt handler (always ARM) 1685 case ARM_INST_BKPT: 1686 case ARM_INST_SMC: 1687 case ARM_INST_SVC: 1688 // TODO: ARM_INST_BKPT, ARM_INST_SMC, ARM_INST_SVC 1689 break; 1690 1691 // Return from exception, obviously modifies PC [interrupt only!] 1692 case ARM_INST_RFEDA: 1693 case ARM_INST_RFEDB: 1694 case ARM_INST_RFEIA: 1695 case ARM_INST_RFEIB: 1696 // TODO: ARM_INST_RFEDA, ARM_INST_RFEDB, ARM_INST_RFEIA, ARM_INST_RFEIB 1697 break; 1698 1699 // Other instructions either can't change R15 or are "undefined" if you do, 1700 // so no sane compiler should ever generate them & we don't care here. 1701 // Also, R15 can only legally be used in a read-only manner for the 1702 // various ARM addressing mode (to get PC-relative addressing of constants), 1703 // but can NOT be used with any of the update modes. 1704 default: 1705 DNBLogError("%s should not be called for instruction code %d!", __FUNCTION__, decodedInstruction.instruction->code); 1706 return false; 1707 break; 1708 } 1709 1710 return true; 1711} 1712 1713void 1714DNBArchMachARM::EvaluateNextInstructionForSoftwareBreakpointSetup(nub_addr_t currentPC, uint32_t cpsr, bool currentPCIsThumb, nub_addr_t *nextPC, bool *nextPCIsThumb) 1715{ 1716 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "DNBArchMachARM::EvaluateNextInstructionForSoftwareBreakpointSetup() called"); 1717 1718 nub_addr_t targetPC = INVALID_NUB_ADDRESS; 1719 uint32_t registerValue; 1720 arm_error_t decodeError; 1721 nub_addr_t currentPCInITBlock, nextPCInITBlock; 1722 int i; 1723 bool last_decoded_instruction_executes = true; 1724 1725 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: default nextPC=0x%8.8x (%s)", __FUNCTION__, *nextPC, *nextPCIsThumb ? "Thumb" : "ARM"); 1726 1727 // Update *nextPC and *nextPCIsThumb for special cases 1728 if (m_last_decode_thumb.itBlockRemaining) // we are in an IT block 1729 { 1730 // Set the nextPC to the PC of the instruction which will execute in the IT block 1731 // If none of the instruction execute in the IT block based on the condition flags, 1732 // then point to the instruction immediately following the IT block 1733 const int itBlockRemaining = m_last_decode_thumb.itBlockRemaining; 1734 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: itBlockRemaining=%8.8x", __FUNCTION__, itBlockRemaining); 1735 1736 // Determine the PC at which the next instruction resides 1737 if (m_last_decode_arm.thumb16b) 1738 currentPCInITBlock = currentPC + 2; 1739 else 1740 currentPCInITBlock = currentPC + 4; 1741 1742 for (i = 0; i < itBlockRemaining; i++) 1743 { 1744 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: currentPCInITBlock=%8.8x", __FUNCTION__, currentPCInITBlock); 1745 decodeError = DecodeInstructionUsingDisassembler(currentPCInITBlock, cpsr, &m_last_decode_arm, &m_last_decode_thumb, &nextPCInITBlock); 1746 1747 if (decodeError != ARM_SUCCESS) 1748 DNBLogError("unable to disassemble instruction at 0x%8.8llx", (uint64_t)currentPCInITBlock); 1749 1750 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: condition=%d", __FUNCTION__, m_last_decode_arm.condition); 1751 if (ConditionPassed(m_last_decode_arm.condition, cpsr)) 1752 { 1753 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Condition codes matched for instruction %d", __FUNCTION__, i); 1754 break; // break from the for loop 1755 } 1756 else 1757 { 1758 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Condition codes DID NOT matched for instruction %d", __FUNCTION__, i); 1759 } 1760 1761 // update currentPC and nextPCInITBlock 1762 currentPCInITBlock = nextPCInITBlock; 1763 } 1764 1765 if (i == itBlockRemaining) // We came out of the IT block without executing any instructions 1766 last_decoded_instruction_executes = false; 1767 1768 *nextPC = currentPCInITBlock; 1769 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: After IT block step-through: *nextPC=%8.8x", __FUNCTION__, *nextPC); 1770 } 1771 1772 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, 1773 "%s: cpsr = %8.8x, thumb16b = %d, thumb = %d, branch = %d, conditional = %d, knownTarget = %d, links = %d, canSwitchMode = %d, doesSwitchMode = %d", 1774 __FUNCTION__, 1775 cpsr, 1776 m_last_decode_arm.thumb16b, 1777 m_last_decode_arm.thumb, 1778 m_last_decode_arm.branch, 1779 m_last_decode_arm.conditional, 1780 m_last_decode_arm.knownTarget, 1781 m_last_decode_arm.links, 1782 m_last_decode_arm.canSwitchMode, 1783 m_last_decode_arm.doesSwitchMode); 1784 1785 1786 if (last_decoded_instruction_executes && // Was this a conditional instruction that did execute? 1787 m_last_decode_arm.branch && // Can this instruction change the PC? 1788 (m_last_decode_arm.instruction->code != ARM_INST_SVC)) // If this instruction is not an SVC instruction 1789 { 1790 // Set targetPC. Compute if needed. 1791 if (m_last_decode_arm.knownTarget) 1792 { 1793 // Fixed, known PC-relative 1794 targetPC = m_last_decode_arm.targetPC; 1795 } 1796 else 1797 { 1798 // if targetPC is not known at compile time (PC-relative target), compute targetPC 1799 if (!ComputeNextPC(currentPC, m_last_decode_arm, currentPCIsThumb, &targetPC)) 1800 { 1801 DNBLogError("%s: Unable to compute targetPC for instruction at 0x%8.8llx", __FUNCTION__, (uint64_t)currentPC); 1802 targetPC = INVALID_NUB_ADDRESS; 1803 } 1804 } 1805 1806 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: targetPC=0x%8.8x, cpsr=0x%8.8x, condition=0x%hhx", __FUNCTION__, targetPC, cpsr, m_last_decode_arm.condition); 1807 1808 // Refine nextPC computation 1809 if ((m_last_decode_arm.instruction->code == ARM_INST_CBZ) || 1810 (m_last_decode_arm.instruction->code == ARM_INST_CBNZ)) 1811 { 1812 // Compare and branch on zero/non-zero (Thumb-16 only) 1813 // Unusual condition check built into the instruction 1814 registerValue = m_state.context.gpr.__r[m_last_decode_arm.op[REG_RD].value]; 1815 1816 if (m_last_decode_arm.instruction->code == ARM_INST_CBZ) 1817 { 1818 if (registerValue == 0) 1819 *nextPC = targetPC; 1820 } 1821 else 1822 { 1823 if (registerValue != 0) 1824 *nextPC = targetPC; 1825 } 1826 } 1827 else if (m_last_decode_arm.conditional) // Is the change conditional on flag results? 1828 { 1829 if (ConditionPassed(m_last_decode_arm.condition, cpsr)) // conditions match 1830 { 1831 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Condition matched!", __FUNCTION__); 1832 *nextPC = targetPC; 1833 } 1834 else 1835 { 1836 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Condition did not match!", __FUNCTION__); 1837 } 1838 } 1839 else 1840 { 1841 *nextPC = targetPC; 1842 } 1843 1844 // Refine nextPCIsThumb computation 1845 if (m_last_decode_arm.doesSwitchMode) 1846 { 1847 *nextPCIsThumb = !currentPCIsThumb; 1848 } 1849 else if (m_last_decode_arm.canSwitchMode) 1850 { 1851 // Legal to switch ARM <--> Thumb mode with this branch 1852 // dependent on bit[0] of targetPC 1853 *nextPCIsThumb = (*nextPC & 1u) != 0; 1854 } 1855 else 1856 { 1857 *nextPCIsThumb = currentPCIsThumb; 1858 } 1859 } 1860 1861 DNBLogThreadedIf(LOG_STEP, "%s: calculated nextPC=0x%8.8x (%s)", __FUNCTION__, *nextPC, *nextPCIsThumb ? "Thumb" : "ARM"); 1862} 1863 1864 1865arm_error_t 1866DNBArchMachARM::DecodeInstructionUsingDisassembler(nub_addr_t curr_pc, uint32_t curr_cpsr, arm_decoded_instruction_t *decodedInstruction, thumb_static_data_t *thumbStaticData, nub_addr_t *next_pc) 1867{ 1868 1869 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: pc=0x%8.8x, cpsr=0x%8.8x", __FUNCTION__, curr_pc, curr_cpsr); 1870 1871 const uint32_t isetstate_mask = MASK_CPSR_T | MASK_CPSR_J; 1872 const uint32_t curr_isetstate = curr_cpsr & isetstate_mask; 1873 uint32_t opcode32; 1874 nub_addr_t nextPC = curr_pc; 1875 arm_error_t decodeReturnCode = ARM_SUCCESS; 1876 1877 m_last_decode_pc = curr_pc; 1878 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: last_decode_pc=0x%8.8x", __FUNCTION__, m_last_decode_pc); 1879 1880 switch (curr_isetstate) { 1881 case 0x0: // ARM Instruction 1882 // Read the ARM opcode 1883 if (m_thread->Process()->Task().ReadMemory(curr_pc, 4, &opcode32) != 4) 1884 { 1885 DNBLogError("unable to read opcode bits 31:0 for an ARM opcode at 0x%8.8llx", (uint64_t)curr_pc); 1886 decodeReturnCode = ARM_ERROR; 1887 } 1888 else 1889 { 1890 nextPC += 4; 1891 decodeReturnCode = ArmDisassembler((uint64_t)curr_pc, opcode32, false, decodedInstruction, NULL, 0, NULL, 0); 1892 1893 if (decodeReturnCode != ARM_SUCCESS) 1894 DNBLogError("Unable to decode ARM instruction 0x%8.8x at 0x%8.8llx", opcode32, (uint64_t)curr_pc); 1895 } 1896 break; 1897 1898 case 0x20: // Thumb Instruction 1899 uint16_t opcode16; 1900 // Read the a 16 bit Thumb opcode 1901 if (m_thread->Process()->Task().ReadMemory(curr_pc, 2, &opcode16) != 2) 1902 { 1903 DNBLogError("unable to read opcode bits 15:0 for a thumb opcode at 0x%8.8llx", (uint64_t)curr_pc); 1904 decodeReturnCode = ARM_ERROR; 1905 } 1906 else 1907 { 1908 nextPC += 2; 1909 opcode32 = opcode16; 1910 1911 decodeReturnCode = ThumbDisassembler((uint64_t)curr_pc, opcode16, false, false, thumbStaticData, decodedInstruction, NULL, 0, NULL, 0); 1912 1913 switch (decodeReturnCode) { 1914 case ARM_SKIP: 1915 // 32 bit thumb opcode 1916 nextPC += 2; 1917 if (m_thread->Process()->Task().ReadMemory(curr_pc+2, 2, &opcode16) != 2) 1918 { 1919 DNBLogError("unable to read opcode bits 15:0 for a thumb opcode at 0x%8.8llx", (uint64_t)curr_pc+2); 1920 } 1921 else 1922 { 1923 opcode32 = (opcode32 << 16) | opcode16; 1924 1925 decodeReturnCode = ThumbDisassembler((uint64_t)(curr_pc+2), opcode16, false, false, thumbStaticData, decodedInstruction, NULL, 0, NULL, 0); 1926 1927 if (decodeReturnCode != ARM_SUCCESS) 1928 DNBLogError("Unable to decode 2nd half of Thumb instruction 0x%8.4hx at 0x%8.8llx", opcode16, (uint64_t)curr_pc+2); 1929 break; 1930 } 1931 break; 1932 1933 case ARM_SUCCESS: 1934 // 16 bit thumb opcode; at this point we are done decoding the opcode 1935 break; 1936 1937 default: 1938 DNBLogError("Unable to decode Thumb instruction 0x%8.4hx at 0x%8.8llx", opcode16, (uint64_t)curr_pc); 1939 decodeReturnCode = ARM_ERROR; 1940 break; 1941 } 1942 } 1943 break; 1944 1945 default: 1946 break; 1947 } 1948 1949 if (next_pc) 1950 *next_pc = nextPC; 1951 1952 return decodeReturnCode; 1953} 1954 1955#endif 1956 1957nub_bool_t 1958DNBArchMachARM::BreakpointHit (nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *baton) 1959{ 1960 nub_addr_t bkpt_pc = (nub_addr_t)baton; 1961 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s(pid = %i, tid = %4.4x, breakID = %u, baton = %p): Setting PC to 0x%8.8x", __FUNCTION__, pid, tid, breakID, baton, bkpt_pc); 1962 1963 DNBRegisterValue pc_value; 1964 DNBThreadGetRegisterValueByID (pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_PC, &pc_value); 1965 pc_value.value.uint32 = bkpt_pc; 1966 return DNBThreadSetRegisterValueByID (pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_PC, &pc_value); 1967} 1968 1969// Set the single step bit in the processor status register. 1970kern_return_t 1971DNBArchMachARM::SetSingleStepSoftwareBreakpoints() 1972{ 1973 DNBError err; 1974 1975#if defined (USE_ARM_DISASSEMBLER_FRAMEWORK) 1976 err = GetGPRState(false); 1977 1978 if (err.Fail()) 1979 { 1980 err.LogThreaded("%s: failed to read the GPR registers", __FUNCTION__); 1981 return err.Error(); 1982 } 1983 1984 nub_addr_t curr_pc = m_state.context.gpr.__pc; 1985 uint32_t curr_cpsr = m_state.context.gpr.__cpsr; 1986 nub_addr_t next_pc = curr_pc; 1987 1988 bool curr_pc_is_thumb = (m_state.context.gpr.__cpsr & 0x20) != 0; 1989 bool next_pc_is_thumb = curr_pc_is_thumb; 1990 1991 uint32_t curr_itstate = ((curr_cpsr & 0x6000000) >> 25) | ((curr_cpsr & 0xFC00) >> 8); 1992 bool inITBlock = (curr_itstate & 0xF) ? 1 : 0; 1993 bool lastInITBlock = ((curr_itstate & 0xF) == 0x8) ? 1 : 0; 1994 1995 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: curr_pc=0x%8.8x (%s), curr_itstate=0x%x, inITBlock=%d, lastInITBlock=%d", __FUNCTION__, curr_pc, curr_pc_is_thumb ? "Thumb" : "ARM", curr_itstate, inITBlock, lastInITBlock); 1996 1997 // If the instruction is not in the IT block, then decode using the Disassembler and compute next_pc 1998 if (!inITBlock) 1999 { 2000 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Decoding an instruction NOT in the IT block", __FUNCTION__); 2001 2002 arm_error_t decodeReturnCode = DecodeInstructionUsingDisassembler(curr_pc, curr_cpsr, &m_last_decode_arm, &m_last_decode_thumb, &next_pc); 2003 2004 if (decodeReturnCode != ARM_SUCCESS) 2005 { 2006 err = KERN_INVALID_ARGUMENT; 2007 DNBLogError("DNBArchMachARM::SetSingleStepSoftwareBreakpoints: Unable to disassemble instruction at 0x%8.8llx", (uint64_t)curr_pc); 2008 } 2009 } 2010 else 2011 { 2012 next_pc = curr_pc + ((m_last_decode_arm.thumb16b) ? 2 : 4); 2013 } 2014 2015 // Instruction is NOT in the IT block OR 2016 if (!inITBlock) 2017 { 2018 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: normal instruction", __FUNCTION__); 2019 EvaluateNextInstructionForSoftwareBreakpointSetup(curr_pc, m_state.context.gpr.__cpsr, curr_pc_is_thumb, &next_pc, &next_pc_is_thumb); 2020 } 2021 else if (inITBlock && !m_last_decode_arm.setsFlags) 2022 { 2023 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: IT instruction that doesn't set flags", __FUNCTION__); 2024 EvaluateNextInstructionForSoftwareBreakpointSetup(curr_pc, m_state.context.gpr.__cpsr, curr_pc_is_thumb, &next_pc, &next_pc_is_thumb); 2025 } 2026 else if (lastInITBlock && m_last_decode_arm.branch) 2027 { 2028 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: IT instruction which last in the IT block and is a branch", __FUNCTION__); 2029 EvaluateNextInstructionForSoftwareBreakpointSetup(curr_pc, m_state.context.gpr.__cpsr, curr_pc_is_thumb, &next_pc, &next_pc_is_thumb); 2030 } 2031 else 2032 { 2033 // Instruction is in IT block and can modify the CPSR flags 2034 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: IT instruction that sets flags", __FUNCTION__); 2035 2036 // NOTE: When this point of code is reached, the instruction at curr_pc has already been decoded 2037 // inside the function ThreadDidStop(). Therefore m_last_decode_arm, m_last_decode_thumb 2038 // reflect the decoded instruction at curr_pc 2039 2040 // If we find an instruction inside the IT block which will set/modify the condition flags (NZCV bits in CPSR), 2041 // we set breakpoints at all remaining instructions inside the IT block starting from the instruction immediately 2042 // following this one AND a breakpoint at the instruction immediately following the IT block. We do this because 2043 // we cannot determine the next_pc until the instruction at which we are currently stopped executes. Hence we 2044 // insert (m_last_decode_thumb.itBlockRemaining+1) 16-bit Thumb breakpoints at consecutive memory locations 2045 // starting at addrOfNextInstructionInITBlock. We record these breakpoints in class variable m_sw_single_step_itblock_break_id[], 2046 // and also record the total number of IT breakpoints set in the variable 'm_sw_single_step_itblock_break_count'. 2047 2048 // The instructions inside the IT block, which are replaced by the 16-bit Thumb breakpoints (opcode=0xDEFE) 2049 // instructions, can be either Thumb-16 or Thumb-32. When a Thumb-32 instruction (say, inst#1) is replaced Thumb 2050 // by a 16-bit breakpoint (OS only supports 16-bit breakpoints in Thumb mode and 32-bit breakpoints in ARM mode), the 2051 // breakpoint for the next instruction (say instr#2) is saved in the upper half of this Thumb-32 (instr#1) 2052 // instruction. Hence if the execution stops at Breakpoint2 corresponding to instr#2, the PC is offset by 16-bits. 2053 // We therefore have to keep track of PC of each instruction in the IT block that is being replaced with the 16-bit 2054 // Thumb breakpoint, to ensure that when the breakpoint is hit, the PC is adjusted to the correct value. We save 2055 // the actual PC corresponding to each instruction in the IT block by associating a call back with each breakpoint 2056 // we set and passing it as a baton. When the breakpoint hits and the callback routine is called, the routine 2057 // adjusts the PC based on the baton that is passed to it. 2058 2059 nub_addr_t addrOfNextInstructionInITBlock, pcInITBlock, nextPCInITBlock, bpAddressInITBlock; 2060 uint16_t opcode16; 2061 uint32_t opcode32; 2062 2063 addrOfNextInstructionInITBlock = (m_last_decode_arm.thumb16b) ? curr_pc + 2 : curr_pc + 4; 2064 2065 pcInITBlock = addrOfNextInstructionInITBlock; 2066 2067 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: itBlockRemaining=%d", __FUNCTION__, m_last_decode_thumb.itBlockRemaining); 2068 2069 m_sw_single_step_itblock_break_count = 0; 2070 for (int i = 0; i <= m_last_decode_thumb.itBlockRemaining; i++) 2071 { 2072 if (NUB_BREAK_ID_IS_VALID(m_sw_single_step_itblock_break_id[i])) 2073 { 2074 DNBLogError("FunctionProfiler::SetSingleStepSoftwareBreakpoints(): Array m_sw_single_step_itblock_break_id should not contain any valid breakpoint IDs at this point. But found a valid breakID=%d at index=%d", m_sw_single_step_itblock_break_id[i], i); 2075 } 2076 else 2077 { 2078 nextPCInITBlock = pcInITBlock; 2079 // Compute nextPCInITBlock based on opcode present at pcInITBlock 2080 if (m_thread->Process()->Task().ReadMemory(pcInITBlock, 2, &opcode16) == 2) 2081 { 2082 opcode32 = opcode16; 2083 nextPCInITBlock += 2; 2084 2085 // Check for 32 bit thumb opcode and read the upper 16 bits if needed 2086 if (((opcode32 & 0xE000) == 0xE000) && (opcode32 & 0x1800)) 2087 { 2088 // Adjust 'next_pc_in_itblock' to point to the default next Thumb instruction for 2089 // a 32 bit Thumb opcode 2090 // Read bits 31:16 of a 32 bit Thumb opcode 2091 if (m_thread->Process()->Task().ReadMemory(pcInITBlock+2, 2, &opcode16) == 2) 2092 { 2093 // 32 bit thumb opcode 2094 opcode32 = (opcode32 << 16) | opcode16; 2095 nextPCInITBlock += 2; 2096 } 2097 else 2098 { 2099 DNBLogError("FunctionProfiler::SetSingleStepSoftwareBreakpoints(): Unable to read opcode bits 31:16 for a 32 bit thumb opcode at pc=0x%8.8llx", (uint64_t)nextPCInITBlock); 2100 } 2101 } 2102 } 2103 else 2104 { 2105 DNBLogError("FunctionProfiler::SetSingleStepSoftwareBreakpoints(): Error reading 16-bit Thumb instruction at pc=0x%8.8x", nextPCInITBlock); 2106 } 2107 2108 2109 // Set breakpoint and associate a callback function with it 2110 bpAddressInITBlock = addrOfNextInstructionInITBlock + 2*i; 2111 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Setting IT breakpoint[%d] at address: 0x%8.8x", __FUNCTION__, i, bpAddressInITBlock); 2112 2113 m_sw_single_step_itblock_break_id[i] = m_thread->Process()->CreateBreakpoint(bpAddressInITBlock, 2, false, m_thread->ThreadID()); 2114 if (!NUB_BREAK_ID_IS_VALID(m_sw_single_step_itblock_break_id[i])) 2115 err = KERN_INVALID_ARGUMENT; 2116 else 2117 { 2118 DNBLogThreadedIf(LOG_STEP, "%s: Set IT breakpoint[%i]=%d set at 0x%8.8x for instruction at 0x%8.8x", __FUNCTION__, i, m_sw_single_step_itblock_break_id[i], bpAddressInITBlock, pcInITBlock); 2119 2120 // Set the breakpoint callback for these special IT breakpoints 2121 // so that if one of these breakpoints gets hit, it knows to 2122 // update the PC to the original address of the conditional 2123 // IT instruction. 2124 DNBBreakpointSetCallback(m_thread->ProcessID(), m_sw_single_step_itblock_break_id[i], DNBArchMachARM::BreakpointHit, (void*)pcInITBlock); 2125 m_sw_single_step_itblock_break_count++; 2126 } 2127 } 2128 2129 pcInITBlock = nextPCInITBlock; 2130 } 2131 2132 DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Set %u IT software single breakpoints.", __FUNCTION__, m_sw_single_step_itblock_break_count); 2133 2134 } 2135 2136 DNBLogThreadedIf(LOG_STEP, "%s: next_pc=0x%8.8x (%s)", __FUNCTION__, next_pc, next_pc_is_thumb ? "Thumb" : "ARM"); 2137 2138 if (next_pc & 0x1) 2139 { 2140 assert(next_pc_is_thumb); 2141 } 2142 2143 if (next_pc_is_thumb) 2144 { 2145 next_pc &= ~0x1; 2146 } 2147 else 2148 { 2149 assert((next_pc & 0x3) == 0); 2150 } 2151 2152 if (!inITBlock || (inITBlock && !m_last_decode_arm.setsFlags) || (lastInITBlock && m_last_decode_arm.branch)) 2153 { 2154 err = KERN_SUCCESS; 2155 2156#if defined DNB_ARCH_MACH_ARM_DEBUG_SW_STEP 2157 m_sw_single_step_next_pc = next_pc; 2158 if (next_pc_is_thumb) 2159 m_sw_single_step_next_pc |= 1; // Set bit zero if the next PC is expected to be Thumb 2160#else 2161 const DNBBreakpoint *bp = m_thread->Process()->Breakpoints().FindByAddress(next_pc); 2162 2163 if (bp == NULL) 2164 { 2165 m_sw_single_step_break_id = m_thread->Process()->CreateBreakpoint(next_pc, next_pc_is_thumb ? 2 : 4, false, m_thread->ThreadID()); 2166 if (!NUB_BREAK_ID_IS_VALID(m_sw_single_step_break_id)) 2167 err = KERN_INVALID_ARGUMENT; 2168 DNBLogThreadedIf(LOG_STEP, "%s: software single step breakpoint with breakID=%d set at 0x%8.8x", __FUNCTION__, m_sw_single_step_break_id, next_pc); 2169 } 2170#endif 2171 } 2172#else 2173 err.LogThreaded("%s: ARMDisassembler.framework support is disabled", __FUNCTION__); 2174#endif 2175 return err.Error(); 2176} 2177 2178uint32_t 2179DNBArchMachARM::NumSupportedHardwareBreakpoints() 2180{ 2181 // Set the init value to something that will let us know that we need to 2182 // autodetect how many breakpoints are supported dynamically... 2183 static uint32_t g_num_supported_hw_breakpoints = UINT_MAX; 2184 if (g_num_supported_hw_breakpoints == UINT_MAX) 2185 { 2186 // Set this to zero in case we can't tell if there are any HW breakpoints 2187 g_num_supported_hw_breakpoints = 0; 2188 2189 size_t len; 2190 uint32_t n = 0; 2191 len = sizeof (n); 2192 if (::sysctlbyname("hw.optional.breakpoint", &n, &len, NULL, 0) == 0) 2193 { 2194 g_num_supported_hw_breakpoints = n; 2195 DNBLogThreadedIf(LOG_THREAD, "hw.optional.breakpoint=%u", n); 2196 } 2197 else 2198 { 2199 // Read the DBGDIDR to get the number of available hardware breakpoints 2200 // However, in some of our current armv7 processors, hardware 2201 // breakpoints/watchpoints were not properly connected. So detect those 2202 // cases using a field in a sysctl. For now we are using "hw.cpusubtype" 2203 // field to distinguish CPU architectures. This is a hack until we can 2204 // get <rdar://problem/6372672> fixed, at which point we will switch to 2205 // using a different sysctl string that will tell us how many BRPs 2206 // are available to us directly without having to read DBGDIDR. 2207 uint32_t register_DBGDIDR; 2208 2209 asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR)); 2210 uint32_t numBRPs = bits(register_DBGDIDR, 27, 24); 2211 // Zero is reserved for the BRP count, so don't increment it if it is zero 2212 if (numBRPs > 0) 2213 numBRPs++; 2214 DNBLogThreadedIf(LOG_THREAD, "DBGDIDR=0x%8.8x (number BRP pairs = %u)", register_DBGDIDR, numBRPs); 2215 2216 if (numBRPs > 0) 2217 { 2218 uint32_t cpusubtype; 2219 len = sizeof(cpusubtype); 2220 // TODO: remove this hack and change to using hw.optional.xx when implmented 2221 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0) 2222 { 2223 DNBLogThreadedIf(LOG_THREAD, "hw.cpusubtype=%d", cpusubtype); 2224 if (cpusubtype == CPU_SUBTYPE_ARM_V7) 2225 DNBLogThreadedIf(LOG_THREAD, "Hardware breakpoints disabled for armv7 (rdar://problem/6372672)"); 2226 else 2227 g_num_supported_hw_breakpoints = numBRPs; 2228 } 2229 } 2230 } 2231 } 2232 return g_num_supported_hw_breakpoints; 2233} 2234 2235 2236uint32_t 2237DNBArchMachARM::NumSupportedHardwareWatchpoints() 2238{ 2239 // Set the init value to something that will let us know that we need to 2240 // autodetect how many watchpoints are supported dynamically... 2241 static uint32_t g_num_supported_hw_watchpoints = UINT_MAX; 2242 if (g_num_supported_hw_watchpoints == UINT_MAX) 2243 { 2244 // Set this to zero in case we can't tell if there are any HW breakpoints 2245 g_num_supported_hw_watchpoints = 0; 2246 2247 2248 size_t len; 2249 uint32_t n = 0; 2250 len = sizeof (n); 2251 if (::sysctlbyname("hw.optional.watchpoint", &n, &len, NULL, 0) == 0) 2252 { 2253 g_num_supported_hw_watchpoints = n; 2254 DNBLogThreadedIf(LOG_THREAD, "hw.optional.watchpoint=%u", n); 2255 } 2256 else 2257 { 2258 // Read the DBGDIDR to get the number of available hardware breakpoints 2259 // However, in some of our current armv7 processors, hardware 2260 // breakpoints/watchpoints were not properly connected. So detect those 2261 // cases using a field in a sysctl. For now we are using "hw.cpusubtype" 2262 // field to distinguish CPU architectures. This is a hack until we can 2263 // get <rdar://problem/6372672> fixed, at which point we will switch to 2264 // using a different sysctl string that will tell us how many WRPs 2265 // are available to us directly without having to read DBGDIDR. 2266 2267 uint32_t register_DBGDIDR; 2268 asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR)); 2269 uint32_t numWRPs = bits(register_DBGDIDR, 31, 28) + 1; 2270 DNBLogThreadedIf(LOG_THREAD, "DBGDIDR=0x%8.8x (number WRP pairs = %u)", register_DBGDIDR, numWRPs); 2271 2272 if (numWRPs > 0) 2273 { 2274 uint32_t cpusubtype; 2275 size_t len; 2276 len = sizeof(cpusubtype); 2277 // TODO: remove this hack and change to using hw.optional.xx when implmented 2278 if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0) 2279 { 2280 DNBLogThreadedIf(LOG_THREAD, "hw.cpusubtype=0x%d", cpusubtype); 2281 2282 if (cpusubtype == CPU_SUBTYPE_ARM_V7) 2283 DNBLogThreadedIf(LOG_THREAD, "Hardware watchpoints disabled for armv7 (rdar://problem/6372672)"); 2284 else 2285 g_num_supported_hw_watchpoints = numWRPs; 2286 } 2287 } 2288 } 2289 } 2290 return g_num_supported_hw_watchpoints; 2291} 2292 2293 2294uint32_t 2295DNBArchMachARM::EnableHardwareBreakpoint (nub_addr_t addr, nub_size_t size) 2296{ 2297 // Make sure our address isn't bogus 2298 if (addr & 1) 2299 return INVALID_NUB_HW_INDEX; 2300 2301 kern_return_t kret = GetDBGState(false); 2302 2303 if (kret == KERN_SUCCESS) 2304 { 2305 const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints(); 2306 uint32_t i; 2307 for (i=0; i<num_hw_breakpoints; ++i) 2308 { 2309 if ((m_state.dbg.__bcr[i] & BCR_ENABLE) == 0) 2310 break; // We found an available hw breakpoint slot (in i) 2311 } 2312 2313 // See if we found an available hw breakpoint slot above 2314 if (i < num_hw_breakpoints) 2315 { 2316 // Make sure bits 1:0 are clear in our address 2317 m_state.dbg.__bvr[i] = addr & ~((nub_addr_t)3); 2318 2319 if (size == 2 || addr & 2) 2320 { 2321 uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1; 2322 2323 // We have a thumb breakpoint 2324 // We have an ARM breakpoint 2325 m_state.dbg.__bcr[i] = BCR_M_IMVA_MATCH | // Stop on address mismatch 2326 byte_addr_select | // Set the correct byte address select so we only trigger on the correct opcode 2327 S_USER | // Which modes should this breakpoint stop in? 2328 BCR_ENABLE; // Enable this hardware breakpoint 2329 DNBLogThreadedIf (LOG_BREAKPOINTS, "DNBArchMachARM::EnableHardwareBreakpoint( addr = 0x%8.8llx, size = %zu ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (Thumb)", 2330 (uint64_t)addr, 2331 size, 2332 i, 2333 i, 2334 m_state.dbg.__bvr[i], 2335 m_state.dbg.__bcr[i]); 2336 } 2337 else if (size == 4) 2338 { 2339 // We have an ARM breakpoint 2340 m_state.dbg.__bcr[i] = BCR_M_IMVA_MATCH | // Stop on address mismatch 2341 BAS_IMVA_ALL | // Stop on any of the four bytes following the IMVA 2342 S_USER | // Which modes should this breakpoint stop in? 2343 BCR_ENABLE; // Enable this hardware breakpoint 2344 DNBLogThreadedIf (LOG_BREAKPOINTS, "DNBArchMachARM::EnableHardwareBreakpoint( addr = 0x%8.8llx, size = %zu ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (ARM)", 2345 (uint64_t)addr, 2346 size, 2347 i, 2348 i, 2349 m_state.dbg.__bvr[i], 2350 m_state.dbg.__bcr[i]); 2351 } 2352 2353 kret = SetDBGState(); 2354 DNBLogThreadedIf(LOG_BREAKPOINTS, "DNBArchMachARM::EnableHardwareBreakpoint() SetDBGState() => 0x%8.8x.", kret); 2355 2356 if (kret == KERN_SUCCESS) 2357 return i; 2358 } 2359 else 2360 { 2361 DNBLogThreadedIf (LOG_BREAKPOINTS, "DNBArchMachARM::EnableHardwareBreakpoint(addr = 0x%8.8llx, size = %zu) => all hardware breakpoint resources are being used.", (uint64_t)addr, size); 2362 } 2363 } 2364 2365 return INVALID_NUB_HW_INDEX; 2366} 2367 2368bool 2369DNBArchMachARM::DisableHardwareBreakpoint (uint32_t hw_index) 2370{ 2371 kern_return_t kret = GetDBGState(false); 2372 2373 const uint32_t num_hw_points = NumSupportedHardwareBreakpoints(); 2374 if (kret == KERN_SUCCESS) 2375 { 2376 if (hw_index < num_hw_points) 2377 { 2378 m_state.dbg.__bcr[hw_index] = 0; 2379 DNBLogThreadedIf(LOG_BREAKPOINTS, "DNBArchMachARM::SetHardwareBreakpoint( %u ) - BVR%u = 0x%8.8x BCR%u = 0x%8.8x", 2380 hw_index, 2381 hw_index, 2382 m_state.dbg.__bvr[hw_index], 2383 hw_index, 2384 m_state.dbg.__bcr[hw_index]); 2385 2386 kret = SetDBGState(); 2387 2388 if (kret == KERN_SUCCESS) 2389 return true; 2390 } 2391 } 2392 return false; 2393} 2394 2395// This stores the lo->hi mappings. It's safe to initialize to all 0's 2396// since hi > lo and therefore LoHi[i] cannot be 0. 2397static uint32_t LoHi[16] = { 0 }; 2398 2399uint32_t 2400DNBArchMachARM::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write) 2401{ 2402 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint(addr = 0x%8.8llx, size = %zu, read = %u, write = %u)", (uint64_t)addr, size, read, write); 2403 2404 const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); 2405 2406 // Can't watch zero bytes 2407 if (size == 0) 2408 return INVALID_NUB_HW_INDEX; 2409 2410 // We must watch for either read or write 2411 if (read == false && write == false) 2412 return INVALID_NUB_HW_INDEX; 2413 2414 // Divide-and-conquer for size == 8. 2415 if (size == 8) 2416 { 2417 uint32_t lo = EnableHardwareWatchpoint(addr, 4, read, write); 2418 if (lo == INVALID_NUB_HW_INDEX) 2419 return INVALID_NUB_HW_INDEX; 2420 uint32_t hi = EnableHardwareWatchpoint(addr+4, 4, read, write); 2421 if (hi == INVALID_NUB_HW_INDEX) 2422 { 2423 DisableHardwareWatchpoint(lo); 2424 return INVALID_NUB_HW_INDEX; 2425 } 2426 // Tag thsi lo->hi mapping in our database. 2427 LoHi[lo] = hi; 2428 return lo; 2429 } 2430 2431 // Otherwise, can't watch more than 4 bytes per WVR/WCR pair 2432 if (size > 4) 2433 return INVALID_NUB_HW_INDEX; 2434 2435 // We can only watch up to four bytes that follow a 4 byte aligned address 2436 // per watchpoint register pair. Since we can only watch until the next 4 2437 // byte boundary, we need to make sure we can properly encode this. 2438 2439 // addr_word_offset = addr % 4, i.e, is in set([0, 1, 2, 3]) 2440 // 2441 // +---+---+---+---+ 2442 // | 0 | 1 | 2 | 3 | 2443 // +---+---+---+---+ 2444 // ^ 2445 // | 2446 // word address (4-byte aligned) = addr & 0xFFFFFFFC => goes into WVR 2447 // 2448 // examples: 2449 // 1. addr_word_offset = 1, size = 1 to watch a uint_8 => byte_mask = (0b0001 << 1) = 0b0010 2450 // 2. addr_word_offset = 2, size = 2 to watch a uint_16 => byte_mask = (0b0011 << 2) = 0b1100 2451 // 2452 // where byte_mask goes into WCR[8:5] 2453 2454 uint32_t addr_word_offset = addr % 4; 2455 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset); 2456 2457 uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset; 2458 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask); 2459 if (byte_mask > 0xfu) 2460 return INVALID_NUB_HW_INDEX; 2461 2462 // Read the debug state 2463 kern_return_t kret = GetDBGState(false); 2464 2465 if (kret == KERN_SUCCESS) 2466 { 2467 // Check to make sure we have the needed hardware support 2468 uint32_t i = 0; 2469 2470 for (i=0; i<num_hw_watchpoints; ++i) 2471 { 2472 if ((m_state.dbg.__wcr[i] & WCR_ENABLE) == 0) 2473 break; // We found an available hw watchpoint slot (in i) 2474 } 2475 2476 // See if we found an available hw watchpoint slot above 2477 if (i < num_hw_watchpoints) 2478 { 2479 //DumpDBGState(m_state.dbg); 2480 2481 // Make the byte_mask into a valid Byte Address Select mask 2482 uint32_t byte_address_select = byte_mask << 5; 2483 // Make sure bits 1:0 are clear in our address 2484 m_state.dbg.__wvr[i] = addr & ~((nub_addr_t)3); // DVA (Data Virtual Address) 2485 m_state.dbg.__wcr[i] = byte_address_select | // Which bytes that follow the DVA that we will watch 2486 S_USER | // Stop only in user mode 2487 (read ? WCR_LOAD : 0) | // Stop on read access? 2488 (write ? WCR_STORE : 0) | // Stop on write access? 2489 WCR_ENABLE; // Enable this watchpoint; 2490 2491 kret = SetDBGState(); 2492 //DumpDBGState(m_state.dbg); 2493 2494 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() SetDBGState() => 0x%8.8x.", kret); 2495 2496 if (kret == KERN_SUCCESS) 2497 return i; 2498 } 2499 else 2500 { 2501 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints); 2502 } 2503 } 2504 return INVALID_NUB_HW_INDEX; 2505} 2506 2507bool 2508DNBArchMachARM::EnableHardwareWatchpoint0 (uint32_t hw_index, bool Delegate) 2509{ 2510 kern_return_t kret = GetDBGState(false); 2511 if (kret != KERN_SUCCESS) 2512 return false; 2513 2514 const uint32_t num_hw_points = NumSupportedHardwareWatchpoints(); 2515 if (hw_index >= num_hw_points) 2516 return false; 2517 2518 if (Delegate && LoHi[hw_index]) { 2519 // Enable lo and hi watchpoint hardware indexes. 2520 return EnableHardwareWatchpoint0(hw_index, false) && 2521 EnableHardwareWatchpoint0(LoHi[hw_index], false); 2522 } 2523 2524 m_state.dbg.__wcr[hw_index] |= (nub_addr_t)WCR_ENABLE; 2525 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x WCR%u = 0x%8.8x", 2526 hw_index, 2527 hw_index, 2528 m_state.dbg.__wvr[hw_index], 2529 hw_index, 2530 m_state.dbg.__wcr[hw_index]); 2531 2532 kret = SetDBGState(); 2533 2534 return (kret == KERN_SUCCESS); 2535} 2536 2537bool 2538DNBArchMachARM::DisableHardwareWatchpoint (uint32_t hw_index) 2539{ 2540 return DisableHardwareWatchpoint0(hw_index, true); 2541} 2542bool 2543DNBArchMachARM::DisableHardwareWatchpoint0 (uint32_t hw_index, bool Delegate) 2544{ 2545 kern_return_t kret = GetDBGState(false); 2546 if (kret != KERN_SUCCESS) 2547 return false; 2548 2549 const uint32_t num_hw_points = NumSupportedHardwareWatchpoints(); 2550 if (hw_index >= num_hw_points) 2551 return false; 2552 2553 if (Delegate && LoHi[hw_index]) { 2554 // Disable lo and hi watchpoint hardware indexes. 2555 return DisableHardwareWatchpoint0(hw_index, false) && 2556 DisableHardwareWatchpoint0(LoHi[hw_index], false); 2557 } 2558 2559 m_state.dbg.__wcr[hw_index] &= ~((nub_addr_t)WCR_ENABLE); 2560 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::DisableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x WCR%u = 0x%8.8x", 2561 hw_index, 2562 hw_index, 2563 m_state.dbg.__wvr[hw_index], 2564 hw_index, 2565 m_state.dbg.__wcr[hw_index]); 2566 2567 kret = SetDBGState(); 2568 2569 return (kret == KERN_SUCCESS); 2570} 2571 2572// {0} -> __bvr[16], {0} -> __bcr[16], {0} --> __wvr[16], {0} -> __wcr{16} 2573DNBArchMachARM::DBG DNBArchMachARM::Global_Debug_State = {{0},{0},{0},{0}}; 2574bool DNBArchMachARM::Valid_Global_Debug_State = false; 2575 2576// Use this callback from MachThread, which in turn was called from MachThreadList, to update 2577// the global view of the hardware watchpoint state, so that when new thread comes along, they 2578// get to inherit the existing hardware watchpoint state. 2579void 2580DNBArchMachARM::HardwareWatchpointStateChanged () 2581{ 2582 Global_Debug_State = m_state.dbg; 2583 Valid_Global_Debug_State = true; 2584} 2585 2586// Returns -1 if the trailing bit patterns are not one of: 2587// { 0b???1, 0b??10, 0b?100, 0b1000 }. 2588static inline 2589int32_t 2590LowestBitSet(uint32_t val) 2591{ 2592 for (unsigned i = 0; i < 4; ++i) { 2593 if (bit(val, i)) 2594 return i; 2595 } 2596 return -1; 2597} 2598 2599// Iterate through the debug registers; return the index of the first watchpoint whose address matches. 2600// As a side effect, the starting address as understood by the debugger is returned which could be 2601// different from 'addr' passed as an in/out argument. 2602uint32_t 2603DNBArchMachARM::GetHardwareWatchpointHit(nub_addr_t &addr) 2604{ 2605 // Read the debug state 2606 kern_return_t kret = GetDBGState(true); 2607 //DumpDBGState(m_state.dbg); 2608 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::GetHardwareWatchpointHit() GetDBGState() => 0x%8.8x.", kret); 2609 DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::GetHardwareWatchpointHit() addr = 0x%llx", (uint64_t)addr); 2610 2611 // This is the watchpoint value to match against, i.e., word address. 2612 nub_addr_t wp_val = addr & ~((nub_addr_t)3); 2613 if (kret == KERN_SUCCESS) 2614 { 2615 DBG &debug_state = m_state.dbg; 2616 uint32_t i, num = NumSupportedHardwareWatchpoints(); 2617 for (i = 0; i < num; ++i) 2618 { 2619 nub_addr_t wp_addr = GetWatchAddress(debug_state, i); 2620 DNBLogThreadedIf(LOG_WATCHPOINTS, 2621 "DNBArchMachARM::GetHardwareWatchpointHit() slot: %u (addr = 0x%llx).", 2622 i, (uint64_t)wp_addr); 2623 if (wp_val == wp_addr) { 2624 uint32_t byte_mask = bits(debug_state.__wcr[i], 8, 5); 2625 2626 // Sanity check the byte_mask, first. 2627 if (LowestBitSet(byte_mask) < 0) 2628 continue; 2629 2630 // Compute the starting address (from the point of view of the debugger). 2631 addr = wp_addr + LowestBitSet(byte_mask); 2632 return i; 2633 } 2634 } 2635 } 2636 return INVALID_NUB_HW_INDEX; 2637} 2638 2639// ThreadWillResume() calls this to clear bits[5:2] (Method of entry bits) of 2640// the Debug Status and Control Register (DSCR). 2641// 2642// b0010 = a watchpoint occurred 2643// b0000 is the reset value 2644void 2645DNBArchMachARM::ClearWatchpointOccurred() 2646{ 2647 uint32_t register_DBGDSCR; 2648 asm("mrc p14, 0, %0, c0, c1, 0" : "=r" (register_DBGDSCR)); 2649 if (bits(register_DBGDSCR, 5, 2) == WATCHPOINT_OCCURRED) 2650 { 2651 uint32_t mask = ~(0xF << 2); 2652 register_DBGDSCR &= mask; 2653 asm("mcr p14, 0, %0, c0, c1, 0" : "=r" (register_DBGDSCR)); 2654 } 2655 return; 2656} 2657 2658// NotifyException() calls this to double check that a watchpoint has occurred 2659// by inspecting the bits[5:2] field of the Debug Status and Control Register 2660// (DSCR). 2661// 2662// b0010 = a watchpoint occurred 2663bool 2664DNBArchMachARM::HasWatchpointOccurred() 2665{ 2666 uint32_t register_DBGDSCR; 2667 asm("mrc p14, 0, %0, c0, c1, 0" : "=r" (register_DBGDSCR)); 2668 return (bits(register_DBGDSCR, 5, 2) == WATCHPOINT_OCCURRED); 2669} 2670 2671bool 2672DNBArchMachARM::IsWatchpointEnabled(const DBG &debug_state, uint32_t hw_index) 2673{ 2674 // Watchpoint Control Registers, bitfield definitions 2675 // ... 2676 // Bits Value Description 2677 // [0] 0 Watchpoint disabled 2678 // 1 Watchpoint enabled. 2679 return (debug_state.__wcr[hw_index] & 1u); 2680} 2681 2682nub_addr_t 2683DNBArchMachARM::GetWatchAddress(const DBG &debug_state, uint32_t hw_index) 2684{ 2685 // Watchpoint Value Registers, bitfield definitions 2686 // Bits Description 2687 // [31:2] Watchpoint value (word address, i.e., 4-byte aligned) 2688 // [1:0] RAZ/SBZP 2689 return bits(debug_state.__wvr[hw_index], 31, 0); 2690} 2691 2692//---------------------------------------------------------------------- 2693// Register information defintions for 32 bit ARMV6. 2694//---------------------------------------------------------------------- 2695enum gpr_regnums 2696{ 2697 gpr_r0 = 0, 2698 gpr_r1, 2699 gpr_r2, 2700 gpr_r3, 2701 gpr_r4, 2702 gpr_r5, 2703 gpr_r6, 2704 gpr_r7, 2705 gpr_r8, 2706 gpr_r9, 2707 gpr_r10, 2708 gpr_r11, 2709 gpr_r12, 2710 gpr_sp, 2711 gpr_lr, 2712 gpr_pc, 2713 gpr_cpsr 2714}; 2715 2716enum 2717{ 2718 vfp_s0 = 0, 2719 vfp_s1, 2720 vfp_s2, 2721 vfp_s3, 2722 vfp_s4, 2723 vfp_s5, 2724 vfp_s6, 2725 vfp_s7, 2726 vfp_s8, 2727 vfp_s9, 2728 vfp_s10, 2729 vfp_s11, 2730 vfp_s12, 2731 vfp_s13, 2732 vfp_s14, 2733 vfp_s15, 2734 vfp_s16, 2735 vfp_s17, 2736 vfp_s18, 2737 vfp_s19, 2738 vfp_s20, 2739 vfp_s21, 2740 vfp_s22, 2741 vfp_s23, 2742 vfp_s24, 2743 vfp_s25, 2744 vfp_s26, 2745 vfp_s27, 2746 vfp_s28, 2747 vfp_s29, 2748 vfp_s30, 2749 vfp_s31, 2750 vfp_d0, 2751 vfp_d1, 2752 vfp_d2, 2753 vfp_d3, 2754 vfp_d4, 2755 vfp_d5, 2756 vfp_d6, 2757 vfp_d7, 2758 vfp_d8, 2759 vfp_d9, 2760 vfp_d10, 2761 vfp_d11, 2762 vfp_d12, 2763 vfp_d13, 2764 vfp_d14, 2765 vfp_d15, 2766 vfp_d16, 2767 vfp_d17, 2768 vfp_d18, 2769 vfp_d19, 2770 vfp_d20, 2771 vfp_d21, 2772 vfp_d22, 2773 vfp_d23, 2774 vfp_d24, 2775 vfp_d25, 2776 vfp_d26, 2777 vfp_d27, 2778 vfp_d28, 2779 vfp_d29, 2780 vfp_d30, 2781 vfp_d31, 2782 vfp_fpscr 2783}; 2784 2785enum 2786{ 2787 exc_exception, 2788 exc_fsr, 2789 exc_far, 2790}; 2791 2792enum 2793{ 2794 gdb_r0 = 0, 2795 gdb_r1, 2796 gdb_r2, 2797 gdb_r3, 2798 gdb_r4, 2799 gdb_r5, 2800 gdb_r6, 2801 gdb_r7, 2802 gdb_r8, 2803 gdb_r9, 2804 gdb_r10, 2805 gdb_r11, 2806 gdb_r12, 2807 gdb_sp, 2808 gdb_lr, 2809 gdb_pc, 2810 gdb_f0, 2811 gdb_f1, 2812 gdb_f2, 2813 gdb_f3, 2814 gdb_f4, 2815 gdb_f5, 2816 gdb_f6, 2817 gdb_f7, 2818 gdb_f8, 2819 gdb_cpsr, 2820 gdb_s0, 2821 gdb_s1, 2822 gdb_s2, 2823 gdb_s3, 2824 gdb_s4, 2825 gdb_s5, 2826 gdb_s6, 2827 gdb_s7, 2828 gdb_s8, 2829 gdb_s9, 2830 gdb_s10, 2831 gdb_s11, 2832 gdb_s12, 2833 gdb_s13, 2834 gdb_s14, 2835 gdb_s15, 2836 gdb_s16, 2837 gdb_s17, 2838 gdb_s18, 2839 gdb_s19, 2840 gdb_s20, 2841 gdb_s21, 2842 gdb_s22, 2843 gdb_s23, 2844 gdb_s24, 2845 gdb_s25, 2846 gdb_s26, 2847 gdb_s27, 2848 gdb_s28, 2849 gdb_s29, 2850 gdb_s30, 2851 gdb_s31, 2852 gdb_fpscr, 2853 gdb_d0, 2854 gdb_d1, 2855 gdb_d2, 2856 gdb_d3, 2857 gdb_d4, 2858 gdb_d5, 2859 gdb_d6, 2860 gdb_d7, 2861 gdb_d8, 2862 gdb_d9, 2863 gdb_d10, 2864 gdb_d11, 2865 gdb_d12, 2866 gdb_d13, 2867 gdb_d14, 2868 gdb_d15 2869}; 2870 2871#define GPR_OFFSET_IDX(idx) (offsetof (DNBArchMachARM::GPR, __r[idx])) 2872#define GPR_OFFSET_NAME(reg) (offsetof (DNBArchMachARM::GPR, __##reg)) 2873#define VFP_S_OFFSET_IDX(idx) (offsetof (DNBArchMachARM::FPU, __r[(idx)]) + offsetof (DNBArchMachARM::Context, vfp)) 2874#define VFP_D_OFFSET_IDX(idx) (VFP_S_OFFSET_IDX ((idx) * 2)) 2875#define VFP_OFFSET_NAME(reg) (offsetof (DNBArchMachARM::FPU, __##reg) + offsetof (DNBArchMachARM::Context, vfp)) 2876#define EXC_OFFSET(reg) (offsetof (DNBArchMachARM::EXC, __##reg) + offsetof (DNBArchMachARM::Context, exc)) 2877 2878// These macros will auto define the register name, alt name, register size, 2879// register offset, encoding, format and native register. This ensures that 2880// the register state structures are defined correctly and have the correct 2881// sizes and offsets. 2882#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, gdb_##reg } 2883#define DEFINE_GPR_NAME(reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 4, GPR_OFFSET_NAME(reg), gcc_##reg, dwarf_##reg, gen, gdb_##reg } 2884//#define FLOAT_FORMAT Float 2885#define FLOAT_FORMAT Hex 2886#define DEFINE_VFP_S_IDX(idx) { e_regSetVFP, vfp_s##idx, "s" #idx, NULL, IEEE754, FLOAT_FORMAT, 4, VFP_S_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_s##idx, INVALID_NUB_REGNUM, gdb_s##idx } 2887//#define DEFINE_VFP_D_IDX(idx) { e_regSetVFP, vfp_d##idx, "d" #idx, NULL, IEEE754, Float, 8, VFP_D_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_d##idx, INVALID_NUB_REGNUM, gdb_d##idx } 2888#define DEFINE_VFP_D_IDX(idx) { e_regSetVFP, vfp_d##idx, "d" #idx, NULL, IEEE754, FLOAT_FORMAT, 8, VFP_D_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_d##idx, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM } 2889 2890// General purpose registers 2891const DNBRegisterInfo 2892DNBArchMachARM::g_gpr_registers[] = 2893{ 2894 DEFINE_GPR_IDX ( 0, r0,"arg1", GENERIC_REGNUM_ARG1 ), 2895 DEFINE_GPR_IDX ( 1, r1,"arg2", GENERIC_REGNUM_ARG2 ), 2896 DEFINE_GPR_IDX ( 2, r2,"arg3", GENERIC_REGNUM_ARG3 ), 2897 DEFINE_GPR_IDX ( 3, r3,"arg4", GENERIC_REGNUM_ARG4 ), 2898 DEFINE_GPR_IDX ( 4, r4, NULL, INVALID_NUB_REGNUM ), 2899 DEFINE_GPR_IDX ( 5, r5, NULL, INVALID_NUB_REGNUM ), 2900 DEFINE_GPR_IDX ( 6, r6, NULL, INVALID_NUB_REGNUM ), 2901 DEFINE_GPR_IDX ( 7, r7, "fp", GENERIC_REGNUM_FP ), 2902 DEFINE_GPR_IDX ( 8, r8, NULL, INVALID_NUB_REGNUM ), 2903 DEFINE_GPR_IDX ( 9, r9, NULL, INVALID_NUB_REGNUM ), 2904 DEFINE_GPR_IDX (10, r10, NULL, INVALID_NUB_REGNUM ), 2905 DEFINE_GPR_IDX (11, r11, NULL, INVALID_NUB_REGNUM ), 2906 DEFINE_GPR_IDX (12, r12, NULL, INVALID_NUB_REGNUM ), 2907 DEFINE_GPR_NAME (sp, "r13", GENERIC_REGNUM_SP ), 2908 DEFINE_GPR_NAME (lr, "r14", GENERIC_REGNUM_RA ), 2909 DEFINE_GPR_NAME (pc, "r15", GENERIC_REGNUM_PC ), 2910 DEFINE_GPR_NAME (cpsr, "flags", GENERIC_REGNUM_FLAGS ) 2911}; 2912 2913// Floating point registers 2914const DNBRegisterInfo 2915DNBArchMachARM::g_vfp_registers[] = 2916{ 2917 DEFINE_VFP_S_IDX ( 0), 2918 DEFINE_VFP_S_IDX ( 1), 2919 DEFINE_VFP_S_IDX ( 2), 2920 DEFINE_VFP_S_IDX ( 3), 2921 DEFINE_VFP_S_IDX ( 4), 2922 DEFINE_VFP_S_IDX ( 5), 2923 DEFINE_VFP_S_IDX ( 6), 2924 DEFINE_VFP_S_IDX ( 7), 2925 DEFINE_VFP_S_IDX ( 8), 2926 DEFINE_VFP_S_IDX ( 9), 2927 DEFINE_VFP_S_IDX (10), 2928 DEFINE_VFP_S_IDX (11), 2929 DEFINE_VFP_S_IDX (12), 2930 DEFINE_VFP_S_IDX (13), 2931 DEFINE_VFP_S_IDX (14), 2932 DEFINE_VFP_S_IDX (15), 2933 DEFINE_VFP_S_IDX (16), 2934 DEFINE_VFP_S_IDX (17), 2935 DEFINE_VFP_S_IDX (18), 2936 DEFINE_VFP_S_IDX (19), 2937 DEFINE_VFP_S_IDX (20), 2938 DEFINE_VFP_S_IDX (21), 2939 DEFINE_VFP_S_IDX (22), 2940 DEFINE_VFP_S_IDX (23), 2941 DEFINE_VFP_S_IDX (24), 2942 DEFINE_VFP_S_IDX (25), 2943 DEFINE_VFP_S_IDX (26), 2944 DEFINE_VFP_S_IDX (27), 2945 DEFINE_VFP_S_IDX (28), 2946 DEFINE_VFP_S_IDX (29), 2947 DEFINE_VFP_S_IDX (30), 2948 DEFINE_VFP_S_IDX (31), 2949 DEFINE_VFP_D_IDX (0), 2950 DEFINE_VFP_D_IDX (1), 2951 DEFINE_VFP_D_IDX (2), 2952 DEFINE_VFP_D_IDX (3), 2953 DEFINE_VFP_D_IDX (4), 2954 DEFINE_VFP_D_IDX (5), 2955 DEFINE_VFP_D_IDX (6), 2956 DEFINE_VFP_D_IDX (7), 2957 DEFINE_VFP_D_IDX (8), 2958 DEFINE_VFP_D_IDX (9), 2959 DEFINE_VFP_D_IDX (10), 2960 DEFINE_VFP_D_IDX (11), 2961 DEFINE_VFP_D_IDX (12), 2962 DEFINE_VFP_D_IDX (13), 2963 DEFINE_VFP_D_IDX (14), 2964 DEFINE_VFP_D_IDX (15), 2965 DEFINE_VFP_D_IDX (16), 2966 DEFINE_VFP_D_IDX (17), 2967 DEFINE_VFP_D_IDX (18), 2968 DEFINE_VFP_D_IDX (19), 2969 DEFINE_VFP_D_IDX (20), 2970 DEFINE_VFP_D_IDX (21), 2971 DEFINE_VFP_D_IDX (22), 2972 DEFINE_VFP_D_IDX (23), 2973 DEFINE_VFP_D_IDX (24), 2974 DEFINE_VFP_D_IDX (25), 2975 DEFINE_VFP_D_IDX (26), 2976 DEFINE_VFP_D_IDX (27), 2977 DEFINE_VFP_D_IDX (28), 2978 DEFINE_VFP_D_IDX (29), 2979 DEFINE_VFP_D_IDX (30), 2980 DEFINE_VFP_D_IDX (31), 2981 { e_regSetVFP, vfp_fpscr, "fpscr", NULL, Uint, Hex, 4, VFP_OFFSET_NAME(fpscr), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gdb_fpscr } 2982}; 2983 2984// Exception registers 2985 2986const DNBRegisterInfo 2987DNBArchMachARM::g_exc_registers[] = 2988{ 2989 { e_regSetVFP, exc_exception , "exception" , NULL, Uint, Hex, 4, EXC_OFFSET(exception) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM }, 2990 { e_regSetVFP, exc_fsr , "fsr" , NULL, Uint, Hex, 4, EXC_OFFSET(fsr) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM }, 2991 { e_regSetVFP, exc_far , "far" , NULL, Uint, Hex, 4, EXC_OFFSET(far) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM } 2992}; 2993 2994// Number of registers in each register set 2995const size_t DNBArchMachARM::k_num_gpr_registers = sizeof(g_gpr_registers)/sizeof(DNBRegisterInfo); 2996const size_t DNBArchMachARM::k_num_vfp_registers = sizeof(g_vfp_registers)/sizeof(DNBRegisterInfo); 2997const size_t DNBArchMachARM::k_num_exc_registers = sizeof(g_exc_registers)/sizeof(DNBRegisterInfo); 2998const size_t DNBArchMachARM::k_num_all_registers = k_num_gpr_registers + k_num_vfp_registers + k_num_exc_registers; 2999 3000//---------------------------------------------------------------------- 3001// Register set definitions. The first definitions at register set index 3002// of zero is for all registers, followed by other registers sets. The 3003// register information for the all register set need not be filled in. 3004//---------------------------------------------------------------------- 3005const DNBRegisterSetInfo 3006DNBArchMachARM::g_reg_sets[] = 3007{ 3008 { "ARM Registers", NULL, k_num_all_registers }, 3009 { "General Purpose Registers", g_gpr_registers, k_num_gpr_registers }, 3010 { "Floating Point Registers", g_vfp_registers, k_num_vfp_registers }, 3011 { "Exception State Registers", g_exc_registers, k_num_exc_registers } 3012}; 3013// Total number of register sets for this architecture 3014const size_t DNBArchMachARM::k_num_register_sets = sizeof(g_reg_sets)/sizeof(DNBRegisterSetInfo); 3015 3016 3017const DNBRegisterSetInfo * 3018DNBArchMachARM::GetRegisterSetInfo(nub_size_t *num_reg_sets) 3019{ 3020 *num_reg_sets = k_num_register_sets; 3021 return g_reg_sets; 3022} 3023 3024bool 3025DNBArchMachARM::GetRegisterValue(int set, int reg, DNBRegisterValue *value) 3026{ 3027 if (set == REGISTER_SET_GENERIC) 3028 { 3029 switch (reg) 3030 { 3031 case GENERIC_REGNUM_PC: // Program Counter 3032 set = e_regSetGPR; 3033 reg = gpr_pc; 3034 break; 3035 3036 case GENERIC_REGNUM_SP: // Stack Pointer 3037 set = e_regSetGPR; 3038 reg = gpr_sp; 3039 break; 3040 3041 case GENERIC_REGNUM_FP: // Frame Pointer 3042 set = e_regSetGPR; 3043 reg = gpr_r7; // is this the right reg? 3044 break; 3045 3046 case GENERIC_REGNUM_RA: // Return Address 3047 set = e_regSetGPR; 3048 reg = gpr_lr; 3049 break; 3050 3051 case GENERIC_REGNUM_FLAGS: // Processor flags register 3052 set = e_regSetGPR; 3053 reg = gpr_cpsr; 3054 break; 3055 3056 default: 3057 return false; 3058 } 3059 } 3060 3061 if (GetRegisterState(set, false) != KERN_SUCCESS) 3062 return false; 3063 3064 const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg); 3065 if (regInfo) 3066 { 3067 value->info = *regInfo; 3068 switch (set) 3069 { 3070 case e_regSetGPR: 3071 if (reg < k_num_gpr_registers) 3072 { 3073 value->value.uint32 = m_state.context.gpr.__r[reg]; 3074 return true; 3075 } 3076 break; 3077 3078 case e_regSetVFP: 3079 if (reg <= vfp_s31) 3080 { 3081 value->value.uint32 = m_state.context.vfp.__r[reg]; 3082 return true; 3083 } 3084 else if (reg <= vfp_d31) 3085 { 3086 uint32_t d_reg_idx = reg - vfp_d0; 3087 uint32_t s_reg_idx = d_reg_idx * 2; 3088 value->value.v_sint32[0] = m_state.context.vfp.__r[s_reg_idx + 0]; 3089 value->value.v_sint32[1] = m_state.context.vfp.__r[s_reg_idx + 1]; 3090 return true; 3091 } 3092 else if (reg == vfp_fpscr) 3093 { 3094 value->value.uint32 = m_state.context.vfp.__fpscr; 3095 return true; 3096 } 3097 break; 3098 3099 case e_regSetEXC: 3100 if (reg < k_num_exc_registers) 3101 { 3102 value->value.uint32 = (&m_state.context.exc.__exception)[reg]; 3103 return true; 3104 } 3105 break; 3106 } 3107 } 3108 return false; 3109} 3110 3111bool 3112DNBArchMachARM::SetRegisterValue(int set, int reg, const DNBRegisterValue *value) 3113{ 3114 if (set == REGISTER_SET_GENERIC) 3115 { 3116 switch (reg) 3117 { 3118 case GENERIC_REGNUM_PC: // Program Counter 3119 set = e_regSetGPR; 3120 reg = gpr_pc; 3121 break; 3122 3123 case GENERIC_REGNUM_SP: // Stack Pointer 3124 set = e_regSetGPR; 3125 reg = gpr_sp; 3126 break; 3127 3128 case GENERIC_REGNUM_FP: // Frame Pointer 3129 set = e_regSetGPR; 3130 reg = gpr_r7; 3131 break; 3132 3133 case GENERIC_REGNUM_RA: // Return Address 3134 set = e_regSetGPR; 3135 reg = gpr_lr; 3136 break; 3137 3138 case GENERIC_REGNUM_FLAGS: // Processor flags register 3139 set = e_regSetGPR; 3140 reg = gpr_cpsr; 3141 break; 3142 3143 default: 3144 return false; 3145 } 3146 } 3147 3148 if (GetRegisterState(set, false) != KERN_SUCCESS) 3149 return false; 3150 3151 bool success = false; 3152 const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg); 3153 if (regInfo) 3154 { 3155 switch (set) 3156 { 3157 case e_regSetGPR: 3158 if (reg < k_num_gpr_registers) 3159 { 3160 m_state.context.gpr.__r[reg] = value->value.uint32; 3161 success = true; 3162 } 3163 break; 3164 3165 case e_regSetVFP: 3166 if (reg <= vfp_s31) 3167 { 3168 m_state.context.vfp.__r[reg] = value->value.uint32; 3169 success = true; 3170 } 3171 else if (reg <= vfp_d31) 3172 { 3173 uint32_t d_reg_idx = reg - vfp_d0; 3174 uint32_t s_reg_idx = d_reg_idx * 2; 3175 m_state.context.vfp.__r[s_reg_idx + 0] = value->value.v_sint32[0]; 3176 m_state.context.vfp.__r[s_reg_idx + 1] = value->value.v_sint32[1]; 3177 success = true; 3178 } 3179 else if (reg == vfp_fpscr) 3180 { 3181 m_state.context.vfp.__fpscr = value->value.uint32; 3182 success = true; 3183 } 3184 break; 3185 3186 case e_regSetEXC: 3187 if (reg < k_num_exc_registers) 3188 { 3189 (&m_state.context.exc.__exception)[reg] = value->value.uint32; 3190 success = true; 3191 } 3192 break; 3193 } 3194 3195 } 3196 if (success) 3197 return SetRegisterState(set) == KERN_SUCCESS; 3198 return false; 3199} 3200 3201kern_return_t 3202DNBArchMachARM::GetRegisterState(int set, bool force) 3203{ 3204 switch (set) 3205 { 3206 case e_regSetALL: return GetGPRState(force) | 3207 GetVFPState(force) | 3208 GetEXCState(force) | 3209 GetDBGState(force); 3210 case e_regSetGPR: return GetGPRState(force); 3211 case e_regSetVFP: return GetVFPState(force); 3212 case e_regSetEXC: return GetEXCState(force); 3213 case e_regSetDBG: return GetDBGState(force); 3214 default: break; 3215 } 3216 return KERN_INVALID_ARGUMENT; 3217} 3218 3219kern_return_t 3220DNBArchMachARM::SetRegisterState(int set) 3221{ 3222 // Make sure we have a valid context to set. 3223 kern_return_t err = GetRegisterState(set, false); 3224 if (err != KERN_SUCCESS) 3225 return err; 3226 3227 switch (set) 3228 { 3229 case e_regSetALL: return SetGPRState() | 3230 SetVFPState() | 3231 SetEXCState() | 3232 SetDBGState(); 3233 case e_regSetGPR: return SetGPRState(); 3234 case e_regSetVFP: return SetVFPState(); 3235 case e_regSetEXC: return SetEXCState(); 3236 case e_regSetDBG: return SetDBGState(); 3237 default: break; 3238 } 3239 return KERN_INVALID_ARGUMENT; 3240} 3241 3242bool 3243DNBArchMachARM::RegisterSetStateIsValid (int set) const 3244{ 3245 return m_state.RegsAreValid(set); 3246} 3247 3248 3249nub_size_t 3250DNBArchMachARM::GetRegisterContext (void *buf, nub_size_t buf_len) 3251{ 3252 nub_size_t size = sizeof (m_state.context); 3253 3254 if (buf && buf_len) 3255 { 3256 if (size > buf_len) 3257 size = buf_len; 3258 3259 bool force = false; 3260 if (GetGPRState(force) | GetVFPState(force) | GetEXCState(force)) 3261 return 0; 3262 ::memcpy (buf, &m_state.context, size); 3263 } 3264 DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM::GetRegisterContext (buf = %p, len = %zu) => %zu", buf, buf_len, size); 3265 // Return the size of the register context even if NULL was passed in 3266 return size; 3267} 3268 3269nub_size_t 3270DNBArchMachARM::SetRegisterContext (const void *buf, nub_size_t buf_len) 3271{ 3272 nub_size_t size = sizeof (m_state.context); 3273 if (buf == NULL || buf_len == 0) 3274 size = 0; 3275 3276 if (size) 3277 { 3278 if (size > buf_len) 3279 size = buf_len; 3280 3281 ::memcpy (&m_state.context, buf, size); 3282 SetGPRState(); 3283 SetVFPState(); 3284 SetEXCState(); 3285 } 3286 DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM::SetRegisterContext (buf = %p, len = %zu) => %zu", buf, buf_len, size); 3287 return size; 3288} 3289 3290 3291#endif // #if defined (__arm__) 3292 3293