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