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