]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp
MFV r339226 (peter): Record merge of serf-1.3.9.
[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     switch (target_arch.GetMachine()) {
173     case llvm::Triple::aarch64:
174       reg_interface = new RegisterInfoPOSIX_arm64(target_arch);
175       break;
176     case llvm::Triple::arm:
177       reg_interface = new RegisterInfoPOSIX_arm(target_arch);
178       break;
179     case llvm::Triple::ppc:
180 #ifndef __powerpc64__
181       reg_interface = new RegisterContextFreeBSD_powerpc32(target_arch);
182       break;
183 #endif
184     case llvm::Triple::ppc64:
185       reg_interface = new RegisterContextFreeBSD_powerpc64(target_arch);
186       break;
187     case llvm::Triple::mips64:
188       reg_interface = new RegisterContextFreeBSD_mips64(target_arch);
189       break;
190     case llvm::Triple::x86:
191       reg_interface = new RegisterContextFreeBSD_i386(target_arch);
192       break;
193     case llvm::Triple::x86_64:
194       reg_interface = new RegisterContextFreeBSD_x86_64(target_arch);
195       break;
196     default:
197       llvm_unreachable("CPU not supported");
198     }
199
200     switch (target_arch.GetMachine()) {
201     case llvm::Triple::aarch64: {
202       RegisterContextPOSIXProcessMonitor_arm64 *reg_ctx =
203           new RegisterContextPOSIXProcessMonitor_arm64(*this, 0, reg_interface);
204       m_posix_thread = reg_ctx;
205       m_reg_context_sp.reset(reg_ctx);
206       break;
207     }
208     case llvm::Triple::arm: {
209       RegisterContextPOSIXProcessMonitor_arm *reg_ctx =
210           new RegisterContextPOSIXProcessMonitor_arm(*this, 0, reg_interface);
211       m_posix_thread = reg_ctx;
212       m_reg_context_sp.reset(reg_ctx);
213       break;
214     }
215     case llvm::Triple::mips64: {
216       RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx =
217           new RegisterContextPOSIXProcessMonitor_mips64(*this, 0,
218                                                         reg_interface);
219       m_posix_thread = reg_ctx;
220       m_reg_context_sp.reset(reg_ctx);
221       break;
222     }
223     case llvm::Triple::ppc:
224     case llvm::Triple::ppc64: {
225       RegisterContextPOSIXProcessMonitor_powerpc *reg_ctx =
226           new RegisterContextPOSIXProcessMonitor_powerpc(*this, 0,
227                                                          reg_interface);
228       m_posix_thread = reg_ctx;
229       m_reg_context_sp.reset(reg_ctx);
230       break;
231     }
232     case llvm::Triple::x86:
233     case llvm::Triple::x86_64: {
234       RegisterContextPOSIXProcessMonitor_x86_64 *reg_ctx =
235           new RegisterContextPOSIXProcessMonitor_x86_64(*this, 0,
236                                                         reg_interface);
237       m_posix_thread = reg_ctx;
238       m_reg_context_sp.reset(reg_ctx);
239       break;
240     }
241     default:
242       break;
243     }
244   }
245   return m_reg_context_sp;
246 }
247
248 lldb::RegisterContextSP
249 FreeBSDThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame) {
250   lldb::RegisterContextSP reg_ctx_sp;
251   uint32_t concrete_frame_idx = 0;
252
253   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
254   LLDB_LOGV(log, "called");
255
256   if (frame)
257     concrete_frame_idx = frame->GetConcreteFrameIndex();
258
259   if (concrete_frame_idx == 0)
260     reg_ctx_sp = GetRegisterContext();
261   else {
262     assert(GetUnwinder());
263     reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame);
264   }
265
266   return reg_ctx_sp;
267 }
268
269 lldb::addr_t FreeBSDThread::GetThreadPointer() {
270   ProcessMonitor &monitor = GetMonitor();
271   addr_t addr;
272   if (monitor.ReadThreadPointer(GetID(), addr))
273     return addr;
274   else
275     return LLDB_INVALID_ADDRESS;
276 }
277
278 bool FreeBSDThread::CalculateStopInfo() {
279   SetStopInfo(m_stop_info_sp);
280   return true;
281 }
282
283 Unwind *FreeBSDThread::GetUnwinder() {
284   if (m_unwinder_ap.get() == NULL)
285     m_unwinder_ap.reset(new UnwindLLDB(*this));
286
287   return m_unwinder_ap.get();
288 }
289
290 void FreeBSDThread::DidStop() {
291   // Don't set the thread state to stopped unless we really stopped.
292 }
293
294 void FreeBSDThread::WillResume(lldb::StateType resume_state) {
295   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
296   if (log)
297     log->Printf("tid %" PRIu64 " resume_state = %s", GetID(),
298                 lldb_private::StateAsCString(resume_state));
299   ProcessSP process_sp(GetProcess());
300   ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(process_sp.get());
301   int signo = GetResumeSignal();
302   bool signo_valid = process->GetUnixSignals()->SignalIsValid(signo);
303
304   switch (resume_state) {
305   case eStateSuspended:
306   case eStateStopped:
307     process->m_suspend_tids.push_back(GetID());
308     break;
309   case eStateRunning:
310     process->m_run_tids.push_back(GetID());
311     if (signo_valid)
312       process->m_resume_signo = signo;
313     break;
314   case eStateStepping:
315     process->m_step_tids.push_back(GetID());
316     if (signo_valid)
317       process->m_resume_signo = signo;
318     break;
319   default:
320     break;
321   }
322 }
323
324 bool FreeBSDThread::Resume() {
325   lldb::StateType resume_state = GetResumeState();
326   ProcessMonitor &monitor = GetMonitor();
327   bool status;
328
329   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
330   if (log)
331     log->Printf("FreeBSDThread::%s (), resume_state = %s", __FUNCTION__,
332                 StateAsCString(resume_state));
333
334   switch (resume_state) {
335   default:
336     assert(false && "Unexpected state for resume!");
337     status = false;
338     break;
339
340   case lldb::eStateRunning:
341     SetState(resume_state);
342     status = monitor.Resume(GetID(), GetResumeSignal());
343     break;
344
345   case lldb::eStateStepping:
346     SetState(resume_state);
347     status = monitor.SingleStep(GetID(), GetResumeSignal());
348     break;
349   case lldb::eStateStopped:
350   case lldb::eStateSuspended:
351     status = true;
352     break;
353   }
354
355   return status;
356 }
357
358 void FreeBSDThread::Notify(const ProcessMessage &message) {
359   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
360   if (log)
361     log->Printf("FreeBSDThread::%s () message kind = '%s' for tid %" PRIu64,
362                 __FUNCTION__, message.PrintKind(), GetID());
363
364   switch (message.GetKind()) {
365   default:
366     assert(false && "Unexpected message kind!");
367     break;
368
369   case ProcessMessage::eExitMessage:
370     // Nothing to be done.
371     break;
372
373   case ProcessMessage::eLimboMessage:
374     LimboNotify(message);
375     break;
376
377   case ProcessMessage::eCrashMessage:
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::eExecMessage:
399     ExecNotify(message);
400     break;
401   }
402 }
403
404 bool FreeBSDThread::EnableHardwareWatchpoint(Watchpoint *wp) {
405   bool wp_set = false;
406   if (wp) {
407     addr_t wp_addr = wp->GetLoadAddress();
408     size_t wp_size = wp->GetByteSize();
409     bool wp_read = wp->WatchpointRead();
410     bool wp_write = wp->WatchpointWrite();
411     uint32_t wp_hw_index = wp->GetHardwareIndex();
412     POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
413     if (reg_ctx)
414       wp_set = reg_ctx->SetHardwareWatchpointWithIndex(
415           wp_addr, wp_size, wp_read, wp_write, wp_hw_index);
416   }
417   return wp_set;
418 }
419
420 bool FreeBSDThread::DisableHardwareWatchpoint(Watchpoint *wp) {
421   bool result = false;
422   if (wp) {
423     lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext();
424     if (reg_ctx_sp.get())
425       result = reg_ctx_sp->ClearHardwareWatchpoint(wp->GetHardwareIndex());
426   }
427   return result;
428 }
429
430 uint32_t FreeBSDThread::NumSupportedHardwareWatchpoints() {
431   lldb::RegisterContextSP reg_ctx_sp = GetRegisterContext();
432   if (reg_ctx_sp.get())
433     return reg_ctx_sp->NumSupportedHardwareWatchpoints();
434   return 0;
435 }
436
437 uint32_t FreeBSDThread::FindVacantWatchpointIndex() {
438   uint32_t hw_index = LLDB_INVALID_INDEX32;
439   uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
440   uint32_t wp_idx;
441   POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
442   if (reg_ctx) {
443     for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
444       if (reg_ctx->IsWatchpointVacant(wp_idx)) {
445         hw_index = wp_idx;
446         break;
447       }
448     }
449   }
450   return hw_index;
451 }
452
453 void FreeBSDThread::BreakNotify(const ProcessMessage &message) {
454   bool status;
455   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
456
457   assert(GetRegisterContext());
458   status = GetPOSIXBreakpointProtocol()->UpdateAfterBreakpoint();
459   assert(status && "Breakpoint update failed!");
460
461   // With our register state restored, resolve the breakpoint object
462   // corresponding to our current PC.
463   assert(GetRegisterContext());
464   lldb::addr_t pc = GetRegisterContext()->GetPC();
465   if (log)
466     log->Printf("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
467   lldb::BreakpointSiteSP bp_site(
468       GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
469
470   // If the breakpoint is for this thread, then we'll report the hit, but if it
471   // is for another thread,
472   // we create a stop reason with should_stop=false.  If there is no breakpoint
473   // location, then report
474   // an invalid stop reason. We don't need to worry about stepping over the
475   // breakpoint here, that will
476   // be taken care of when the thread resumes and notices that there's a
477   // breakpoint under the pc.
478   if (bp_site) {
479     lldb::break_id_t bp_id = bp_site->GetID();
480     // If we have an operating system plug-in, we might have set a thread
481     // specific breakpoint using the
482     // operating system thread ID, so we can't make any assumptions about the
483     // thread ID so we must always
484     // report the breakpoint regardless of the thread.
485     if (bp_site->ValidForThisThread(this) ||
486         GetProcess()->GetOperatingSystem() != NULL)
487       SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id));
488     else {
489       const bool should_stop = false;
490       SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id,
491                                                                  should_stop));
492     }
493   } else
494     SetStopInfo(StopInfoSP());
495 }
496
497 void FreeBSDThread::WatchNotify(const ProcessMessage &message) {
498   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
499
500   lldb::addr_t halt_addr = message.GetHWAddress();
501   if (log)
502     log->Printf(
503         "FreeBSDThread::%s () Hardware Watchpoint Address = 0x%8.8" PRIx64,
504         __FUNCTION__, halt_addr);
505
506   POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
507   if (reg_ctx) {
508     uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
509     uint32_t wp_idx;
510     for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
511       if (reg_ctx->IsWatchpointHit(wp_idx)) {
512         // Clear the watchpoint hit here
513         reg_ctx->ClearWatchpointHits();
514         break;
515       }
516     }
517
518     if (wp_idx == num_hw_wps)
519       return;
520
521     Target &target = GetProcess()->GetTarget();
522     lldb::addr_t wp_monitor_addr = reg_ctx->GetWatchpointAddress(wp_idx);
523     const WatchpointList &wp_list = target.GetWatchpointList();
524     lldb::WatchpointSP wp_sp = wp_list.FindByAddress(wp_monitor_addr);
525
526     assert(wp_sp.get() && "No watchpoint found");
527     SetStopInfo(
528         StopInfo::CreateStopReasonWithWatchpointID(*this, wp_sp->GetID()));
529   }
530 }
531
532 void FreeBSDThread::TraceNotify(const ProcessMessage &message) {
533   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
534
535   // Try to resolve the breakpoint object corresponding to the current PC.
536   assert(GetRegisterContext());
537   lldb::addr_t pc = GetRegisterContext()->GetPC();
538   if (log)
539     log->Printf("FreeBSDThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
540   lldb::BreakpointSiteSP bp_site(
541       GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
542
543   // If the current pc is a breakpoint site then set the StopInfo to Breakpoint.
544   // Otherwise, set the StopInfo to Watchpoint or Trace.
545   // If we have an operating system plug-in, we might have set a thread specific
546   // breakpoint using the
547   // operating system thread ID, so we can't make any assumptions about the
548   // thread ID so we must always
549   // report the breakpoint regardless of the thread.
550   if (bp_site && (bp_site->ValidForThisThread(this) ||
551                   GetProcess()->GetOperatingSystem() != NULL))
552     SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID(
553         *this, bp_site->GetID()));
554   else {
555     POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
556     if (reg_ctx) {
557       uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
558       uint32_t wp_idx;
559       for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++) {
560         if (reg_ctx->IsWatchpointHit(wp_idx)) {
561           WatchNotify(message);
562           return;
563         }
564       }
565     }
566     SetStopInfo(StopInfo::CreateStopReasonToTrace(*this));
567   }
568 }
569
570 void FreeBSDThread::LimboNotify(const ProcessMessage &message) {
571   SetStopInfo(lldb::StopInfoSP(new POSIXLimboStopInfo(*this)));
572 }
573
574 void FreeBSDThread::SignalNotify(const ProcessMessage &message) {
575   int signo = message.GetSignal();
576   if (message.GetKind() == ProcessMessage::eCrashMessage) {
577     std::string stop_description = GetCrashReasonString(
578         message.GetCrashReason(), message.GetFaultAddress());
579     SetStopInfo(StopInfo::CreateStopReasonWithSignal(
580         *this, signo, stop_description.c_str()));
581   } else {
582     SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
583   }
584 }
585
586 void FreeBSDThread::SignalDeliveredNotify(const ProcessMessage &message) {
587   int signo = message.GetSignal();
588   SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, signo));
589 }
590
591 unsigned FreeBSDThread::GetRegisterIndexFromOffset(unsigned offset) {
592   unsigned reg = LLDB_INVALID_REGNUM;
593   ArchSpec arch = HostInfo::GetArchitecture();
594
595   switch (arch.GetMachine()) {
596   default:
597     llvm_unreachable("CPU type not supported!");
598     break;
599
600   case llvm::Triple::aarch64:
601   case llvm::Triple::arm:
602   case llvm::Triple::mips64:
603   case llvm::Triple::ppc:
604   case llvm::Triple::ppc64:
605   case llvm::Triple::x86:
606   case llvm::Triple::x86_64: {
607     POSIXBreakpointProtocol *reg_ctx = GetPOSIXBreakpointProtocol();
608     reg = reg_ctx->GetRegisterIndexFromOffset(offset);
609   } break;
610   }
611   return reg;
612 }
613
614 void FreeBSDThread::ExecNotify(const ProcessMessage &message) {
615   SetStopInfo(StopInfo::CreateStopReasonWithExec(*this));
616 }
617
618 const char *FreeBSDThread::GetRegisterName(unsigned reg) {
619   const char *name = nullptr;
620   ArchSpec arch = HostInfo::GetArchitecture();
621
622   switch (arch.GetMachine()) {
623   default:
624     assert(false && "CPU type not supported!");
625     break;
626
627   case llvm::Triple::aarch64:
628   case llvm::Triple::arm:
629   case llvm::Triple::mips64:
630   case llvm::Triple::ppc:
631   case llvm::Triple::ppc64:
632   case llvm::Triple::x86:
633   case llvm::Triple::x86_64:
634     name = GetRegisterContext()->GetRegisterName(reg);
635     break;
636   }
637   return name;
638 }
639
640 const char *FreeBSDThread::GetRegisterNameFromOffset(unsigned offset) {
641   return GetRegisterName(GetRegisterIndexFromOffset(offset));
642 }