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 (__powerpc__) || defined (__ppc__) || defined (__ppc64__) 15 16 #if __DARWIN_UNIX03 17 #define PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(reg) __##reg 18 #else 19 #define PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(reg) reg 20 #endif 21 22 #include "MacOSX/ppc/DNBArchImpl.h" 23 #include "MacOSX/MachThread.h" 24 #include "DNBBreakpoint.h" 25 #include "DNBLog.h" 26 #include "DNBRegisterInfo.h" 27 28 static const uint8_t g_breakpoint_opcode[] = { 0x7F, 0xC0, 0x00, 0x08 }; 29 30 const uint8_t * const 31 DNBArchMachPPC::SoftwareBreakpointOpcode (nub_size_t size) 32 { 33 if (size == 4) 34 return g_breakpoint_opcode; 35 return NULL; 36 } 37 38 uint32_t 39 DNBArchMachPPC::GetCPUType() 40 { 41 return CPU_TYPE_POWERPC; 42 } 43 44 uint64_t 45 DNBArchMachPPC::GetPC(uint64_t failValue) 46 { 47 // Get program counter 48 if (GetGPRState(false) == KERN_SUCCESS) 49 return m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr0); 50 return failValue; 51 } 52 53 kern_return_t 54 DNBArchMachPPC::SetPC(uint64_t value) 55 { 56 // Get program counter 57 kern_return_t err = GetGPRState(false); 58 if (err == KERN_SUCCESS) 59 { 60 m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr0) = value; 61 err = SetGPRState(); 62 } 63 return err == KERN_SUCCESS; 64 } 65 66 uint64_t 67 DNBArchMachPPC::GetSP(uint64_t failValue) 68 { 69 // Get stack pointer 70 if (GetGPRState(false) == KERN_SUCCESS) 71 return m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(r1); 72 return failValue; 73 } 74 75 kern_return_t 76 DNBArchMachPPC::GetGPRState(bool force) 77 { 78 if (force || m_state.GetError(e_regSetGPR, Read)) 79 { 80 mach_msg_type_number_t count = e_regSetWordSizeGPR; 81 m_state.SetError(e_regSetGPR, Read, ::thread_get_state(m_thread->MachPortNumber(), e_regSetGPR, (thread_state_t)&m_state.gpr, &count)); 82 } 83 return m_state.GetError(e_regSetGPR, Read); 84 } 85 86 kern_return_t 87 DNBArchMachPPC::GetFPRState(bool force) 88 { 89 if (force || m_state.GetError(e_regSetFPR, Read)) 90 { 91 mach_msg_type_number_t count = e_regSetWordSizeFPR; 92 m_state.SetError(e_regSetFPR, Read, ::thread_get_state(m_thread->MachPortNumber(), e_regSetFPR, (thread_state_t)&m_state.fpr, &count)); 93 } 94 return m_state.GetError(e_regSetFPR, Read); 95 } 96 97 kern_return_t 98 DNBArchMachPPC::GetEXCState(bool force) 99 { 100 if (force || m_state.GetError(e_regSetEXC, Read)) 101 { 102 mach_msg_type_number_t count = e_regSetWordSizeEXC; 103 m_state.SetError(e_regSetEXC, Read, ::thread_get_state(m_thread->MachPortNumber(), e_regSetEXC, (thread_state_t)&m_state.exc, &count)); 104 } 105 return m_state.GetError(e_regSetEXC, Read); 106 } 107 108 kern_return_t 109 DNBArchMachPPC::GetVECState(bool force) 110 { 111 if (force || m_state.GetError(e_regSetVEC, Read)) 112 { 113 mach_msg_type_number_t count = e_regSetWordSizeVEC; 114 m_state.SetError(e_regSetVEC, Read, ::thread_get_state(m_thread->MachPortNumber(), e_regSetVEC, (thread_state_t)&m_state.vec, &count)); 115 } 116 return m_state.GetError(e_regSetVEC, Read); 117 } 118 119 kern_return_t 120 DNBArchMachPPC::SetGPRState() 121 { 122 m_state.SetError(e_regSetGPR, Write, ::thread_set_state(m_thread->MachPortNumber(), e_regSetGPR, (thread_state_t)&m_state.gpr, e_regSetWordSizeGPR)); 123 return m_state.GetError(e_regSetGPR, Write); 124 } 125 126 kern_return_t 127 DNBArchMachPPC::SetFPRState() 128 { 129 m_state.SetError(e_regSetFPR, Write, ::thread_set_state(m_thread->MachPortNumber(), e_regSetFPR, (thread_state_t)&m_state.fpr, e_regSetWordSizeFPR)); 130 return m_state.GetError(e_regSetFPR, Write); 131 } 132 133 kern_return_t 134 DNBArchMachPPC::SetEXCState() 135 { 136 m_state.SetError(e_regSetEXC, Write, ::thread_set_state(m_thread->MachPortNumber(), e_regSetEXC, (thread_state_t)&m_state.exc, e_regSetWordSizeEXC)); 137 return m_state.GetError(e_regSetEXC, Write); 138 } 139 140 kern_return_t 141 DNBArchMachPPC::SetVECState() 142 { 143 m_state.SetError(e_regSetVEC, Write, ::thread_set_state(m_thread->MachPortNumber(), e_regSetVEC, (thread_state_t)&m_state.vec, e_regSetWordSizeVEC)); 144 return m_state.GetError(e_regSetVEC, Write); 145 } 146 147 bool 148 DNBArchMachPPC::ThreadWillResume() 149 { 150 bool success = true; 151 152 // Do we need to step this thread? If so, let the mach thread tell us so. 153 if (m_thread->IsStepping()) 154 { 155 // This is the primary thread, let the arch do anything it needs 156 success = EnableHardwareSingleStep(true) == KERN_SUCCESS; 157 } 158 return success; 159 } 160 161 bool 162 DNBArchMachPPC::ThreadDidStop() 163 { 164 bool success = true; 165 166 m_state.InvalidateAllRegisterStates(); 167 168 // Are we stepping a single instruction? 169 if (GetGPRState(true) == KERN_SUCCESS) 170 { 171 // We are single stepping, was this the primary thread? 172 if (m_thread->IsStepping()) 173 { 174 // This was the primary thread, we need to clear the trace 175 // bit if so. 176 success = EnableHardwareSingleStep(false) == KERN_SUCCESS; 177 } 178 else 179 { 180 // The MachThread will automatically restore the suspend count 181 // in ThreadDidStop(), so we don't need to do anything here if 182 // we weren't the primary thread the last time 183 } 184 } 185 return success; 186 } 187 188 189 // Set the single step bit in the processor status register. 190 kern_return_t 191 DNBArchMachPPC::EnableHardwareSingleStep (bool enable) 192 { 193 DNBLogThreadedIf(LOG_STEP, "DNBArchMachPPC::EnableHardwareSingleStep( enable = %d )", enable); 194 if (GetGPRState(false) == KERN_SUCCESS) 195 { 196 const uint32_t trace_bit = 0x400; 197 if (enable) 198 m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr1) |= trace_bit; 199 else 200 m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr1) &= ~trace_bit; 201 return SetGPRState(); 202 } 203 return m_state.GetError(e_regSetGPR, Read); 204 } 205 206 //---------------------------------------------------------------------- 207 // Register information defintions for 32 bit PowerPC. 208 //---------------------------------------------------------------------- 209 210 enum gpr_regnums 211 { 212 e_regNumGPR_srr0, 213 e_regNumGPR_srr1, 214 e_regNumGPR_r0, 215 e_regNumGPR_r1, 216 e_regNumGPR_r2, 217 e_regNumGPR_r3, 218 e_regNumGPR_r4, 219 e_regNumGPR_r5, 220 e_regNumGPR_r6, 221 e_regNumGPR_r7, 222 e_regNumGPR_r8, 223 e_regNumGPR_r9, 224 e_regNumGPR_r10, 225 e_regNumGPR_r11, 226 e_regNumGPR_r12, 227 e_regNumGPR_r13, 228 e_regNumGPR_r14, 229 e_regNumGPR_r15, 230 e_regNumGPR_r16, 231 e_regNumGPR_r17, 232 e_regNumGPR_r18, 233 e_regNumGPR_r19, 234 e_regNumGPR_r20, 235 e_regNumGPR_r21, 236 e_regNumGPR_r22, 237 e_regNumGPR_r23, 238 e_regNumGPR_r24, 239 e_regNumGPR_r25, 240 e_regNumGPR_r26, 241 e_regNumGPR_r27, 242 e_regNumGPR_r28, 243 e_regNumGPR_r29, 244 e_regNumGPR_r30, 245 e_regNumGPR_r31, 246 e_regNumGPR_cr, 247 e_regNumGPR_xer, 248 e_regNumGPR_lr, 249 e_regNumGPR_ctr, 250 e_regNumGPR_mq, 251 e_regNumGPR_vrsave 252 }; 253 254 255 256 257 // General purpose registers 258 static DNBRegisterInfo g_gpr_registers[] = 259 { 260 { "srr0" , Uint, 4, Hex }, 261 { "srr1" , Uint, 4, Hex }, 262 { "r0" , Uint, 4, Hex }, 263 { "r1" , Uint, 4, Hex }, 264 { "r2" , Uint, 4, Hex }, 265 { "r3" , Uint, 4, Hex }, 266 { "r4" , Uint, 4, Hex }, 267 { "r5" , Uint, 4, Hex }, 268 { "r6" , Uint, 4, Hex }, 269 { "r7" , Uint, 4, Hex }, 270 { "r8" , Uint, 4, Hex }, 271 { "r9" , Uint, 4, Hex }, 272 { "r10" , Uint, 4, Hex }, 273 { "r11" , Uint, 4, Hex }, 274 { "r12" , Uint, 4, Hex }, 275 { "r13" , Uint, 4, Hex }, 276 { "r14" , Uint, 4, Hex }, 277 { "r15" , Uint, 4, Hex }, 278 { "r16" , Uint, 4, Hex }, 279 { "r17" , Uint, 4, Hex }, 280 { "r18" , Uint, 4, Hex }, 281 { "r19" , Uint, 4, Hex }, 282 { "r20" , Uint, 4, Hex }, 283 { "r21" , Uint, 4, Hex }, 284 { "r22" , Uint, 4, Hex }, 285 { "r23" , Uint, 4, Hex }, 286 { "r24" , Uint, 4, Hex }, 287 { "r25" , Uint, 4, Hex }, 288 { "r26" , Uint, 4, Hex }, 289 { "r27" , Uint, 4, Hex }, 290 { "r28" , Uint, 4, Hex }, 291 { "r29" , Uint, 4, Hex }, 292 { "r30" , Uint, 4, Hex }, 293 { "r31" , Uint, 4, Hex }, 294 { "cr" , Uint, 4, Hex }, 295 { "xer" , Uint, 4, Hex }, 296 { "lr" , Uint, 4, Hex }, 297 { "ctr" , Uint, 4, Hex }, 298 { "mq" , Uint, 4, Hex }, 299 { "vrsave", Uint, 4, Hex }, 300 }; 301 302 // Floating point registers 303 static DNBRegisterInfo g_fpr_registers[] = 304 { 305 { "fp0" , IEEE754, 8, Float }, 306 { "fp1" , IEEE754, 8, Float }, 307 { "fp2" , IEEE754, 8, Float }, 308 { "fp3" , IEEE754, 8, Float }, 309 { "fp4" , IEEE754, 8, Float }, 310 { "fp5" , IEEE754, 8, Float }, 311 { "fp6" , IEEE754, 8, Float }, 312 { "fp7" , IEEE754, 8, Float }, 313 { "fp8" , IEEE754, 8, Float }, 314 { "fp9" , IEEE754, 8, Float }, 315 { "fp10" , IEEE754, 8, Float }, 316 { "fp11" , IEEE754, 8, Float }, 317 { "fp12" , IEEE754, 8, Float }, 318 { "fp13" , IEEE754, 8, Float }, 319 { "fp14" , IEEE754, 8, Float }, 320 { "fp15" , IEEE754, 8, Float }, 321 { "fp16" , IEEE754, 8, Float }, 322 { "fp17" , IEEE754, 8, Float }, 323 { "fp18" , IEEE754, 8, Float }, 324 { "fp19" , IEEE754, 8, Float }, 325 { "fp20" , IEEE754, 8, Float }, 326 { "fp21" , IEEE754, 8, Float }, 327 { "fp22" , IEEE754, 8, Float }, 328 { "fp23" , IEEE754, 8, Float }, 329 { "fp24" , IEEE754, 8, Float }, 330 { "fp25" , IEEE754, 8, Float }, 331 { "fp26" , IEEE754, 8, Float }, 332 { "fp27" , IEEE754, 8, Float }, 333 { "fp28" , IEEE754, 8, Float }, 334 { "fp29" , IEEE754, 8, Float }, 335 { "fp30" , IEEE754, 8, Float }, 336 { "fp31" , IEEE754, 8, Float }, 337 { "fpscr" , Uint, 4, Hex } 338 }; 339 340 // Exception registers 341 342 static DNBRegisterInfo g_exc_registers[] = 343 { 344 { "dar" , Uint, 4, Hex }, 345 { "dsisr" , Uint, 4, Hex }, 346 { "exception" , Uint, 4, Hex } 347 }; 348 349 // Altivec registers 350 static DNBRegisterInfo g_vec_registers[] = 351 { 352 { "vr0" , Vector, 16, VectorOfFloat32 }, 353 { "vr1" , Vector, 16, VectorOfFloat32 }, 354 { "vr2" , Vector, 16, VectorOfFloat32 }, 355 { "vr3" , Vector, 16, VectorOfFloat32 }, 356 { "vr4" , Vector, 16, VectorOfFloat32 }, 357 { "vr5" , Vector, 16, VectorOfFloat32 }, 358 { "vr6" , Vector, 16, VectorOfFloat32 }, 359 { "vr7" , Vector, 16, VectorOfFloat32 }, 360 { "vr8" , Vector, 16, VectorOfFloat32 }, 361 { "vr9" , Vector, 16, VectorOfFloat32 }, 362 { "vr10" , Vector, 16, VectorOfFloat32 }, 363 { "vr11" , Vector, 16, VectorOfFloat32 }, 364 { "vr12" , Vector, 16, VectorOfFloat32 }, 365 { "vr13" , Vector, 16, VectorOfFloat32 }, 366 { "vr14" , Vector, 16, VectorOfFloat32 }, 367 { "vr15" , Vector, 16, VectorOfFloat32 }, 368 { "vr16" , Vector, 16, VectorOfFloat32 }, 369 { "vr17" , Vector, 16, VectorOfFloat32 }, 370 { "vr18" , Vector, 16, VectorOfFloat32 }, 371 { "vr19" , Vector, 16, VectorOfFloat32 }, 372 { "vr20" , Vector, 16, VectorOfFloat32 }, 373 { "vr21" , Vector, 16, VectorOfFloat32 }, 374 { "vr22" , Vector, 16, VectorOfFloat32 }, 375 { "vr23" , Vector, 16, VectorOfFloat32 }, 376 { "vr24" , Vector, 16, VectorOfFloat32 }, 377 { "vr25" , Vector, 16, VectorOfFloat32 }, 378 { "vr26" , Vector, 16, VectorOfFloat32 }, 379 { "vr27" , Vector, 16, VectorOfFloat32 }, 380 { "vr28" , Vector, 16, VectorOfFloat32 }, 381 { "vr29" , Vector, 16, VectorOfFloat32 }, 382 { "vr30" , Vector, 16, VectorOfFloat32 }, 383 { "vr31" , Vector, 16, VectorOfFloat32 }, 384 { "vscr" , Uint, 16, Hex }, 385 { "vrvalid" , Uint, 4, Hex } 386 }; 387 388 // Number of registers in each register set 389 const size_t k_num_gpr_registers = sizeof(g_gpr_registers)/sizeof(DNBRegisterInfo); 390 const size_t k_num_fpr_registers = sizeof(g_fpr_registers)/sizeof(DNBRegisterInfo); 391 const size_t k_num_exc_registers = sizeof(g_exc_registers)/sizeof(DNBRegisterInfo); 392 const size_t k_num_vec_registers = sizeof(g_vec_registers)/sizeof(DNBRegisterInfo); 393 // Total number of registers for this architecture 394 const size_t k_num_ppc_registers = k_num_gpr_registers + k_num_fpr_registers + k_num_exc_registers + k_num_vec_registers; 395 396 //---------------------------------------------------------------------- 397 // Register set definitions. The first definitions at register set index 398 // of zero is for all registers, followed by other registers sets. The 399 // register information for the all register set need not be filled in. 400 //---------------------------------------------------------------------- 401 static const DNBRegisterSetInfo g_reg_sets[] = 402 { 403 { "PowerPC Registers", NULL, k_num_ppc_registers }, 404 { "General Purpose Registers", g_gpr_registers, k_num_gpr_registers }, 405 { "Floating Point Registers", g_fpr_registers, k_num_fpr_registers }, 406 { "Exception State Registers", g_exc_registers, k_num_exc_registers }, 407 { "Altivec Registers", g_vec_registers, k_num_vec_registers } 408 }; 409 // Total number of register sets for this architecture 410 const size_t k_num_register_sets = sizeof(g_reg_sets)/sizeof(DNBRegisterSetInfo); 411 412 413 const DNBRegisterSetInfo * 414 DNBArchMachPPC::GetRegisterSetInfo(nub_size_t *num_reg_sets) const 415 { 416 *num_reg_sets = k_num_register_sets; 417 return g_reg_sets; 418 } 419 420 bool 421 DNBArchMachPPC::GetRegisterValue(int set, int reg, DNBRegisterValue *value) const 422 { 423 if (set == REGISTER_SET_GENERIC) 424 { 425 switch (reg) 426 { 427 case GENERIC_REGNUM_PC: // Program Counter 428 set = e_regSetGPR; 429 reg = e_regNumGPR_srr0; 430 break; 431 432 case GENERIC_REGNUM_SP: // Stack Pointer 433 set = e_regSetGPR; 434 reg = e_regNumGPR_r1; 435 break; 436 437 case GENERIC_REGNUM_FP: // Frame Pointer 438 // Return false for now instead of returning r30 as gcc 3.x would 439 // use a variety of registers for the FP and it takes inspecting 440 // the stack to make sure there is a frame pointer before we can 441 // determine the FP. 442 return false; 443 444 case GENERIC_REGNUM_RA: // Return Address 445 set = e_regSetGPR; 446 reg = e_regNumGPR_lr; 447 break; 448 449 case GENERIC_REGNUM_FLAGS: // Processor flags register 450 set = e_regSetGPR; 451 reg = e_regNumGPR_srr1; 452 break; 453 454 default: 455 return false; 456 } 457 } 458 459 if (!m_state.RegsAreValid(set)) 460 return false; 461 462 const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg); 463 if (regInfo) 464 { 465 value->info = *regInfo; 466 switch (set) 467 { 468 case e_regSetGPR: 469 if (reg < k_num_gpr_registers) 470 { 471 value->value.uint32 = (&m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr0))[reg]; 472 return true; 473 } 474 break; 475 476 case e_regSetFPR: 477 if (reg < 32) 478 { 479 value->value.float64 = m_state.fpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(fpregs)[reg]; 480 return true; 481 } 482 else if (reg == 32) 483 { 484 value->value.uint32 = m_state.fpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(fpscr); 485 return true; 486 } 487 break; 488 489 case e_regSetEXC: 490 if (reg < k_num_exc_registers) 491 { 492 value->value.uint32 = (&m_state.exc.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(dar))[reg]; 493 return true; 494 } 495 break; 496 497 case e_regSetVEC: 498 if (reg < k_num_vec_registers) 499 { 500 if (reg < 33) // FP0 - FP31 and VSCR 501 { 502 // Copy all 4 uint32 values for this vector register 503 value->value.v_uint32[0] = m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg][0]; 504 value->value.v_uint32[1] = m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg][1]; 505 value->value.v_uint32[2] = m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg][2]; 506 value->value.v_uint32[3] = m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg][3]; 507 return true; 508 } 509 else if (reg == 34) // VRVALID 510 { 511 value->value.uint32 = m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vrvalid); 512 return true; 513 } 514 } 515 break; 516 } 517 } 518 return false; 519 } 520 521 522 kern_return_t 523 DNBArchMachPPC::GetRegisterState(int set, bool force) 524 { 525 switch (set) 526 { 527 case e_regSetALL: 528 return GetGPRState(force) | 529 GetFPRState(force) | 530 GetEXCState(force) | 531 GetVECState(force); 532 case e_regSetGPR: return GetGPRState(force); 533 case e_regSetFPR: return GetFPRState(force); 534 case e_regSetEXC: return GetEXCState(force); 535 case e_regSetVEC: return GetVECState(force); 536 default: break; 537 } 538 return KERN_INVALID_ARGUMENT; 539 } 540 541 kern_return_t 542 DNBArchMachPPC::SetRegisterState(int set) 543 { 544 // Make sure we have a valid context to set. 545 kern_return_t err = GetRegisterState(set, false); 546 if (err != KERN_SUCCESS) 547 return err; 548 549 switch (set) 550 { 551 case e_regSetALL: return SetGPRState() | SetFPRState() | SetEXCState() | SetVECState(); 552 case e_regSetGPR: return SetGPRState(); 553 case e_regSetFPR: return SetFPRState(); 554 case e_regSetEXC: return SetEXCState(); 555 case e_regSetVEC: return SetVECState(); 556 default: break; 557 } 558 return KERN_INVALID_ARGUMENT; 559 } 560 561 bool 562 DNBArchMachPPC::RegisterSetStateIsValid (int set) const 563 { 564 return m_state.RegsAreValid(set); 565 } 566 567 568 #endif // #if defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__) 569 570