1 //===-- FreeBSDThread.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 // C Includes 11 #include <errno.h> 12 13 // C++ Includes 14 // Other libraries and framework includes 15 #include "lldb/Core/State.h" 16 #include "lldb/Target/UnixSignals.h" 17 18 // Project includes 19 #include "lldb/Breakpoint/Watchpoint.h" 20 #include "lldb/Breakpoint/BreakpointLocation.h" 21 #include "lldb/Core/Debugger.h" 22 #include "lldb/Core/State.h" 23 #include "lldb/Host/Host.h" 24 #include "lldb/Host/HostNativeThread.h" 25 #include "lldb/Host/HostInfo.h" 26 #include "lldb/Target/Process.h" 27 #include "lldb/Target/StopInfo.h" 28 #include "lldb/Target/Target.h" 29 #include "lldb/Target/ThreadSpec.h" 30 #include "llvm/ADT/SmallString.h" 31 #include "POSIXStopInfo.h" 32 #include "FreeBSDThread.h" 33 #include "ProcessFreeBSD.h" 34 #include "ProcessPOSIXLog.h" 35 #include "ProcessMonitor.h" 36 #include "RegisterContextPOSIXProcessMonitor_arm.h" 37 #include "RegisterContextPOSIXProcessMonitor_arm64.h" 38 #include "RegisterContextPOSIXProcessMonitor_mips64.h" 39 #include "RegisterContextPOSIXProcessMonitor_powerpc.h" 40 #include "RegisterContextPOSIXProcessMonitor_x86.h" 41 #include "Plugins/Process/Utility/RegisterContextFreeBSD_arm.h" 42 #include "Plugins/Process/Utility/RegisterContextFreeBSD_arm64.h" 43 #include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h" 44 #include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h" 45 #include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h" 46 #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h" 47 #include "Plugins/Process/Utility/UnwindLLDB.h" 48 49 using namespace lldb; 50 using namespace lldb_private; 51 52 FreeBSDThread::FreeBSDThread(Process &process, lldb::tid_t tid) 53 : Thread(process, tid), 54 m_frame_ap (), 55 m_breakpoint (), 56 m_thread_name_valid (false), 57 m_thread_name (), 58 m_posix_thread(NULL) 59 { 60 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 61 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) 62 log->Printf ("FreeBSDThread::%s (tid = %" PRIi64 ")", __FUNCTION__, tid); 63 64 // Set the current watchpoints for this thread. 65 Target &target = GetProcess()->GetTarget(); 66 const WatchpointList &wp_list = target.GetWatchpointList(); 67 size_t wp_size = wp_list.GetSize(); 68 69 for (uint32_t wp_idx = 0; wp_idx < wp_size; wp_idx++) 70 { 71 lldb::WatchpointSP wp = wp_list.GetByIndex(wp_idx); 72 if (wp.get() && wp->IsEnabled()) 73 { 74 // This watchpoint as been enabled; obviously this "new" thread 75 // has been created since that watchpoint was enabled. Since 76 // the POSIXBreakpointProtocol has yet to be initialized, its 77 // m_watchpoints_initialized member will be FALSE. Attempting to 78 // read the debug status register to determine if a watchpoint 79 // has been hit would result in the zeroing of that register. 80 // Since the active debug registers would have been cloned when 81 // this thread was created, simply force the m_watchpoints_initized 82 // member to TRUE and avoid resetting dr6 and dr7. 83 GetPOSIXBreakpointProtocol()->ForceWatchpointsInitialized(); 84 } 85 } 86 } 87 88 FreeBSDThread::~FreeBSDThread() 89 { 90 DestroyThread(); 91 } 92 93 ProcessMonitor & 94 FreeBSDThread::GetMonitor() 95 { 96 ProcessSP base = GetProcess(); 97 ProcessFreeBSD &process = static_cast<ProcessFreeBSD&>(*base); 98 return process.GetMonitor(); 99 } 100 101 void 102 FreeBSDThread::RefreshStateAfterStop() 103 { 104 // Invalidate all registers in our register context. We don't set "force" to 105 // true because the stop reply packet might have had some register values 106 // that were expedited and these will already be copied into the register 107 // context by the time this function gets called. The KDPRegisterContext 108 // class has been made smart enough to detect when it needs to invalidate 109 // which registers are valid by putting hooks in the register read and 110 // register supply functions where they check the process stop ID and do 111 // the right thing. 112 //if (StateIsStoppedState(GetState()) 113 { 114 const bool force = false; 115 GetRegisterContext()->InvalidateIfNeeded (force); 116 } 117 } 118 119 const char * 120 FreeBSDThread::GetInfo() 121 { 122 return NULL; 123 } 124 125 void 126 FreeBSDThread::SetName (const char *name) 127 { 128 m_thread_name_valid = (name && name[0]); 129 if (m_thread_name_valid) 130 m_thread_name.assign (name); 131 else 132 m_thread_name.clear(); 133 } 134 135 const char * 136 FreeBSDThread::GetName () 137 { 138 if (!m_thread_name_valid) 139 { 140 llvm::SmallString<32> thread_name; 141 HostNativeThread::GetName(GetID(), thread_name); 142 m_thread_name = thread_name.c_str(); 143 m_thread_name_valid = true; 144 } 145 146 if (m_thread_name.empty()) 147 return NULL; 148 return m_thread_name.c_str(); 149 } 150 151 lldb::RegisterContextSP 152 FreeBSDThread::GetRegisterContext() 153 { 154 if (!m_reg_context_sp) 155 { 156 m_posix_thread = NULL; 157 158 RegisterInfoInterface *reg_interface = NULL; 159 const ArchSpec &target_arch = GetProcess()->GetTarget().GetArchitecture(); 160 161 assert(target_arch.GetTriple().getOS() == llvm::Triple::FreeBSD); 162 switch (target_arch.GetMachine()) 163 { 164 case llvm::Triple::aarch64: 165 reg_interface = new RegisterContextFreeBSD_arm64(target_arch); 166 break; 167 case llvm::Triple::arm: 168 reg_interface = new RegisterContextFreeBSD_arm(target_arch); 169 break; 170 case llvm::Triple::ppc: 171 #ifndef __powerpc64__ 172 reg_interface = new RegisterContextFreeBSD_powerpc32(target_arch); 173 break; 174 #endif 175 case llvm::Triple::ppc64: 176 reg_interface = new RegisterContextFreeBSD_powerpc64(target_arch); 177 break; 178 case llvm::Triple::mips64: 179 reg_interface = new RegisterContextFreeBSD_mips64(target_arch); 180 break; 181 case llvm::Triple::x86: 182 reg_interface = new RegisterContextFreeBSD_i386(target_arch); 183 break; 184 case llvm::Triple::x86_64: 185 reg_interface = new RegisterContextFreeBSD_x86_64(target_arch); 186 break; 187 default: 188 llvm_unreachable("CPU not supported"); 189 } 190 191 switch (target_arch.GetMachine()) 192 { 193 case llvm::Triple::aarch64: 194 { 195 RegisterContextPOSIXProcessMonitor_arm64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_arm64(*this, 0, reg_interface); 196 m_posix_thread = reg_ctx; 197 m_reg_context_sp.reset(reg_ctx); 198 break; 199 } 200 case llvm::Triple::arm: 201 { 202 RegisterContextPOSIXProcessMonitor_arm *reg_ctx = new RegisterContextPOSIXProcessMonitor_arm(*this, 0, reg_interface); 203 m_posix_thread = reg_ctx; 204 m_reg_context_sp.reset(reg_ctx); 205 break; 206 } 207 case llvm::Triple::mips64: 208 { 209 RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_mips64(*this, 0, reg_interface); 210 m_posix_thread = reg_ctx; 211 m_reg_context_sp.reset(reg_ctx); 212 break; 213 } 214 case llvm::Triple::ppc: 215 case llvm::Triple::ppc64: 216 { 217 RegisterContextPOSIXProcessMonitor_powerpc *reg_ctx = new RegisterContextPOSIXProcessMonitor_powerpc(*this, 0, reg_interface); 218 m_posix_thread = reg_ctx; 219 m_reg_context_sp.reset(reg_ctx); 220 break; 221 } 222 case llvm::Triple::x86: 223 case llvm::Triple::x86_64: 224 { 225 RegisterContextPOSIXProcessMonitor_x86_64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_x86_64(*this, 0, reg_interface); 226 m_posix_thread = reg_ctx; 227 m_reg_context_sp.reset(reg_ctx); 228 break; 229 } 230 default: 231 break; 232 } 233 } 234 return m_reg_context_sp; 235 } 236 237 lldb::RegisterContextSP 238 FreeBSDThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame) 239 { 240 lldb::RegisterContextSP reg_ctx_sp; 241 uint32_t concrete_frame_idx = 0; 242 243 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 244 if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) 245 log->Printf ("FreeBSDThread::%s ()", __FUNCTION__); 246 247 if (frame) 248 concrete_frame_idx = frame->GetConcreteFrameIndex(); 249 250 if (concrete_frame_idx == 0) 251 reg_ctx_sp = GetRegisterContext(); 252 else 253 { 254 assert(GetUnwinder()); 255 reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame); 256 } 257 258 return reg_ctx_sp; 259 } 260 261 lldb::addr_t 262 FreeBSDThread::GetThreadPointer () 263 { 264 ProcessMonitor &monitor = GetMonitor(); 265 addr_t addr; 266 if (monitor.ReadThreadPointer (GetID(), addr)) 267 return addr; 268 else 269 return LLDB_INVALID_ADDRESS; 270 } 271 272 bool 273 FreeBSDThread::CalculateStopInfo() 274 { 275 SetStopInfo (m_stop_info_sp); 276 return true; 277 } 278 279 Unwind * 280 FreeBSDThread::GetUnwinder() 281 { 282 if (m_unwinder_ap.get() == NULL) 283 m_unwinder_ap.reset(new UnwindLLDB(*this)); 284 285 return m_unwinder_ap.get(); 286 } 287 288 void 289 FreeBSDThread::DidStop() 290 { 291 // Don't set the thread state to stopped unless we really stopped. 292 } 293 294 void 295 FreeBSDThread::WillResume(lldb::StateType resume_state) 296 { 297 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 298 if (log) 299 log->Printf("tid %lu resume_state = %s", GetID(), 300 lldb_private::StateAsCString(resume_state)); 301 ProcessSP process_sp(GetProcess()); 302 ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(process_sp.get()); 303 int signo = GetResumeSignal(); 304 bool signo_valid = process->GetUnixSignals()->SignalIsValid(signo); 305 306 switch (resume_state) 307 { 308 case eStateSuspended: 309 case eStateStopped: 310 process->m_suspend_tids.push_back(GetID()); 311 break; 312 case eStateRunning: 313 process->m_run_tids.push_back(GetID()); 314 if (signo_valid) 315 process->m_resume_signo = signo; 316 break; 317 case eStateStepping: 318 process->m_step_tids.push_back(GetID()); 319 if (signo_valid) 320 process->m_resume_signo = signo; 321 break; 322 default: 323 break; 324 } 325 } 326 327 bool 328 FreeBSDThread::Resume() 329 { 330 lldb::StateType resume_state = GetResumeState(); 331 ProcessMonitor &monitor = GetMonitor(); 332 bool status; 333 334 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 335 if (log) 336 log->Printf ("FreeBSDThread::%s (), resume_state = %s", __FUNCTION__, 337 StateAsCString(resume_state)); 338 339 switch (resume_state) 340 { 341 default: 342 assert(false && "Unexpected state for resume!"); 343 status = false; 344 break; 345 346 case lldb::eStateRunning: 347 SetState(resume_state); 348 status = monitor.Resume(GetID(), GetResumeSignal()); 349 break; 350 351 case lldb::eStateStepping: 352 SetState(resume_state); 353 status = monitor.SingleStep(GetID(), GetResumeSignal()); 354 break; 355 case lldb::eStateStopped: 356 case lldb::eStateSuspended: 357 status = true; 358 break; 359 } 360 361 return status; 362 } 363 364 void 365 FreeBSDThread::Notify(const ProcessMessage &message) 366 { 367 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 368 if (log) 369 log->Printf ("FreeBSDThread::%s () message kind = '%s' for tid %" PRIu64, 370 __FUNCTION__, message.PrintKind(), GetID()); 371 372 switch (message.GetKind()) 373 { 374 default: 375 assert(false && "Unexpected message kind!"); 376 break; 377 378 case ProcessMessage::eExitMessage: 379 // Nothing to be done. 380 break; 381 382 case ProcessMessage::eLimboMessage: 383 LimboNotify(message); 384 break; 385 386 case ProcessMessage::eSignalMessage: 387 SignalNotify(message); 388 break; 389 390 case ProcessMessage::eSignalDeliveredMessage: 391 SignalDeliveredNotify(message); 392 break; 393 394 case ProcessMessage::eTraceMessage: 395 TraceNotify(message); 396 break; 397 398 case ProcessMessage::eBreakpointMessage: 399 BreakNotify(message); 400 break; 401 402 case ProcessMessage::eWatchpointMessage: 403 WatchNotify(message); 404 break; 405 406 case ProcessMessage::eCrashMessage: 407 CrashNotify(message); 408 break; 409 410 case ProcessMessage::eExecMessage: 411 ExecNotify(message); 412 break; 413 } 414 } 415 416 bool 417 FreeBSDThread::EnableHardwareWatchpoint(Watchpoint *wp) 418 { 419 bool wp_set = false; 420 if (wp) 421 { 422 addr_t wp_addr = wp->GetLoadAddress(); 423 size_t wp_size = wp->GetByteSize(); 424 bool wp_read = wp->WatchpointRead(); 425 bool wp_write = wp->WatchpointWrite(); 426 uint32_t wp_hw_index = wp->GetHardwareIndex(); 427 POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol(); 428 if (reg_ctx) 429 wp_set = reg_ctx->SetHardwareWatchpointWithIndex(wp_addr, wp_size, 430 wp_read, wp_write, 431 wp_hw_index); 432 } 433 return wp_set; 434 } 435 436 bool 437 FreeBSDThread::DisableHardwareWatchpoint(Watchpoint *wp) 438 { 439 bool result = false; 440 if (wp) 441 { 442 lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext(); 443 if (reg_ctx_sp.get()) 444 result = reg_ctx_sp->ClearHardwareWatchpoint(wp->GetHardwareIndex()); 445 } 446 return result; 447 } 448 449 uint32_t 450 FreeBSDThread::NumSupportedHardwareWatchpoints() 451 { 452 lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext(); 453 if (reg_ctx_sp.get()) 454 return reg_ctx_sp->NumSupportedHardwareWatchpoints(); 455 return 0; 456 } 457 458 uint32_t 459 FreeBSDThread::FindVacantWatchpointIndex() 460 { 461 uint32_t hw_index = LLDB_INVALID_INDEX32; 462 uint32_t num_hw_wps = NumSupportedHardwareWatchpoints(); 463 uint32_t wp_idx; 464 POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol(); 465 if (reg_ctx) 466 { 467 for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) 468 { 469 if (reg_ctx->IsWatchpointVacant(wp_idx)) 470 { 471 hw_index = wp_idx; 472 break; 473 } 474 } 475 } 476 return hw_index; 477 } 478 479 void 480 FreeBSDThread::BreakNotify(const ProcessMessage &message) 481 { 482 bool status; 483 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 484 485 assert(GetRegisterContext()); 486 status = GetPOSIXBreakpointProtocol()->UpdateAfterBreakpoint(); 487 assert(status && "Breakpoint update failed!"); 488 489 // With our register state restored, resolve the breakpoint object 490 // corresponding to our current PC. 491 assert(GetRegisterContext()); 492 lldb::addr_t pc = GetRegisterContext()->GetPC(); 493 if (log) 494 log->Printf ("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc); 495 lldb::BreakpointSiteSP bp_site(GetProcess()->GetBreakpointSiteList().FindByAddress(pc)); 496 497 // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread, 498 // we create a stop reason with should_stop=false. If there is no breakpoint location, then report 499 // an invalid stop reason. We don't need to worry about stepping over the breakpoint here, that will 500 // be taken care of when the thread resumes and notices that there's a breakpoint under the pc. 501 if (bp_site) 502 { 503 lldb::break_id_t bp_id = bp_site->GetID(); 504 // If we have an operating system plug-in, we might have set a thread specific breakpoint using the 505 // operating system thread ID, so we can't make any assumptions about the thread ID so we must always 506 // report the breakpoint regardless of the thread. 507 if (bp_site->ValidForThisThread(this) || GetProcess()->GetOperatingSystem () != NULL) 508 SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id)); 509 else 510 { 511 const bool should_stop = false; 512 SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id, should_stop)); 513 } 514 } 515 else 516 SetStopInfo(StopInfoSP()); 517 } 518 519 void 520 FreeBSDThread::WatchNotify(const ProcessMessage &message) 521 { 522 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 523 524 lldb::addr_t halt_addr = message.GetHWAddress(); 525 if (log) 526 log->Printf ("FreeBSDThread::%s () Hardware Watchpoint Address = 0x%8.8" 527 PRIx64, __FUNCTION__, halt_addr); 528 529 POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol(); 530 if (reg_ctx) 531 { 532 uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints(); 533 uint32_t wp_idx; 534 for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) 535 { 536 if (reg_ctx->IsWatchpointHit(wp_idx)) 537 { 538 // Clear the watchpoint hit here 539 reg_ctx->ClearWatchpointHits(); 540 break; 541 } 542 } 543 544 if (wp_idx == num_hw_wps) 545 return; 546 547 Target &target = GetProcess()->GetTarget(); 548 lldb::addr_t wp_monitor_addr = reg_ctx->GetWatchpointAddress(wp_idx); 549 const WatchpointList &wp_list = target.GetWatchpointList(); 550 lldb::WatchpointSP wp_sp = wp_list.FindByAddress(wp_monitor_addr); 551 552 assert(wp_sp.get() && "No watchpoint found"); 553 SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID(*this, 554 wp_sp->GetID())); 555 } 556 } 557 558 void 559 FreeBSDThread::TraceNotify(const ProcessMessage &message) 560 { 561 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 562 563 // Try to resolve the breakpoint object corresponding to the current PC. 564 assert(GetRegisterContext()); 565 lldb::addr_t pc = GetRegisterContext()->GetPC(); 566 if (log) 567 log->Printf ("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc); 568 lldb::BreakpointSiteSP bp_site(GetProcess()->GetBreakpointSiteList().FindByAddress(pc)); 569 570 // If the current pc is a breakpoint site then set the StopInfo to Breakpoint. 571 // Otherwise, set the StopInfo to Watchpoint or Trace. 572 // If we have an operating system plug-in, we might have set a thread specific breakpoint using the 573 // operating system thread ID, so we can't make any assumptions about the thread ID so we must always 574 // report the breakpoint regardless of the thread. 575 if (bp_site && (bp_site->ValidForThisThread(this) || GetProcess()->GetOperatingSystem () != NULL)) 576 SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_site->GetID())); 577 else 578 { 579 POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol(); 580 if (reg_ctx) 581 { 582 uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints(); 583 uint32_t wp_idx; 584 for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) 585 { 586 if (reg_ctx->IsWatchpointHit(wp_idx)) 587 { 588 WatchNotify(message); 589 return; 590 } 591 } 592 } 593 SetStopInfo (StopInfo::CreateStopReasonToTrace(*this)); 594 } 595 } 596 597 void 598 FreeBSDThread::LimboNotify(const ProcessMessage &message) 599 { 600 SetStopInfo (lldb::StopInfoSP(new POSIXLimboStopInfo(*this))); 601 } 602 603 void 604 FreeBSDThread::SignalNotify(const ProcessMessage &message) 605 { 606 int signo = message.GetSignal(); 607 SetStopInfo (StopInfo::CreateStopReasonWithSignal(*this, signo)); 608 } 609 610 void 611 FreeBSDThread::SignalDeliveredNotify(const ProcessMessage &message) 612 { 613 int signo = message.GetSignal(); 614 SetStopInfo (StopInfo::CreateStopReasonWithSignal(*this, signo)); 615 } 616 617 void 618 FreeBSDThread::CrashNotify(const ProcessMessage &message) 619 { 620 // FIXME: Update stop reason as per bugzilla 14598 621 int signo = message.GetSignal(); 622 623 assert(message.GetKind() == ProcessMessage::eCrashMessage); 624 625 Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); 626 if (log) 627 log->Printf ("FreeBSDThread::%s () signo = %i, reason = '%s'", 628 __FUNCTION__, signo, message.PrintCrashReason()); 629 630 SetStopInfo (lldb::StopInfoSP(new POSIXCrashStopInfo(*this, signo, 631 message.GetCrashReason(), 632 message.GetFaultAddress()))); 633 } 634 635 unsigned 636 FreeBSDThread::GetRegisterIndexFromOffset(unsigned offset) 637 { 638 unsigned reg = LLDB_INVALID_REGNUM; 639 ArchSpec arch = HostInfo::GetArchitecture(); 640 641 switch (arch.GetMachine()) 642 { 643 default: 644 llvm_unreachable("CPU type not supported!"); 645 break; 646 647 case llvm::Triple::aarch64: 648 case llvm::Triple::arm: 649 case llvm::Triple::mips64: 650 case llvm::Triple::ppc: 651 case llvm::Triple::ppc64: 652 case llvm::Triple::x86: 653 case llvm::Triple::x86_64: 654 { 655 POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol(); 656 reg = reg_ctx->GetRegisterIndexFromOffset(offset); 657 } 658 break; 659 } 660 return reg; 661 } 662 663 void 664 FreeBSDThread::ExecNotify(const ProcessMessage &message) 665 { 666 SetStopInfo (StopInfo::CreateStopReasonWithExec(*this)); 667 } 668 669 const char * 670 FreeBSDThread::GetRegisterName(unsigned reg) 671 { 672 const char * name = nullptr; 673 ArchSpec arch = HostInfo::GetArchitecture(); 674 675 switch (arch.GetMachine()) 676 { 677 default: 678 assert(false && "CPU type not supported!"); 679 break; 680 681 case llvm::Triple::aarch64: 682 case llvm::Triple::arm: 683 case llvm::Triple::mips64: 684 case llvm::Triple::ppc: 685 case llvm::Triple::ppc64: 686 case llvm::Triple::x86: 687 case llvm::Triple::x86_64: 688 name = GetRegisterContext()->GetRegisterName(reg); 689 break; 690 } 691 return name; 692 } 693 694 const char * 695 FreeBSDThread::GetRegisterNameFromOffset(unsigned offset) 696 { 697 return GetRegisterName(GetRegisterIndexFromOffset(offset)); 698 } 699 700