1 //===-- NativeProcessFreeBSD.cpp ------------------------------------------===//
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 "NativeProcessFreeBSD.h"
10 
11 // clang-format off
12 #include <sys/types.h>
13 #include <sys/ptrace.h>
14 #include <sys/sysctl.h>
15 #include <sys/user.h>
16 #include <sys/wait.h>
17 #include <machine/elf.h>
18 // clang-format on
19 
20 #include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
21 #include "lldb/Host/HostProcess.h"
22 #include "lldb/Host/posix/ProcessLauncherPosixFork.h"
23 #include "lldb/Target/Process.h"
24 #include "lldb/Utility/State.h"
25 #include "llvm/Support/Errno.h"
26 
27 using namespace lldb;
28 using namespace lldb_private;
29 using namespace lldb_private::process_freebsd;
30 using namespace llvm;
31 
32 // Simple helper function to ensure flags are enabled on the given file
33 // descriptor.
34 static Status EnsureFDFlags(int fd, int flags) {
35   Status error;
36 
37   int status = fcntl(fd, F_GETFL);
38   if (status == -1) {
39     error.SetErrorToErrno();
40     return error;
41   }
42 
43   if (fcntl(fd, F_SETFL, status | flags) == -1) {
44     error.SetErrorToErrno();
45     return error;
46   }
47 
48   return error;
49 }
50 
51 // Public Static Methods
52 
53 llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
54 NativeProcessFreeBSD::Factory::Launch(ProcessLaunchInfo &launch_info,
55                                       NativeDelegate &native_delegate,
56                                       MainLoop &mainloop) const {
57   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
58 
59   Status status;
60   ::pid_t pid = ProcessLauncherPosixFork()
61                     .LaunchProcess(launch_info, status)
62                     .GetProcessId();
63   LLDB_LOG(log, "pid = {0:x}", pid);
64   if (status.Fail()) {
65     LLDB_LOG(log, "failed to launch process: {0}", status);
66     return status.ToError();
67   }
68 
69   // Wait for the child process to trap on its call to execve.
70   int wstatus;
71   ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
72   assert(wpid == pid);
73   (void)wpid;
74   if (!WIFSTOPPED(wstatus)) {
75     LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}",
76              WaitStatus::Decode(wstatus));
77     return llvm::make_error<StringError>("Could not sync with inferior process",
78                                          llvm::inconvertibleErrorCode());
79   }
80   LLDB_LOG(log, "inferior started, now in stopped state");
81 
82   ProcessInstanceInfo Info;
83   if (!Host::GetProcessInfo(pid, Info)) {
84     return llvm::make_error<StringError>("Cannot get process architecture",
85                                          llvm::inconvertibleErrorCode());
86   }
87 
88   // Set the architecture to the exe architecture.
89   LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,
90            Info.GetArchitecture().GetArchitectureName());
91 
92   std::unique_ptr<NativeProcessFreeBSD> process_up(new NativeProcessFreeBSD(
93       pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), native_delegate,
94       Info.GetArchitecture(), mainloop));
95 
96   status = process_up->SetupTrace();
97   if (status.Fail())
98     return status.ToError();
99 
100   for (const auto &thread : process_up->m_threads)
101     static_cast<NativeThreadFreeBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
102   process_up->SetState(StateType::eStateStopped, false);
103 
104   return std::move(process_up);
105 }
106 
107 llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
108 NativeProcessFreeBSD::Factory::Attach(
109     lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
110     MainLoop &mainloop) const {
111   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
112   LLDB_LOG(log, "pid = {0:x}", pid);
113 
114   // Retrieve the architecture for the running process.
115   ProcessInstanceInfo Info;
116   if (!Host::GetProcessInfo(pid, Info)) {
117     return llvm::make_error<StringError>("Cannot get process architecture",
118                                          llvm::inconvertibleErrorCode());
119   }
120 
121   std::unique_ptr<NativeProcessFreeBSD> process_up(new NativeProcessFreeBSD(
122       pid, -1, native_delegate, Info.GetArchitecture(), mainloop));
123 
124   Status status = process_up->Attach();
125   if (!status.Success())
126     return status.ToError();
127 
128   return std::move(process_up);
129 }
130 
131 NativeProcessFreeBSD::Extension
132 NativeProcessFreeBSD::Factory::GetSupportedExtensions() const {
133   return
134 #if defined(PT_COREDUMP)
135       Extension::savecore |
136 #endif
137       Extension::multiprocess | Extension::fork | Extension::vfork |
138       Extension::pass_signals | Extension::auxv | Extension::libraries_svr4;
139 }
140 
141 // Public Instance Methods
142 
143 NativeProcessFreeBSD::NativeProcessFreeBSD(::pid_t pid, int terminal_fd,
144                                            NativeDelegate &delegate,
145                                            const ArchSpec &arch,
146                                            MainLoop &mainloop)
147     : NativeProcessELF(pid, terminal_fd, delegate), m_arch(arch),
148       m_main_loop(mainloop) {
149   if (m_terminal_fd != -1) {
150     Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
151     assert(status.Success());
152   }
153 
154   Status status;
155   m_sigchld_handle = mainloop.RegisterSignal(
156       SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status);
157   assert(m_sigchld_handle && status.Success());
158 }
159 
160 // Handles all waitpid events from the inferior process.
161 void NativeProcessFreeBSD::MonitorCallback(lldb::pid_t pid, int signal) {
162   switch (signal) {
163   case SIGTRAP:
164     return MonitorSIGTRAP(pid);
165   case SIGSTOP:
166     return MonitorSIGSTOP(pid);
167   default:
168     return MonitorSignal(pid, signal);
169   }
170 }
171 
172 void NativeProcessFreeBSD::MonitorExited(lldb::pid_t pid, WaitStatus status) {
173   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
174 
175   LLDB_LOG(log, "got exit signal({0}) , pid = {1}", status, pid);
176 
177   /* Stop Tracking All Threads attached to Process */
178   m_threads.clear();
179 
180   SetExitStatus(status, true);
181 
182   // Notify delegate that our process has exited.
183   SetState(StateType::eStateExited, true);
184 }
185 
186 void NativeProcessFreeBSD::MonitorSIGSTOP(lldb::pid_t pid) {
187   /* Stop all Threads attached to Process */
188   for (const auto &thread : m_threads) {
189     static_cast<NativeThreadFreeBSD &>(*thread).SetStoppedBySignal(SIGSTOP,
190                                                                    nullptr);
191   }
192   SetState(StateType::eStateStopped, true);
193 }
194 
195 void NativeProcessFreeBSD::MonitorSIGTRAP(lldb::pid_t pid) {
196   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
197   struct ptrace_lwpinfo info;
198 
199   const auto siginfo_err = PtraceWrapper(PT_LWPINFO, pid, &info, sizeof(info));
200   if (siginfo_err.Fail()) {
201     LLDB_LOG(log, "PT_LWPINFO failed {0}", siginfo_err);
202     return;
203   }
204   assert(info.pl_event == PL_EVENT_SIGNAL);
205 
206   LLDB_LOG(log, "got SIGTRAP, pid = {0}, lwpid = {1}, flags = {2:x}", pid,
207            info.pl_lwpid, info.pl_flags);
208   NativeThreadFreeBSD *thread = nullptr;
209 
210   if (info.pl_flags & (PL_FLAG_BORN | PL_FLAG_EXITED)) {
211     if (info.pl_flags & PL_FLAG_BORN) {
212       LLDB_LOG(log, "monitoring new thread, tid = {0}", info.pl_lwpid);
213       NativeThreadFreeBSD &t = AddThread(info.pl_lwpid);
214 
215       // Technically, the FreeBSD kernel copies the debug registers to new
216       // threads.  However, there is a non-negligible delay between acquiring
217       // the DR values and reporting the new thread during which the user may
218       // establish a new watchpoint.  In order to ensure that watchpoints
219       // established during this period are propagated to new threads,
220       // explicitly copy the DR value at the time the new thread is reported.
221       //
222       // See also: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=250954
223 
224       llvm::Error error = t.CopyWatchpointsFrom(
225           static_cast<NativeThreadFreeBSD &>(*GetCurrentThread()));
226       if (error) {
227         LLDB_LOG_ERROR(log, std::move(error),
228                        "failed to copy watchpoints to new thread {1}: {0}",
229                        info.pl_lwpid);
230         SetState(StateType::eStateInvalid);
231         return;
232       }
233     } else /*if (info.pl_flags & PL_FLAG_EXITED)*/ {
234       LLDB_LOG(log, "thread exited, tid = {0}", info.pl_lwpid);
235       RemoveThread(info.pl_lwpid);
236     }
237 
238     Status error =
239         PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0);
240     if (error.Fail())
241       SetState(StateType::eStateInvalid);
242     return;
243   }
244 
245   if (info.pl_flags & PL_FLAG_EXEC) {
246     Status error = ReinitializeThreads();
247     if (error.Fail()) {
248       SetState(StateType::eStateInvalid);
249       return;
250     }
251 
252     // Let our delegate know we have just exec'd.
253     NotifyDidExec();
254 
255     for (const auto &thread : m_threads)
256       static_cast<NativeThreadFreeBSD &>(*thread).SetStoppedByExec();
257     SetCurrentThreadID(m_threads.front()->GetID());
258     SetState(StateType::eStateStopped, true);
259     return;
260   }
261 
262   if (info.pl_lwpid > 0) {
263     for (const auto &t : m_threads) {
264       if (t->GetID() == static_cast<lldb::tid_t>(info.pl_lwpid))
265         thread = static_cast<NativeThreadFreeBSD *>(t.get());
266       static_cast<NativeThreadFreeBSD *>(t.get())->SetStoppedWithNoReason();
267     }
268     if (!thread)
269       LLDB_LOG(log, "thread not found in m_threads, pid = {0}, LWP = {1}", pid,
270                info.pl_lwpid);
271   }
272 
273   if (info.pl_flags & PL_FLAG_FORKED) {
274     assert(thread);
275     MonitorClone(info.pl_child_pid, info.pl_flags & PL_FLAG_VFORKED, *thread);
276     return;
277   }
278 
279   if (info.pl_flags & PL_FLAG_VFORK_DONE) {
280     assert(thread);
281     if ((m_enabled_extensions & Extension::vfork) == Extension::vfork) {
282       thread->SetStoppedByVForkDone();
283       SetState(StateType::eStateStopped, true);
284     } else {
285       Status error =
286           PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0);
287       if (error.Fail())
288         SetState(StateType::eStateInvalid);
289     }
290     return;
291   }
292 
293   if (info.pl_flags & PL_FLAG_SI) {
294     assert(info.pl_siginfo.si_signo == SIGTRAP);
295     LLDB_LOG(log, "SIGTRAP siginfo: si_code = {0}, pid = {1}",
296              info.pl_siginfo.si_code, info.pl_siginfo.si_pid);
297 
298     switch (info.pl_siginfo.si_code) {
299     case TRAP_BRKPT:
300       LLDB_LOG(log, "SIGTRAP/TRAP_BRKPT: si_addr: {0}",
301                info.pl_siginfo.si_addr);
302 
303       if (thread) {
304         auto thread_info =
305             m_threads_stepping_with_breakpoint.find(thread->GetID());
306         if (thread_info != m_threads_stepping_with_breakpoint.end()) {
307           thread->SetStoppedByTrace();
308           Status brkpt_error = RemoveBreakpoint(thread_info->second);
309           if (brkpt_error.Fail())
310             LLDB_LOG(log, "pid = {0} remove stepping breakpoint: {1}",
311                      thread_info->first, brkpt_error);
312           m_threads_stepping_with_breakpoint.erase(thread_info);
313         } else
314           thread->SetStoppedByBreakpoint();
315         FixupBreakpointPCAsNeeded(*thread);
316         SetCurrentThreadID(thread->GetID());
317       }
318       SetState(StateType::eStateStopped, true);
319       return;
320     case TRAP_TRACE:
321       LLDB_LOG(log, "SIGTRAP/TRAP_TRACE: si_addr: {0}",
322                info.pl_siginfo.si_addr);
323 
324       if (thread) {
325         auto &regctx = static_cast<NativeRegisterContextFreeBSD &>(
326             thread->GetRegisterContext());
327         uint32_t wp_index = LLDB_INVALID_INDEX32;
328         Status error = regctx.GetWatchpointHitIndex(
329             wp_index, reinterpret_cast<uintptr_t>(info.pl_siginfo.si_addr));
330         if (error.Fail())
331           LLDB_LOG(log,
332                    "received error while checking for watchpoint hits, pid = "
333                    "{0}, LWP = {1}, error = {2}",
334                    pid, info.pl_lwpid, error);
335         if (wp_index != LLDB_INVALID_INDEX32) {
336           regctx.ClearWatchpointHit(wp_index);
337           thread->SetStoppedByWatchpoint(wp_index);
338           SetCurrentThreadID(thread->GetID());
339           SetState(StateType::eStateStopped, true);
340           break;
341         }
342 
343         thread->SetStoppedByTrace();
344         SetCurrentThreadID(thread->GetID());
345       }
346 
347       SetState(StateType::eStateStopped, true);
348       return;
349     }
350   }
351 
352   // Either user-generated SIGTRAP or an unknown event that would
353   // otherwise leave the debugger hanging.
354   LLDB_LOG(log, "unknown SIGTRAP, passing to generic handler");
355   MonitorSignal(pid, SIGTRAP);
356 }
357 
358 void NativeProcessFreeBSD::MonitorSignal(lldb::pid_t pid, int signal) {
359   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
360   struct ptrace_lwpinfo info;
361 
362   const auto siginfo_err = PtraceWrapper(PT_LWPINFO, pid, &info, sizeof(info));
363   if (siginfo_err.Fail()) {
364     LLDB_LOG(log, "PT_LWPINFO failed {0}", siginfo_err);
365     return;
366   }
367   assert(info.pl_event == PL_EVENT_SIGNAL);
368   // TODO: do we need to handle !PL_FLAG_SI?
369   assert(info.pl_flags & PL_FLAG_SI);
370   assert(info.pl_siginfo.si_signo == signal);
371 
372   for (const auto &abs_thread : m_threads) {
373     NativeThreadFreeBSD &thread =
374         static_cast<NativeThreadFreeBSD &>(*abs_thread);
375     assert(info.pl_lwpid >= 0);
376     if (info.pl_lwpid == 0 ||
377         static_cast<lldb::tid_t>(info.pl_lwpid) == thread.GetID()) {
378       thread.SetStoppedBySignal(info.pl_siginfo.si_signo, &info.pl_siginfo);
379       SetCurrentThreadID(thread.GetID());
380     } else
381       thread.SetStoppedWithNoReason();
382   }
383   SetState(StateType::eStateStopped, true);
384 }
385 
386 Status NativeProcessFreeBSD::PtraceWrapper(int req, lldb::pid_t pid, void *addr,
387                                            int data, int *result) {
388   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
389   Status error;
390   int ret;
391 
392   errno = 0;
393   ret =
394       ptrace(req, static_cast<::pid_t>(pid), static_cast<caddr_t>(addr), data);
395 
396   if (ret == -1)
397     error.SetErrorToErrno();
398 
399   if (result)
400     *result = ret;
401 
402   LLDB_LOG(log, "ptrace({0}, {1}, {2}, {3})={4:x}", req, pid, addr, data, ret);
403 
404   if (error.Fail())
405     LLDB_LOG(log, "ptrace() failed: {0}", error);
406 
407   return error;
408 }
409 
410 llvm::Expected<llvm::ArrayRef<uint8_t>>
411 NativeProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
412   static const uint8_t g_arm_opcode[] = {0xfe, 0xde, 0xff, 0xe7};
413   static const uint8_t g_thumb_opcode[] = {0x01, 0xde};
414 
415   switch (GetArchitecture().GetMachine()) {
416   case llvm::Triple::arm:
417     switch (size_hint) {
418     case 2:
419       return llvm::makeArrayRef(g_thumb_opcode);
420     case 4:
421       return llvm::makeArrayRef(g_arm_opcode);
422     default:
423       return llvm::createStringError(llvm::inconvertibleErrorCode(),
424                                      "Unrecognised trap opcode size hint!");
425     }
426   default:
427     return NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_hint);
428   }
429 }
430 
431 Status NativeProcessFreeBSD::Resume(const ResumeActionList &resume_actions) {
432   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
433   LLDB_LOG(log, "pid {0}", GetID());
434 
435   Status ret;
436 
437   int signal = 0;
438   for (const auto &abs_thread : m_threads) {
439     assert(abs_thread && "thread list should not contain NULL threads");
440     NativeThreadFreeBSD &thread =
441         static_cast<NativeThreadFreeBSD &>(*abs_thread);
442 
443     const ResumeAction *action =
444         resume_actions.GetActionForThread(thread.GetID(), true);
445     // we need to explicit issue suspend requests, so it is simpler to map it
446     // into proper action
447     ResumeAction suspend_action{thread.GetID(), eStateSuspended,
448                                 LLDB_INVALID_SIGNAL_NUMBER};
449 
450     if (action == nullptr) {
451       LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(),
452                thread.GetID());
453       action = &suspend_action;
454     }
455 
456     LLDB_LOG(
457         log,
458         "processing resume action state {0} signal {1} for pid {2} tid {3}",
459         action->state, action->signal, GetID(), thread.GetID());
460 
461     switch (action->state) {
462     case eStateRunning:
463       ret = thread.Resume();
464       break;
465     case eStateStepping:
466       ret = thread.SingleStep();
467       break;
468     case eStateSuspended:
469     case eStateStopped:
470       if (action->signal != LLDB_INVALID_SIGNAL_NUMBER)
471         return Status("Passing signal to suspended thread unsupported");
472 
473       ret = thread.Suspend();
474       break;
475 
476     default:
477       return Status(
478           "NativeProcessFreeBSD::%s (): unexpected state %s specified "
479           "for pid %" PRIu64 ", tid %" PRIu64,
480           __FUNCTION__, StateAsCString(action->state), GetID(), thread.GetID());
481     }
482 
483     if (!ret.Success())
484       return ret;
485     if (action->signal != LLDB_INVALID_SIGNAL_NUMBER)
486       signal = action->signal;
487   }
488 
489   ret =
490       PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1), signal);
491   if (ret.Success())
492     SetState(eStateRunning, true);
493   return ret;
494 }
495 
496 Status NativeProcessFreeBSD::Halt() {
497   Status error;
498 
499   if (kill(GetID(), SIGSTOP) != 0)
500     error.SetErrorToErrno();
501   return error;
502 }
503 
504 Status NativeProcessFreeBSD::Detach() {
505   Status error;
506 
507   // Stop monitoring the inferior.
508   m_sigchld_handle.reset();
509 
510   // Tell ptrace to detach from the process.
511   if (GetID() == LLDB_INVALID_PROCESS_ID)
512     return error;
513 
514   return PtraceWrapper(PT_DETACH, GetID());
515 }
516 
517 Status NativeProcessFreeBSD::Signal(int signo) {
518   Status error;
519 
520   if (kill(GetID(), signo))
521     error.SetErrorToErrno();
522 
523   return error;
524 }
525 
526 Status NativeProcessFreeBSD::Interrupt() { return Halt(); }
527 
528 Status NativeProcessFreeBSD::Kill() {
529   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
530   LLDB_LOG(log, "pid {0}", GetID());
531 
532   Status error;
533 
534   switch (m_state) {
535   case StateType::eStateInvalid:
536   case StateType::eStateExited:
537   case StateType::eStateCrashed:
538   case StateType::eStateDetached:
539   case StateType::eStateUnloaded:
540     // Nothing to do - the process is already dead.
541     LLDB_LOG(log, "ignored for PID {0} due to current state: {1}", GetID(),
542              StateAsCString(m_state));
543     return error;
544 
545   case StateType::eStateConnected:
546   case StateType::eStateAttaching:
547   case StateType::eStateLaunching:
548   case StateType::eStateStopped:
549   case StateType::eStateRunning:
550   case StateType::eStateStepping:
551   case StateType::eStateSuspended:
552     // We can try to kill a process in these states.
553     break;
554   }
555 
556   return PtraceWrapper(PT_KILL, m_pid);
557 }
558 
559 Status NativeProcessFreeBSD::GetMemoryRegionInfo(lldb::addr_t load_addr,
560                                                  MemoryRegionInfo &range_info) {
561 
562   if (m_supports_mem_region == LazyBool::eLazyBoolNo) {
563     // We're done.
564     return Status("unsupported");
565   }
566 
567   Status error = PopulateMemoryRegionCache();
568   if (error.Fail()) {
569     return error;
570   }
571 
572   lldb::addr_t prev_base_address = 0;
573   // FIXME start by finding the last region that is <= target address using
574   // binary search.  Data is sorted.
575   // There can be a ton of regions on pthreads apps with lots of threads.
576   for (auto it = m_mem_region_cache.begin(); it != m_mem_region_cache.end();
577        ++it) {
578     MemoryRegionInfo &proc_entry_info = it->first;
579     // Sanity check assumption that memory map entries are ascending.
580     assert((proc_entry_info.GetRange().GetRangeBase() >= prev_base_address) &&
581            "descending memory map entries detected, unexpected");
582     prev_base_address = proc_entry_info.GetRange().GetRangeBase();
583     UNUSED_IF_ASSERT_DISABLED(prev_base_address);
584     // If the target address comes before this entry, indicate distance to next
585     // region.
586     if (load_addr < proc_entry_info.GetRange().GetRangeBase()) {
587       range_info.GetRange().SetRangeBase(load_addr);
588       range_info.GetRange().SetByteSize(
589           proc_entry_info.GetRange().GetRangeBase() - load_addr);
590       range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
591       range_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
592       range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
593       range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
594       return error;
595     } else if (proc_entry_info.GetRange().Contains(load_addr)) {
596       // The target address is within the memory region we're processing here.
597       range_info = proc_entry_info;
598       return error;
599     }
600     // The target memory address comes somewhere after the region we just
601     // parsed.
602   }
603   // If we made it here, we didn't find an entry that contained the given
604   // address. Return the load_addr as start and the amount of bytes betwwen
605   // load address and the end of the memory as size.
606   range_info.GetRange().SetRangeBase(load_addr);
607   range_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
608   range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
609   range_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
610   range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
611   range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
612   return error;
613 }
614 
615 Status NativeProcessFreeBSD::PopulateMemoryRegionCache() {
616   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
617   // If our cache is empty, pull the latest.  There should always be at least
618   // one memory region if memory region handling is supported.
619   if (!m_mem_region_cache.empty()) {
620     LLDB_LOG(log, "reusing {0} cached memory region entries",
621              m_mem_region_cache.size());
622     return Status();
623   }
624 
625   int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, static_cast<int>(m_pid)};
626   int ret;
627   size_t len;
628 
629   ret = ::sysctl(mib, 4, nullptr, &len, nullptr, 0);
630   if (ret != 0) {
631     m_supports_mem_region = LazyBool::eLazyBoolNo;
632     return Status("sysctl() for KERN_PROC_VMMAP failed");
633   }
634 
635   std::unique_ptr<WritableMemoryBuffer> buf =
636       llvm::WritableMemoryBuffer::getNewMemBuffer(len);
637   ret = ::sysctl(mib, 4, buf->getBufferStart(), &len, nullptr, 0);
638   if (ret != 0) {
639     m_supports_mem_region = LazyBool::eLazyBoolNo;
640     return Status("sysctl() for KERN_PROC_VMMAP failed");
641   }
642 
643   char *bp = buf->getBufferStart();
644   char *end = bp + len;
645   while (bp < end) {
646     auto *kv = reinterpret_cast<struct kinfo_vmentry *>(bp);
647     if (kv->kve_structsize == 0)
648       break;
649     bp += kv->kve_structsize;
650 
651     MemoryRegionInfo info;
652     info.Clear();
653     info.GetRange().SetRangeBase(kv->kve_start);
654     info.GetRange().SetRangeEnd(kv->kve_end);
655     info.SetMapped(MemoryRegionInfo::OptionalBool::eYes);
656 
657     if (kv->kve_protection & VM_PROT_READ)
658       info.SetReadable(MemoryRegionInfo::OptionalBool::eYes);
659     else
660       info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
661 
662     if (kv->kve_protection & VM_PROT_WRITE)
663       info.SetWritable(MemoryRegionInfo::OptionalBool::eYes);
664     else
665       info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
666 
667     if (kv->kve_protection & VM_PROT_EXECUTE)
668       info.SetExecutable(MemoryRegionInfo::OptionalBool::eYes);
669     else
670       info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
671 
672     if (kv->kve_path[0])
673       info.SetName(kv->kve_path);
674 
675     m_mem_region_cache.emplace_back(info,
676                                     FileSpec(info.GetName().GetCString()));
677   }
678 
679   if (m_mem_region_cache.empty()) {
680     // No entries after attempting to read them.  This shouldn't happen. Assume
681     // we don't support map entries.
682     LLDB_LOG(log, "failed to find any vmmap entries, assuming no support "
683                   "for memory region metadata retrieval");
684     m_supports_mem_region = LazyBool::eLazyBoolNo;
685     return Status("not supported");
686   }
687   LLDB_LOG(log, "read {0} memory region entries from process {1}",
688            m_mem_region_cache.size(), GetID());
689   // We support memory retrieval, remember that.
690   m_supports_mem_region = LazyBool::eLazyBoolYes;
691 
692   return Status();
693 }
694 
695 size_t NativeProcessFreeBSD::UpdateThreads() { return m_threads.size(); }
696 
697 Status NativeProcessFreeBSD::SetBreakpoint(lldb::addr_t addr, uint32_t size,
698                                            bool hardware) {
699   if (hardware)
700     return SetHardwareBreakpoint(addr, size);
701   return SetSoftwareBreakpoint(addr, size);
702 }
703 
704 Status NativeProcessFreeBSD::GetLoadedModuleFileSpec(const char *module_path,
705                                                      FileSpec &file_spec) {
706   Status error = PopulateMemoryRegionCache();
707   if (error.Fail())
708     return error;
709 
710   FileSpec module_file_spec(module_path);
711   FileSystem::Instance().Resolve(module_file_spec);
712 
713   file_spec.Clear();
714   for (const auto &it : m_mem_region_cache) {
715     if (it.second.GetFilename() == module_file_spec.GetFilename()) {
716       file_spec = it.second;
717       return Status();
718     }
719   }
720   return Status("Module file (%s) not found in process' memory map!",
721                 module_file_spec.GetFilename().AsCString());
722 }
723 
724 Status
725 NativeProcessFreeBSD::GetFileLoadAddress(const llvm::StringRef &file_name,
726                                          lldb::addr_t &load_addr) {
727   load_addr = LLDB_INVALID_ADDRESS;
728   Status error = PopulateMemoryRegionCache();
729   if (error.Fail())
730     return error;
731 
732   FileSpec file(file_name);
733   for (const auto &it : m_mem_region_cache) {
734     if (it.second == file) {
735       load_addr = it.first.GetRange().GetRangeBase();
736       return Status();
737     }
738   }
739   return Status("No load address found for file %s.", file_name.str().c_str());
740 }
741 
742 void NativeProcessFreeBSD::SigchldHandler() {
743   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
744   int status;
745   ::pid_t wait_pid =
746       llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status, WNOHANG);
747 
748   if (wait_pid == 0)
749     return;
750 
751   if (wait_pid == -1) {
752     Status error(errno, eErrorTypePOSIX);
753     LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error);
754     return;
755   }
756 
757   WaitStatus wait_status = WaitStatus::Decode(status);
758   bool exited = wait_status.type == WaitStatus::Exit ||
759                 (wait_status.type == WaitStatus::Signal &&
760                  wait_pid == static_cast<::pid_t>(GetID()));
761 
762   LLDB_LOG(log,
763            "waitpid ({0}, &status, _) => pid = {1}, status = {2}, exited = {3}",
764            GetID(), wait_pid, status, exited);
765 
766   if (exited)
767     MonitorExited(wait_pid, wait_status);
768   else {
769     assert(wait_status.type == WaitStatus::Stop);
770     MonitorCallback(wait_pid, wait_status.status);
771   }
772 }
773 
774 bool NativeProcessFreeBSD::HasThreadNoLock(lldb::tid_t thread_id) {
775   for (const auto &thread : m_threads) {
776     assert(thread && "thread list should not contain NULL threads");
777     if (thread->GetID() == thread_id) {
778       // We have this thread.
779       return true;
780     }
781   }
782 
783   // We don't have this thread.
784   return false;
785 }
786 
787 NativeThreadFreeBSD &NativeProcessFreeBSD::AddThread(lldb::tid_t thread_id) {
788   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
789   LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id);
790 
791   assert(thread_id > 0);
792   assert(!HasThreadNoLock(thread_id) &&
793          "attempted to add a thread by id that already exists");
794 
795   // If this is the first thread, save it as the current thread
796   if (m_threads.empty())
797     SetCurrentThreadID(thread_id);
798 
799   m_threads.push_back(std::make_unique<NativeThreadFreeBSD>(*this, thread_id));
800   return static_cast<NativeThreadFreeBSD &>(*m_threads.back());
801 }
802 
803 void NativeProcessFreeBSD::RemoveThread(lldb::tid_t thread_id) {
804   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
805   LLDB_LOG(log, "pid {0} removing thread with tid {1}", GetID(), thread_id);
806 
807   assert(thread_id > 0);
808   assert(HasThreadNoLock(thread_id) &&
809          "attempted to remove a thread that does not exist");
810 
811   for (auto it = m_threads.begin(); it != m_threads.end(); ++it) {
812     if ((*it)->GetID() == thread_id) {
813       m_threads.erase(it);
814       break;
815     }
816   }
817 
818   if (GetCurrentThreadID() == thread_id)
819     SetCurrentThreadID(m_threads.front()->GetID());
820 }
821 
822 Status NativeProcessFreeBSD::Attach() {
823   // Attach to the requested process.
824   // An attach will cause the thread to stop with a SIGSTOP.
825   Status status = PtraceWrapper(PT_ATTACH, m_pid);
826   if (status.Fail())
827     return status;
828 
829   int wstatus;
830   // Need to use WALLSIG otherwise we receive an error with errno=ECHLD At this
831   // point we should have a thread stopped if waitpid succeeds.
832   if ((wstatus = llvm::sys::RetryAfterSignal(-1, waitpid, m_pid, nullptr, 0)) <
833       0)
834     return Status(errno, eErrorTypePOSIX);
835 
836   // Initialize threads and tracing status
837   // NB: this needs to be called before we set thread state
838   status = SetupTrace();
839   if (status.Fail())
840     return status;
841 
842   for (const auto &thread : m_threads)
843     static_cast<NativeThreadFreeBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
844 
845   // Let our process instance know the thread has stopped.
846   SetCurrentThreadID(m_threads.front()->GetID());
847   SetState(StateType::eStateStopped, false);
848   return Status();
849 }
850 
851 Status NativeProcessFreeBSD::ReadMemory(lldb::addr_t addr, void *buf,
852                                         size_t size, size_t &bytes_read) {
853   unsigned char *dst = static_cast<unsigned char *>(buf);
854   struct ptrace_io_desc io;
855 
856   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY));
857   LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
858 
859   bytes_read = 0;
860   io.piod_op = PIOD_READ_D;
861   io.piod_len = size;
862 
863   do {
864     io.piod_offs = (void *)(addr + bytes_read);
865     io.piod_addr = dst + bytes_read;
866 
867     Status error = NativeProcessFreeBSD::PtraceWrapper(PT_IO, GetID(), &io);
868     if (error.Fail() || io.piod_len == 0)
869       return error;
870 
871     bytes_read += io.piod_len;
872     io.piod_len = size - bytes_read;
873   } while (bytes_read < size);
874 
875   return Status();
876 }
877 
878 Status NativeProcessFreeBSD::WriteMemory(lldb::addr_t addr, const void *buf,
879                                          size_t size, size_t &bytes_written) {
880   const unsigned char *src = static_cast<const unsigned char *>(buf);
881   Status error;
882   struct ptrace_io_desc io;
883 
884   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY));
885   LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
886 
887   bytes_written = 0;
888   io.piod_op = PIOD_WRITE_D;
889   io.piod_len = size;
890 
891   do {
892     io.piod_addr =
893         const_cast<void *>(static_cast<const void *>(src + bytes_written));
894     io.piod_offs = (void *)(addr + bytes_written);
895 
896     Status error = NativeProcessFreeBSD::PtraceWrapper(PT_IO, GetID(), &io);
897     if (error.Fail() || io.piod_len == 0)
898       return error;
899 
900     bytes_written += io.piod_len;
901     io.piod_len = size - bytes_written;
902   } while (bytes_written < size);
903 
904   return error;
905 }
906 
907 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
908 NativeProcessFreeBSD::GetAuxvData() const {
909   int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_AUXV, static_cast<int>(GetID())};
910   size_t auxv_size = AT_COUNT * sizeof(Elf_Auxinfo);
911   std::unique_ptr<WritableMemoryBuffer> buf =
912       llvm::WritableMemoryBuffer::getNewMemBuffer(auxv_size);
913 
914   if (::sysctl(mib, 4, buf->getBufferStart(), &auxv_size, nullptr, 0) != 0)
915     return std::error_code(errno, std::generic_category());
916 
917   return buf;
918 }
919 
920 Status NativeProcessFreeBSD::SetupTrace() {
921   // Enable event reporting
922   int events;
923   Status status =
924       PtraceWrapper(PT_GET_EVENT_MASK, GetID(), &events, sizeof(events));
925   if (status.Fail())
926     return status;
927   events |= PTRACE_LWP | PTRACE_FORK | PTRACE_VFORK;
928   status = PtraceWrapper(PT_SET_EVENT_MASK, GetID(), &events, sizeof(events));
929   if (status.Fail())
930     return status;
931 
932   return ReinitializeThreads();
933 }
934 
935 Status NativeProcessFreeBSD::ReinitializeThreads() {
936   // Clear old threads
937   m_threads.clear();
938 
939   int num_lwps;
940   Status error = PtraceWrapper(PT_GETNUMLWPS, GetID(), nullptr, 0, &num_lwps);
941   if (error.Fail())
942     return error;
943 
944   std::vector<lwpid_t> lwp_ids;
945   lwp_ids.resize(num_lwps);
946   error = PtraceWrapper(PT_GETLWPLIST, GetID(), lwp_ids.data(),
947                         lwp_ids.size() * sizeof(lwpid_t), &num_lwps);
948   if (error.Fail())
949     return error;
950 
951   // Reinitialize from scratch threads and register them in process
952   for (lwpid_t lwp : lwp_ids)
953     AddThread(lwp);
954 
955   return error;
956 }
957 
958 bool NativeProcessFreeBSD::SupportHardwareSingleStepping() const {
959   return !m_arch.IsMIPS();
960 }
961 
962 void NativeProcessFreeBSD::MonitorClone(::pid_t child_pid, bool is_vfork,
963                                         NativeThreadFreeBSD &parent_thread) {
964   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
965   LLDB_LOG(log, "fork, child_pid={0}", child_pid);
966 
967   int status;
968   ::pid_t wait_pid =
969       llvm::sys::RetryAfterSignal(-1, ::waitpid, child_pid, &status, 0);
970   if (wait_pid != child_pid) {
971     LLDB_LOG(log,
972              "waiting for pid {0} failed. Assuming the pid has "
973              "disappeared in the meantime",
974              child_pid);
975     return;
976   }
977   if (WIFEXITED(status)) {
978     LLDB_LOG(log,
979              "waiting for pid {0} returned an 'exited' event. Not "
980              "tracking it.",
981              child_pid);
982     return;
983   }
984 
985   struct ptrace_lwpinfo info;
986   const auto siginfo_err = PtraceWrapper(PT_LWPINFO, child_pid, &info, sizeof(info));
987   if (siginfo_err.Fail()) {
988     LLDB_LOG(log, "PT_LWPINFO failed {0}", siginfo_err);
989     return;
990   }
991   assert(info.pl_event == PL_EVENT_SIGNAL);
992   lldb::tid_t child_tid = info.pl_lwpid;
993 
994   std::unique_ptr<NativeProcessFreeBSD> child_process{
995       new NativeProcessFreeBSD(static_cast<::pid_t>(child_pid), m_terminal_fd,
996                                m_delegate, m_arch, m_main_loop)};
997   if (!is_vfork)
998     child_process->m_software_breakpoints = m_software_breakpoints;
999 
1000   Extension expected_ext = is_vfork ? Extension::vfork : Extension::fork;
1001   if ((m_enabled_extensions & expected_ext) == expected_ext) {
1002     child_process->SetupTrace();
1003     for (const auto &thread : child_process->m_threads)
1004       static_cast<NativeThreadFreeBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
1005     child_process->SetState(StateType::eStateStopped, false);
1006 
1007     m_delegate.NewSubprocess(this, std::move(child_process));
1008     if (is_vfork)
1009       parent_thread.SetStoppedByVFork(child_pid, child_tid);
1010     else
1011       parent_thread.SetStoppedByFork(child_pid, child_tid);
1012     SetState(StateType::eStateStopped, true);
1013   } else {
1014     child_process->Detach();
1015     Status pt_error =
1016         PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1), 0);
1017     if (pt_error.Fail()) {
1018       LLDB_LOG_ERROR(log, pt_error.ToError(),
1019                      "unable to resume parent process {1}: {0}", GetID());
1020       SetState(StateType::eStateInvalid);
1021     }
1022   }
1023 }
1024 
1025 llvm::Expected<std::string>
1026 NativeProcessFreeBSD::SaveCore(llvm::StringRef path_hint) {
1027 #if defined(PT_COREDUMP)
1028   using namespace llvm::sys::fs;
1029 
1030   llvm::SmallString<128> path{path_hint};
1031   Status error;
1032   struct ptrace_coredump pc = {};
1033 
1034   // Try with the suggested path first.  If there is no suggested path or it
1035   // failed to open, use a temporary file.
1036   if (path.empty() ||
1037       openFile(path, pc.pc_fd, CD_CreateNew, FA_Write, OF_None)) {
1038     if (std::error_code errc =
1039             createTemporaryFile("lldb", "core", pc.pc_fd, path))
1040       return llvm::createStringError(errc, "Unable to create a temporary file");
1041   }
1042   error = PtraceWrapper(PT_COREDUMP, GetID(), &pc, sizeof(pc));
1043 
1044   std::error_code close_err = closeFile(pc.pc_fd);
1045   if (error.Fail())
1046     return error.ToError();
1047   if (close_err)
1048     return llvm::createStringError(
1049         close_err, "Unable to close the core dump after writing");
1050   return path.str().str();
1051 #else // !defined(PT_COREDUMP)
1052   return llvm::createStringError(
1053       llvm::inconvertibleErrorCode(),
1054       "PT_COREDUMP not supported in the FreeBSD version used to build LLDB");
1055 #endif
1056 }
1057