]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Process / FreeBSD / FreeBSDThread.cpp
1 //===-- FreeBSDThread.cpp ---------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include <errno.h>
10 #include <pthread.h>
11 #include <pthread_np.h>
12 #include <stdlib.h>
13 #include <sys/sysctl.h>
14 #include <sys/types.h>
15 #include <sys/user.h>
16
17 #include "lldb/Target/UnixSignals.h"
18 #include "lldb/Utility/State.h"
19
20 #include "FreeBSDThread.h"
21 #include "POSIXStopInfo.h"
22 #include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
23 #include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
24 #include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
25 #include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
26 #include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
27 #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
28 #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
29 #include "Plugins/Process/Utility/UnwindLLDB.h"
30 #include "ProcessFreeBSD.h"
31 #include "ProcessMonitor.h"
32 #include "RegisterContextPOSIXProcessMonitor_arm.h"
33 #include "RegisterContextPOSIXProcessMonitor_arm64.h"
34 #include "RegisterContextPOSIXProcessMonitor_mips64.h"
35 #include "RegisterContextPOSIXProcessMonitor_powerpc.h"
36 #include "RegisterContextPOSIXProcessMonitor_x86.h"
37 #include "lldb/Breakpoint/BreakpointLocation.h"
38 #include "lldb/Breakpoint/Watchpoint.h"
39 #include "lldb/Core/Debugger.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 "lldb/Utility/State.h"
48 #include "llvm/ADT/SmallString.h"
49
50 using namespace lldb;
51 using namespace lldb_private;
52
53 FreeBSDThread::FreeBSDThread(Process &process, lldb::tid_t tid)
54     : Thread(process, tid), m_frame_up(), m_breakpoint(),
55       m_thread_name_valid(false), m_thread_name(), m_posix_thread(nullptr) {
56   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
57   LLDB_LOGV(log, "tid = {0}", 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 has been
68       // created since that watchpoint was enabled.  Since the
69       // POSIXBreakpointProtocol has yet to be initialized, its
70       // m_watchpoints_initialized member will be FALSE.  Attempting to read
71       // the debug status register to determine if a watchpoint has been hit
72       // would result in the zeroing of that register. Since the active debug
73       // registers would have been cloned when this thread was created, simply
74       // force the m_watchpoints_initized member to TRUE and avoid resetting
75       // 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 the
97   // right thing. if (StateIsStoppedState(GetState())
98   {
99     const bool force = false;
100     GetRegisterContext()->InvalidateIfNeeded(force);
101   }
102 }
103
104 const char *FreeBSDThread::GetInfo() { return nullptr; }
105
106 void FreeBSDThread::SetName(const char *name) {
107   m_thread_name_valid = (name && name[0]);
108   if (m_thread_name_valid)
109     m_thread_name.assign(name);
110   else
111     m_thread_name.clear();
112 }
113
114 const char *FreeBSDThread::GetName() {
115   if (!m_thread_name_valid) {
116     m_thread_name.clear();
117     int pid = GetProcess()->GetID();
118
119     struct kinfo_proc *kp = nullptr, *nkp;
120     size_t len = 0;
121     int error;
122     int ctl[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_INC_THREAD,
123                   pid};
124
125     while (1) {
126       error = sysctl(ctl, 4, kp, &len, nullptr, 0);
127       if (kp == nullptr || (error != 0 && errno == ENOMEM)) {
128         // Add extra space in case threads are added before next call.
129         len += sizeof(*kp) + len / 10;
130         nkp = (struct kinfo_proc *)realloc(kp, len);
131         if (nkp == nullptr) {
132           free(kp);
133           return nullptr;
134         }
135         kp = nkp;
136         continue;
137       }
138       if (error != 0)
139         len = 0;
140       break;
141     }
142
143     for (size_t i = 0; i < len / sizeof(*kp); i++) {
144       if (kp[i].ki_tid == (lwpid_t)GetID()) {
145         m_thread_name.append(kp[i].ki_tdname,
146                              kp[i].ki_tdname + strlen(kp[i].ki_tdname));
147         break;
148       }
149     }
150     free(kp);
151     m_thread_name_valid = true;
152   }
153
154   if (m_thread_name.empty())
155     return nullptr;
156   return m_thread_name.c_str();
157 }
158
159 lldb::RegisterContextSP FreeBSDThread::GetRegisterContext() {
160   if (!m_reg_context_sp) {
161     m_posix_thread = nullptr;
162
163     RegisterInfoInterface *reg_interface = nullptr;
164     const ArchSpec &target_arch = GetProcess()->GetTarget().GetArchitecture();
165
166     switch (target_arch.GetMachine()) {
167     case llvm::Triple::aarch64:
168       reg_interface = new RegisterInfoPOSIX_arm64(target_arch);
169       break;
170     case llvm::Triple::arm:
171       reg_interface = new RegisterInfoPOSIX_arm(target_arch);
172       break;
173     case llvm::Triple::ppc:
174 #ifndef __powerpc64__
175       reg_interface = new RegisterContextFreeBSD_powerpc32(target_arch);
176       break;
177 #endif
178     case llvm::Triple::ppc64:
179       reg_interface = new RegisterContextFreeBSD_powerpc64(target_arch);
180       break;
181     case llvm::Triple::mips64:
182       reg_interface = new RegisterContextFreeBSD_mips64(target_arch);
183       break;
184     case llvm::Triple::x86:
185       reg_interface = new RegisterContextFreeBSD_i386(target_arch);
186       break;
187     case llvm::Triple::x86_64:
188       reg_interface = new RegisterContextFreeBSD_x86_64(target_arch);
189       break;
190     default:
191       llvm_unreachable("CPU not supported");
192     }
193
194     switch (target_arch.GetMachine()) {
195     case llvm::Triple::aarch64: {
196       RegisterContextPOSIXProcessMonitor_arm64 *reg_ctx =
197           new RegisterContextPOSIXProcessMonitor_arm64(*this, 0, reg_interface);
198       m_posix_thread = reg_ctx;
199       m_reg_context_sp.reset(reg_ctx);
200       break;
201     }
202     case llvm::Triple::arm: {
203       RegisterContextPOSIXProcessMonitor_arm *reg_ctx =
204           new RegisterContextPOSIXProcessMonitor_arm(*this, 0, reg_interface);
205       m_posix_thread = reg_ctx;
206       m_reg_context_sp.reset(reg_ctx);
207       break;
208     }
209     case llvm::Triple::mips64: {
210       RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx =
211           new RegisterContextPOSIXProcessMonitor_mips64(*this, 0,
212                                                         reg_interface);
213       m_posix_thread = reg_ctx;
214       m_reg_context_sp.reset(reg_ctx);
215       break;
216     }
217     case llvm::Triple::ppc:
218     case llvm::Triple::ppc64: {
219       RegisterContextPOSIXProcessMonitor_powerpc *reg_ctx =
220           new RegisterContextPOSIXProcessMonitor_powerpc(*this, 0,
221                                                          reg_interface);
222       m_posix_thread = reg_ctx;
223       m_reg_context_sp.reset(reg_ctx);
224       break;
225     }
226     case llvm::Triple::x86:
227     case llvm::Triple::x86_64: {
228       RegisterContextPOSIXProcessMonitor_x86_64 *reg_ctx =
229           new RegisterContextPOSIXProcessMonitor_x86_64(*this, 0,
230                                                         reg_interface);
231       m_posix_thread = reg_ctx;
232       m_reg_context_sp.reset(reg_ctx);
233       break;
234     }
235     default:
236       break;
237     }
238   }
239   return m_reg_context_sp;
240 }
241
242 lldb::RegisterContextSP
243 FreeBSDThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame) {
244   lldb::RegisterContextSP reg_ctx_sp;
245   uint32_t concrete_frame_idx = 0;
246
247   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
248   LLDB_LOGV(log, "called");
249
250   if (frame)
251     concrete_frame_idx = frame->GetConcreteFrameIndex();
252
253   if (concrete_frame_idx == 0)
254     reg_ctx_sp = GetRegisterContext();
255   else {
256     assert(GetUnwinder());
257     reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame);
258   }
259
260   return reg_ctx_sp;
261 }
262
263 lldb::addr_t FreeBSDThread::GetThreadPointer() {
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 FreeBSDThread::CalculateStopInfo() {
273   SetStopInfo(m_stop_info_sp);
274   return true;
275 }
276
277 Unwind *FreeBSDThread::GetUnwinder() {
278   if (!m_unwinder_up)
279     m_unwinder_up.reset(new UnwindLLDB(*this));
280
281   return m_unwinder_up.get();
282 }
283
284 void FreeBSDThread::DidStop() {
285   // Don't set the thread state to stopped unless we really stopped.
286 }
287
288 void FreeBSDThread::WillResume(lldb::StateType resume_state) {
289   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
290   if (log)
291     log->Printf("tid %" PRIu64 " resume_state = %s", GetID(),
292                 lldb_private::StateAsCString(resume_state));
293   ProcessSP process_sp(GetProcess());
294   ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(process_sp.get());
295   int signo = GetResumeSignal();
296   bool signo_valid = process->GetUnixSignals()->SignalIsValid(signo);
297
298   switch (resume_state) {
299   case eStateSuspended:
300   case eStateStopped:
301     process->m_suspend_tids.push_back(GetID());
302     break;
303   case eStateRunning:
304     process->m_run_tids.push_back(GetID());
305     if (signo_valid)
306       process->m_resume_signo = signo;
307     break;
308   case eStateStepping:
309     process->m_step_tids.push_back(GetID());
310     if (signo_valid)
311       process->m_resume_signo = signo;
312     break;
313   default:
314     break;
315   }
316 }
317
318 bool FreeBSDThread::Resume() {
319   lldb::StateType resume_state = GetResumeState();
320   ProcessMonitor &monitor = GetMonitor();
321   bool status;
322
323   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
324   if (log)
325     log->Printf("FreeBSDThread::%s (), resume_state = %s", __FUNCTION__,
326                 StateAsCString(resume_state));
327
328   switch (resume_state) {
329   default:
330     assert(false && "Unexpected state for resume!");
331     status = false;
332     break;
333
334   case lldb::eStateRunning:
335     SetState(resume_state);
336     status = monitor.Resume(GetID(), GetResumeSignal());
337     break;
338
339   case lldb::eStateStepping:
340     SetState(resume_state);
341     status = monitor.SingleStep(GetID(), GetResumeSignal());
342     break;
343   case lldb::eStateStopped:
344   case lldb::eStateSuspended:
345     status = true;
346     break;
347   }
348
349   return status;
350 }
351
352 void FreeBSDThread::Notify(const ProcessMessage &message) {
353   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
354   if (log)
355     log->Printf("FreeBSDThread::%s () message kind = '%s' for tid %" PRIu64,
356                 __FUNCTION__, message.PrintKind(), GetID());
357
358   switch (message.GetKind()) {
359   default:
360     assert(false && "Unexpected message kind!");
361     break;
362
363   case ProcessMessage::eExitMessage:
364     // Nothing to be done.
365     break;
366
367   case ProcessMessage::eLimboMessage:
368     LimboNotify(message);
369     break;
370
371   case ProcessMessage::eCrashMessage:
372   case ProcessMessage::eSignalMessage:
373     SignalNotify(message);
374     break;
375
376   case ProcessMessage::eSignalDeliveredMessage:
377     SignalDeliveredNotify(message);
378     break;
379
380   case ProcessMessage::eTraceMessage:
381     TraceNotify(message);
382     break;
383
384   case ProcessMessage::eBreakpointMessage:
385     BreakNotify(message);
386     break;
387
388   case ProcessMessage::eWatchpointMessage:
389     WatchNotify(message);
390     break;
391
392   case ProcessMessage::eExecMessage:
393     ExecNotify(message);
394     break;
395   }
396 }
397
398 bool FreeBSDThread::EnableHardwareWatchpoint(Watchpoint *wp) {
399   bool wp_set = false;
400   if (wp) {
401     addr_t wp_addr = wp->GetLoadAddress();
402     size_t wp_size = wp->GetByteSize();
403     bool wp_read = wp->WatchpointRead();
404     bool wp_write = wp->WatchpointWrite();
405     uint32_t wp_hw_index = wp->GetHardwareIndex();
406     POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
407     if (reg_ctx)
408       wp_set = reg_ctx->SetHardwareWatchpointWithIndex(
409           wp_addr, wp_size, wp_read, wp_write, wp_hw_index);
410   }
411   return wp_set;
412 }
413
414 bool FreeBSDThread::DisableHardwareWatchpoint(Watchpoint *wp) {
415   bool result = false;
416   if (wp) {
417     lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext();
418     if (reg_ctx_sp.get())
419       result = reg_ctx_sp->ClearHardwareWatchpoint(wp->GetHardwareIndex());
420   }
421   return result;
422 }
423
424 uint32_t FreeBSDThread::NumSupportedHardwareWatchpoints() {
425   lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext();
426   if (reg_ctx_sp.get())
427     return reg_ctx_sp->NumSupportedHardwareWatchpoints();
428   return 0;
429 }
430
431 uint32_t FreeBSDThread::FindVacantWatchpointIndex() {
432   uint32_t hw_index = LLDB_INVALID_INDEX32;
433   uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
434   uint32_t wp_idx;
435   POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
436   if (reg_ctx) {
437     for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
438       if (reg_ctx->IsWatchpointVacant(wp_idx)) {
439         hw_index = wp_idx;
440         break;
441       }
442     }
443   }
444   return hw_index;
445 }
446
447 void FreeBSDThread::BreakNotify(const ProcessMessage &message) {
448   bool status;
449   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
450
451   assert(GetRegisterContext());
452   status = GetPOSIXBreakpointProtocol()->UpdateAfterBreakpoint();
453   assert(status && "Breakpoint update failed!");
454
455   // With our register state restored, resolve the breakpoint object
456   // corresponding to our current PC.
457   assert(GetRegisterContext());
458   lldb::addr_t pc = GetRegisterContext()->GetPC();
459   if (log)
460     log->Printf("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
461   lldb::BreakpointSiteSP bp_site(
462       GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
463
464   // If the breakpoint is for this thread, then we'll report the hit, but if it
465   // is for another thread, we create a stop reason with should_stop=false.  If
466   // there is no breakpoint location, then report an invalid stop reason. We
467   // don't need to worry about stepping over the breakpoint here, that will be
468   // taken care of when the thread resumes and notices that there's a
469   // breakpoint under the pc.
470   if (bp_site) {
471     lldb::break_id_t bp_id = bp_site->GetID();
472     // If we have an operating system plug-in, we might have set a thread
473     // specific breakpoint using the operating system thread ID, so we can't
474     // make any assumptions about the thread ID so we must always report the
475     // breakpoint regardless of the thread.
476     if (bp_site->ValidForThisThread(this) ||
477         GetProcess()->GetOperatingSystem() != nullptr)
478       SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id));
479     else {
480       const bool should_stop = false;
481       SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id,
482                                                                  should_stop));
483     }
484   } else
485     SetStopInfo(StopInfoSP());
486 }
487
488 void FreeBSDThread::WatchNotify(const ProcessMessage &message) {
489   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
490
491   lldb::addr_t halt_addr = message.GetHWAddress();
492   if (log)
493     log->Printf(
494         "FreeBSDThread::%s () Hardware Watchpoint Address = 0x%8.8" PRIx64,
495         __FUNCTION__, halt_addr);
496
497   POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
498   if (reg_ctx) {
499     uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
500     uint32_t wp_idx;
501     for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
502       if (reg_ctx->IsWatchpointHit(wp_idx)) {
503         // Clear the watchpoint hit here
504         reg_ctx->ClearWatchpointHits();
505         break;
506       }
507     }
508
509     if (wp_idx == num_hw_wps)
510       return;
511
512     Target &target = GetProcess()->GetTarget();
513     lldb::addr_t wp_monitor_addr = reg_ctx->GetWatchpointAddress(wp_idx);
514     const WatchpointList &wp_list = target.GetWatchpointList();
515     lldb::WatchpointSP wp_sp = wp_list.FindByAddress(wp_monitor_addr);
516
517     assert(wp_sp.get() && "No watchpoint found");
518     SetStopInfo(
519         StopInfo::CreateStopReasonWithWatchpointID(*this, wp_sp->GetID()));
520   }
521 }
522
523 void FreeBSDThread::TraceNotify(const ProcessMessage &message) {
524   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
525
526   // Try to resolve the breakpoint object corresponding to the current PC.
527   assert(GetRegisterContext());
528   lldb::addr_t pc = GetRegisterContext()->GetPC();
529   if (log)
530     log->Printf("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
531   lldb::BreakpointSiteSP bp_site(
532       GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
533
534   // If the current pc is a breakpoint site then set the StopInfo to
535   // Breakpoint. Otherwise, set the StopInfo to Watchpoint or Trace. If we have
536   // an operating system plug-in, we might have set a thread specific
537   // breakpoint using the operating system thread ID, so we can't make any
538   // assumptions about the thread ID so we must always report the breakpoint
539   // regardless of the thread.
540   if (bp_site && (bp_site->ValidForThisThread(this) ||
541                   GetProcess()->GetOperatingSystem() != nullptr))
542     SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(
543         *this, bp_site->GetID()));
544   else {
545     POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
546     if (reg_ctx) {
547       uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
548       uint32_t wp_idx;
549       for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
550         if (reg_ctx->IsWatchpointHit(wp_idx)) {
551           WatchNotify(message);
552           return;
553         }
554       }
555     }
556     SetStopInfo(StopInfo::CreateStopReasonToTrace(*this));
557   }
558 }
559
560 void FreeBSDThread::LimboNotify(const ProcessMessage &message) {
561   SetStopInfo(lldb::StopInfoSP(new POSIXLimboStopInfo(*this)));
562 }
563
564 void FreeBSDThread::SignalNotify(const ProcessMessage &message) {
565   int signo = message.GetSignal();
566   if (message.GetKind() == ProcessMessage::eCrashMessage) {
567     std::string stop_description = GetCrashReasonString(
568         message.GetCrashReason(), message.GetFaultAddress());
569     SetStopInfo(StopInfo::CreateStopReasonWithSignal(
570         *this, signo, stop_description.c_str()));
571   } else {
572     SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
573   }
574 }
575
576 void FreeBSDThread::SignalDeliveredNotify(const ProcessMessage &message) {
577   int signo = message.GetSignal();
578   SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
579 }
580
581 unsigned FreeBSDThread::GetRegisterIndexFromOffset(unsigned offset) {
582   unsigned reg = LLDB_INVALID_REGNUM;
583   ArchSpec arch = HostInfo::GetArchitecture();
584
585   switch (arch.GetMachine()) {
586   default:
587     llvm_unreachable("CPU type not supported!");
588     break;
589
590   case llvm::Triple::aarch64:
591   case llvm::Triple::arm:
592   case llvm::Triple::mips64:
593   case llvm::Triple::ppc:
594   case llvm::Triple::ppc64:
595   case llvm::Triple::x86:
596   case llvm::Triple::x86_64: {
597     POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
598     reg = reg_ctx->GetRegisterIndexFromOffset(offset);
599   } break;
600   }
601   return reg;
602 }
603
604 void FreeBSDThread::ExecNotify(const ProcessMessage &message) {
605   SetStopInfo(StopInfo::CreateStopReasonWithExec(*this));
606 }
607
608 const char *FreeBSDThread::GetRegisterName(unsigned reg) {
609   const char *name = nullptr;
610   ArchSpec arch = HostInfo::GetArchitecture();
611
612   switch (arch.GetMachine()) {
613   default:
614     assert(false && "CPU type not supported!");
615     break;
616
617   case llvm::Triple::aarch64:
618   case llvm::Triple::arm:
619   case llvm::Triple::mips64:
620   case llvm::Triple::ppc:
621   case llvm::Triple::ppc64:
622   case llvm::Triple::x86:
623   case llvm::Triple::x86_64:
624     name = GetRegisterContext()->GetRegisterName(reg);
625     break;
626   }
627   return name;
628 }
629
630 const char *FreeBSDThread::GetRegisterNameFromOffset(unsigned offset) {
631   return GetRegisterName(GetRegisterIndexFromOffset(offset));
632 }