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