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