1 //===-- NativeProcessNetBSD.cpp ------------------------------- -*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "NativeProcessNetBSD.h"
11 
12 // C Includes
13 
14 // C++ Includes
15 
16 // Other libraries and framework includes
17 #include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
18 #include "lldb/Core/State.h"
19 #include "lldb/Host/HostProcess.h"
20 #include "lldb/Host/common/NativeBreakpoint.h"
21 #include "lldb/Host/common/NativeRegisterContext.h"
22 #include "lldb/Host/posix/ProcessLauncherPosixFork.h"
23 #include "lldb/Target/Process.h"
24 
25 // System includes - They have to be included after framework includes because
26 // they define some
27 // macros which collide with variable names in other modules
28 // clang-format off
29 #include <sys/types.h>
30 #include <sys/ptrace.h>
31 #include <sys/sysctl.h>
32 #include <sys/wait.h>
33 #include <uvm/uvm_prot.h>
34 #include <elf.h>
35 #include <util.h>
36 // clang-format on
37 
38 using namespace lldb;
39 using namespace lldb_private;
40 using namespace lldb_private::process_netbsd;
41 using namespace llvm;
42 
43 // Simple helper function to ensure flags are enabled on the given file
44 // descriptor.
45 static Status EnsureFDFlags(int fd, int flags) {
46   Status error;
47 
48   int status = fcntl(fd, F_GETFL);
49   if (status == -1) {
50     error.SetErrorToErrno();
51     return error;
52   }
53 
54   if (fcntl(fd, F_SETFL, status | flags) == -1) {
55     error.SetErrorToErrno();
56     return error;
57   }
58 
59   return error;
60 }
61 
62 // -----------------------------------------------------------------------------
63 // Public Static Methods
64 // -----------------------------------------------------------------------------
65 
66 Status NativeProcessProtocol::Launch(
67     ProcessLaunchInfo &launch_info,
68     NativeProcessProtocol::NativeDelegate &native_delegate, MainLoop &mainloop,
69     NativeProcessProtocolSP &native_process_sp) {
70   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
71 
72   Status error;
73 
74   // Verify the working directory is valid if one was specified.
75   FileSpec working_dir{launch_info.GetWorkingDirectory()};
76   if (working_dir && (!working_dir.ResolvePath() ||
77                       !llvm::sys::fs::is_directory(working_dir.GetPath()))) {
78     error.SetErrorStringWithFormat("No such file or directory: %s",
79                                    working_dir.GetCString());
80     return error;
81   }
82 
83   // Create the NativeProcessNetBSD in launch mode.
84   native_process_sp.reset(new NativeProcessNetBSD());
85 
86   if (!native_process_sp->RegisterNativeDelegate(native_delegate)) {
87     native_process_sp.reset();
88     error.SetErrorStringWithFormat("failed to register the native delegate");
89     return error;
90   }
91 
92   error = std::static_pointer_cast<NativeProcessNetBSD>(native_process_sp)
93               ->LaunchInferior(mainloop, launch_info);
94 
95   if (error.Fail()) {
96     native_process_sp.reset();
97     LLDB_LOG(log, "failed to launch process: {0}", error);
98     return error;
99   }
100 
101   launch_info.SetProcessID(native_process_sp->GetID());
102 
103   return error;
104 }
105 
106 Status NativeProcessProtocol::Attach(
107     lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
108     MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) {
109   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
110   LLDB_LOG(log, "pid = {0:x}", pid);
111 
112   // Retrieve the architecture for the running process.
113   ArchSpec process_arch;
114   Status error = ResolveProcessArchitecture(pid, process_arch);
115   if (!error.Success())
116     return error;
117 
118   std::shared_ptr<NativeProcessNetBSD> native_process_netbsd_sp(
119       new NativeProcessNetBSD());
120 
121   if (!native_process_netbsd_sp->RegisterNativeDelegate(native_delegate)) {
122     error.SetErrorStringWithFormat("failed to register the native delegate");
123     return error;
124   }
125 
126   native_process_netbsd_sp->AttachToInferior(mainloop, pid, error);
127   if (!error.Success())
128     return error;
129 
130   native_process_sp = native_process_netbsd_sp;
131   return error;
132 }
133 
134 // -----------------------------------------------------------------------------
135 // Public Instance Methods
136 // -----------------------------------------------------------------------------
137 
138 NativeProcessNetBSD::NativeProcessNetBSD()
139     : NativeProcessProtocol(LLDB_INVALID_PROCESS_ID), m_arch(),
140       m_supports_mem_region(eLazyBoolCalculate), m_mem_region_cache() {}
141 
142 // Handles all waitpid events from the inferior process.
143 void NativeProcessNetBSD::MonitorCallback(lldb::pid_t pid, int signal) {
144   switch (signal) {
145   case SIGTRAP:
146     return MonitorSIGTRAP(pid);
147   case SIGSTOP:
148     return MonitorSIGSTOP(pid);
149   default:
150     return MonitorSignal(pid, signal);
151   }
152 }
153 
154 void NativeProcessNetBSD::MonitorExited(lldb::pid_t pid, WaitStatus status) {
155   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
156 
157   LLDB_LOG(log, "got exit signal({0}) , pid = {1}", status, pid);
158 
159   /* Stop Tracking All Threads attached to Process */
160   m_threads.clear();
161 
162   SetExitStatus(status, true);
163 
164   // Notify delegate that our process has exited.
165   SetState(StateType::eStateExited, true);
166 }
167 
168 void NativeProcessNetBSD::MonitorSIGSTOP(lldb::pid_t pid) {
169   ptrace_siginfo_t info;
170 
171   const auto siginfo_err =
172       PtraceWrapper(PT_GET_SIGINFO, pid, &info, sizeof(info));
173 
174   // Get details on the signal raised.
175   if (siginfo_err.Success()) {
176     // Handle SIGSTOP from LLGS (LLDB GDB Server)
177     if (info.psi_siginfo.si_code == SI_USER &&
178         info.psi_siginfo.si_pid == ::getpid()) {
179       /* Stop Tracking All Threads attached to Process */
180       for (const auto &thread_sp : m_threads) {
181         static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
182             SIGSTOP, &info.psi_siginfo);
183       }
184     }
185   }
186 }
187 
188 void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
189   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
190   ptrace_siginfo_t info;
191 
192   const auto siginfo_err =
193       PtraceWrapper(PT_GET_SIGINFO, pid, &info, sizeof(info));
194 
195   // Get details on the signal raised.
196   if (siginfo_err.Fail()) {
197     return;
198   }
199 
200   switch (info.psi_siginfo.si_code) {
201   case TRAP_BRKPT:
202     for (const auto &thread_sp : m_threads) {
203       static_pointer_cast<NativeThreadNetBSD>(thread_sp)
204           ->SetStoppedByBreakpoint();
205       FixupBreakpointPCAsNeeded(
206           *static_pointer_cast<NativeThreadNetBSD>(thread_sp));
207     }
208     SetState(StateType::eStateStopped, true);
209     break;
210   case TRAP_TRACE:
211     for (const auto &thread_sp : m_threads) {
212       static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedByTrace();
213     }
214     SetState(StateType::eStateStopped, true);
215     break;
216   case TRAP_EXEC: {
217     Status error = ReinitializeThreads();
218     if (error.Fail()) {
219       SetState(StateType::eStateInvalid);
220       return;
221     }
222 
223     // Let our delegate know we have just exec'd.
224     NotifyDidExec();
225 
226     for (const auto &thread_sp : m_threads) {
227       static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedByExec();
228     }
229     SetState(StateType::eStateStopped, true);
230   } break;
231   case TRAP_DBREG: {
232     // If a watchpoint was hit, report it
233     uint32_t wp_index;
234     Status error =
235         static_pointer_cast<NativeThreadNetBSD>(m_threads[info.psi_lwpid])
236             ->GetRegisterContext()
237             ->GetWatchpointHitIndex(wp_index,
238                                     (uintptr_t)info.psi_siginfo.si_addr);
239     if (error.Fail())
240       LLDB_LOG(log,
241                "received error while checking for watchpoint hits, pid = "
242                "{0}, LWP = {1}, error = {2}",
243                GetID(), info.psi_lwpid, error);
244     if (wp_index != LLDB_INVALID_INDEX32) {
245       for (const auto &thread_sp : m_threads) {
246         static_pointer_cast<NativeThreadNetBSD>(thread_sp)
247             ->SetStoppedByWatchpoint(wp_index);
248       }
249       SetState(StateType::eStateStopped, true);
250       break;
251     }
252 
253     // If a breakpoint was hit, report it
254     uint32_t bp_index;
255     error = static_pointer_cast<NativeThreadNetBSD>(m_threads[info.psi_lwpid])
256                 ->GetRegisterContext()
257                 ->GetHardwareBreakHitIndex(bp_index,
258                                            (uintptr_t)info.psi_siginfo.si_addr);
259     if (error.Fail())
260       LLDB_LOG(log,
261                "received error while checking for hardware "
262                "breakpoint hits, pid = {0}, LWP = {1}, error = {2}",
263                GetID(), info.psi_lwpid, error);
264     if (bp_index != LLDB_INVALID_INDEX32) {
265       for (const auto &thread_sp : m_threads) {
266         static_pointer_cast<NativeThreadNetBSD>(thread_sp)
267             ->SetStoppedByBreakpoint();
268       }
269       SetState(StateType::eStateStopped, true);
270       break;
271     }
272   } break;
273   }
274 }
275 
276 void NativeProcessNetBSD::MonitorSignal(lldb::pid_t pid, int signal) {
277   ptrace_siginfo_t info;
278   const auto siginfo_err =
279       PtraceWrapper(PT_GET_SIGINFO, pid, &info, sizeof(info));
280 
281   for (const auto &thread_sp : m_threads) {
282     static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
283         info.psi_siginfo.si_signo, &info.psi_siginfo);
284   }
285   SetState(StateType::eStateStopped, true);
286 }
287 
288 Status NativeProcessNetBSD::PtraceWrapper(int req, lldb::pid_t pid, void *addr,
289                                           int data, int *result) {
290   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
291   Status error;
292   int ret;
293 
294   errno = 0;
295   ret = ptrace(req, static_cast<::pid_t>(pid), addr, data);
296 
297   if (ret == -1)
298     error.SetErrorToErrno();
299 
300   if (result)
301     *result = ret;
302 
303   LLDB_LOG(log, "ptrace({0}, {1}, {2}, {3})={4:x}", req, pid, addr, data, ret);
304 
305   if (error.Fail())
306     LLDB_LOG(log, "ptrace() failed: {0}", error);
307 
308   return error;
309 }
310 
311 Status NativeProcessNetBSD::GetSoftwareBreakpointPCOffset(
312     uint32_t &actual_opcode_size) {
313   // FIXME put this behind a breakpoint protocol class that can be
314   // set per architecture.  Need ARM, MIPS support here.
315   static const uint8_t g_i386_opcode[] = {0xCC};
316   switch (m_arch.GetMachine()) {
317   case llvm::Triple::x86_64:
318     actual_opcode_size = static_cast<uint32_t>(sizeof(g_i386_opcode));
319     return Status();
320   default:
321     assert(false && "CPU type not supported!");
322     return Status("CPU type not supported");
323   }
324 }
325 
326 Status
327 NativeProcessNetBSD::FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread) {
328   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
329   Status error;
330   // Find out the size of a breakpoint (might depend on where we are in the
331   // code).
332   NativeRegisterContextSP context_sp = thread.GetRegisterContext();
333   if (!context_sp) {
334     error.SetErrorString("cannot get a NativeRegisterContext for the thread");
335     LLDB_LOG(log, "failed: {0}", error);
336     return error;
337   }
338   uint32_t breakpoint_size = 0;
339   error = GetSoftwareBreakpointPCOffset(breakpoint_size);
340   if (error.Fail()) {
341     LLDB_LOG(log, "GetBreakpointSize() failed: {0}", error);
342     return error;
343   } else
344     LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size);
345   // First try probing for a breakpoint at a software breakpoint location: PC
346   // - breakpoint size.
347   const lldb::addr_t initial_pc_addr =
348       context_sp->GetPCfromBreakpointLocation();
349   lldb::addr_t breakpoint_addr = initial_pc_addr;
350   if (breakpoint_size > 0) {
351     // Do not allow breakpoint probe to wrap around.
352     if (breakpoint_addr >= breakpoint_size)
353       breakpoint_addr -= breakpoint_size;
354   }
355   // Check if we stopped because of a breakpoint.
356   NativeBreakpointSP breakpoint_sp;
357   error = m_breakpoint_list.GetBreakpoint(breakpoint_addr, breakpoint_sp);
358   if (!error.Success() || !breakpoint_sp) {
359     // We didn't find one at a software probe location.  Nothing to do.
360     LLDB_LOG(log,
361              "pid {0} no lldb breakpoint found at current pc with "
362              "adjustment: {1}",
363              GetID(), breakpoint_addr);
364     return Status();
365   }
366   // If the breakpoint is not a software breakpoint, nothing to do.
367   if (!breakpoint_sp->IsSoftwareBreakpoint()) {
368     LLDB_LOG(
369         log,
370         "pid {0} breakpoint found at {1:x}, not software, nothing to adjust",
371         GetID(), breakpoint_addr);
372     return Status();
373   }
374   //
375   // We have a software breakpoint and need to adjust the PC.
376   //
377   // Sanity check.
378   if (breakpoint_size == 0) {
379     // Nothing to do!  How did we get here?
380     LLDB_LOG(log,
381              "pid {0} breakpoint found at {1:x}, it is software, but the "
382              "size is zero, nothing to do (unexpected)",
383              GetID(), breakpoint_addr);
384     return Status();
385   }
386   //
387   // We have a software breakpoint and need to adjust the PC.
388   //
389   // Sanity check.
390   if (breakpoint_size == 0) {
391     // Nothing to do!  How did we get here?
392     LLDB_LOG(log,
393              "pid {0} breakpoint found at {1:x}, it is software, but the "
394              "size is zero, nothing to do (unexpected)",
395              GetID(), breakpoint_addr);
396     return Status();
397   }
398   // Change the program counter.
399   LLDB_LOG(log, "pid {0} tid {1}: changing PC from {2:x} to {3:x}", GetID(),
400            thread.GetID(), initial_pc_addr, breakpoint_addr);
401   error = context_sp->SetPC(breakpoint_addr);
402   if (error.Fail()) {
403     LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(),
404              thread.GetID(), error);
405     return error;
406   }
407   return error;
408 }
409 
410 Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
411   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
412   LLDB_LOG(log, "pid {0}", GetID());
413 
414   const auto &thread_sp = m_threads[0];
415   const ResumeAction *const action =
416       resume_actions.GetActionForThread(thread_sp->GetID(), true);
417 
418   if (action == nullptr) {
419     LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(),
420              thread_sp->GetID());
421     return Status();
422   }
423 
424   Status error;
425 
426   switch (action->state) {
427   case eStateRunning: {
428     // Run the thread, possibly feeding it the signal.
429     error = NativeProcessNetBSD::PtraceWrapper(PT_CONTINUE, GetID(), (void *)1,
430                                                action->signal);
431     if (!error.Success())
432       return error;
433     for (const auto &thread_sp : m_threads) {
434       static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetRunning();
435     }
436     SetState(eStateRunning, true);
437     break;
438   }
439   case eStateStepping:
440     // Run the thread, possibly feeding it the signal.
441     error = NativeProcessNetBSD::PtraceWrapper(PT_STEP, GetID(), (void *)1,
442                                                action->signal);
443     if (!error.Success())
444       return error;
445     for (const auto &thread_sp : m_threads) {
446       static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStepping();
447     }
448     SetState(eStateStepping, true);
449     break;
450 
451   case eStateSuspended:
452   case eStateStopped:
453     llvm_unreachable("Unexpected state");
454 
455   default:
456     return Status("NativeProcessNetBSD::%s (): unexpected state %s specified "
457                   "for pid %" PRIu64 ", tid %" PRIu64,
458                   __FUNCTION__, StateAsCString(action->state), GetID(),
459                   thread_sp->GetID());
460   }
461 
462   return Status();
463 }
464 
465 Status NativeProcessNetBSD::Halt() {
466   Status error;
467 
468   if (kill(GetID(), SIGSTOP) != 0)
469     error.SetErrorToErrno();
470 
471   return error;
472 }
473 
474 Status NativeProcessNetBSD::Detach() {
475   Status error;
476 
477   // Stop monitoring the inferior.
478   m_sigchld_handle.reset();
479 
480   // Tell ptrace to detach from the process.
481   if (GetID() == LLDB_INVALID_PROCESS_ID)
482     return error;
483 
484   return PtraceWrapper(PT_DETACH, GetID());
485 }
486 
487 Status NativeProcessNetBSD::Signal(int signo) {
488   Status error;
489 
490   if (kill(GetID(), signo))
491     error.SetErrorToErrno();
492 
493   return error;
494 }
495 
496 Status NativeProcessNetBSD::Kill() {
497   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
498   LLDB_LOG(log, "pid {0}", GetID());
499 
500   Status error;
501 
502   switch (m_state) {
503   case StateType::eStateInvalid:
504   case StateType::eStateExited:
505   case StateType::eStateCrashed:
506   case StateType::eStateDetached:
507   case StateType::eStateUnloaded:
508     // Nothing to do - the process is already dead.
509     LLDB_LOG(log, "ignored for PID {0} due to current state: {1}", GetID(),
510              StateAsCString(m_state));
511     return error;
512 
513   case StateType::eStateConnected:
514   case StateType::eStateAttaching:
515   case StateType::eStateLaunching:
516   case StateType::eStateStopped:
517   case StateType::eStateRunning:
518   case StateType::eStateStepping:
519   case StateType::eStateSuspended:
520     // We can try to kill a process in these states.
521     break;
522   }
523 
524   if (kill(GetID(), SIGKILL) != 0) {
525     error.SetErrorToErrno();
526     return error;
527   }
528 
529   return error;
530 }
531 
532 Status NativeProcessNetBSD::GetMemoryRegionInfo(lldb::addr_t load_addr,
533                                                 MemoryRegionInfo &range_info) {
534 
535   if (m_supports_mem_region == LazyBool::eLazyBoolNo) {
536     // We're done.
537     return Status("unsupported");
538   }
539 
540   Status error = PopulateMemoryRegionCache();
541   if (error.Fail()) {
542     return error;
543   }
544 
545   lldb::addr_t prev_base_address = 0;
546   // FIXME start by finding the last region that is <= target address using
547   // binary search.  Data is sorted.
548   // There can be a ton of regions on pthreads apps with lots of threads.
549   for (auto it = m_mem_region_cache.begin(); it != m_mem_region_cache.end();
550        ++it) {
551     MemoryRegionInfo &proc_entry_info = it->first;
552     // Sanity check assumption that memory map entries are ascending.
553     assert((proc_entry_info.GetRange().GetRangeBase() >= prev_base_address) &&
554            "descending memory map entries detected, unexpected");
555     prev_base_address = proc_entry_info.GetRange().GetRangeBase();
556     UNUSED_IF_ASSERT_DISABLED(prev_base_address);
557     // If the target address comes before this entry, indicate distance to
558     // next region.
559     if (load_addr < proc_entry_info.GetRange().GetRangeBase()) {
560       range_info.GetRange().SetRangeBase(load_addr);
561       range_info.GetRange().SetByteSize(
562           proc_entry_info.GetRange().GetRangeBase() - load_addr);
563       range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
564       range_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
565       range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
566       range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
567       return error;
568     } else if (proc_entry_info.GetRange().Contains(load_addr)) {
569       // The target address is within the memory region we're processing here.
570       range_info = proc_entry_info;
571       return error;
572     }
573     // The target memory address comes somewhere after the region we just
574     // parsed.
575   }
576   // If we made it here, we didn't find an entry that contained the given
577   // address. Return the
578   // load_addr as start and the amount of bytes betwwen load address and the
579   // end of the memory as size.
580   range_info.GetRange().SetRangeBase(load_addr);
581   range_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
582   range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
583   range_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
584   range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
585   range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
586   return error;
587 }
588 
589 Status NativeProcessNetBSD::PopulateMemoryRegionCache() {
590   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
591   // If our cache is empty, pull the latest.  There should always be at least
592   // one memory region if memory region handling is supported.
593   if (!m_mem_region_cache.empty()) {
594     LLDB_LOG(log, "reusing {0} cached memory region entries",
595              m_mem_region_cache.size());
596     return Status();
597   }
598 
599   struct kinfo_vmentry *vm;
600   size_t count, i;
601   vm = kinfo_getvmmap(GetID(), &count);
602   if (vm == NULL) {
603     m_supports_mem_region = LazyBool::eLazyBoolNo;
604     Status error;
605     error.SetErrorString("not supported");
606     return error;
607   }
608   for (i = 0; i < count; i++) {
609     MemoryRegionInfo info;
610     info.Clear();
611     info.GetRange().SetRangeBase(vm[i].kve_start);
612     info.GetRange().SetRangeEnd(vm[i].kve_end);
613     info.SetMapped(MemoryRegionInfo::OptionalBool::eYes);
614 
615     if (vm[i].kve_protection & VM_PROT_READ)
616       info.SetReadable(MemoryRegionInfo::OptionalBool::eYes);
617     else
618       info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
619 
620     if (vm[i].kve_protection & VM_PROT_WRITE)
621       info.SetWritable(MemoryRegionInfo::OptionalBool::eYes);
622     else
623       info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
624 
625     if (vm[i].kve_protection & VM_PROT_EXECUTE)
626       info.SetExecutable(MemoryRegionInfo::OptionalBool::eYes);
627     else
628       info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
629 
630     if (vm[i].kve_path[0])
631       info.SetName(vm[i].kve_path);
632 
633     m_mem_region_cache.emplace_back(
634         info, FileSpec(info.GetName().GetCString(), true));
635   }
636   free(vm);
637 
638   if (m_mem_region_cache.empty()) {
639     // No entries after attempting to read them.  This shouldn't happen.
640     // Assume we don't support map entries.
641     LLDB_LOG(log, "failed to find any vmmap entries, assuming no support "
642                   "for memory region metadata retrieval");
643     m_supports_mem_region = LazyBool::eLazyBoolNo;
644     Status error;
645     error.SetErrorString("not supported");
646     return error;
647   }
648   LLDB_LOG(log, "read {0} memory region entries from process {1}",
649            m_mem_region_cache.size(), GetID());
650   // We support memory retrieval, remember that.
651   m_supports_mem_region = LazyBool::eLazyBoolYes;
652   return Status();
653 }
654 
655 Status NativeProcessNetBSD::AllocateMemory(size_t size, uint32_t permissions,
656                                            lldb::addr_t &addr) {
657   return Status("Unimplemented");
658 }
659 
660 Status NativeProcessNetBSD::DeallocateMemory(lldb::addr_t addr) {
661   return Status("Unimplemented");
662 }
663 
664 lldb::addr_t NativeProcessNetBSD::GetSharedLibraryInfoAddress() {
665   // punt on this for now
666   return LLDB_INVALID_ADDRESS;
667 }
668 
669 size_t NativeProcessNetBSD::UpdateThreads() { return m_threads.size(); }
670 
671 bool NativeProcessNetBSD::GetArchitecture(ArchSpec &arch) const {
672   arch = m_arch;
673   return true;
674 }
675 
676 Status NativeProcessNetBSD::SetBreakpoint(lldb::addr_t addr, uint32_t size,
677                                           bool hardware) {
678   if (hardware)
679     return Status("NativeProcessNetBSD does not support hardware breakpoints");
680   else
681     return SetSoftwareBreakpoint(addr, size);
682 }
683 
684 Status NativeProcessNetBSD::GetSoftwareBreakpointTrapOpcode(
685     size_t trap_opcode_size_hint, size_t &actual_opcode_size,
686     const uint8_t *&trap_opcode_bytes) {
687   static const uint8_t g_i386_opcode[] = {0xCC};
688 
689   switch (m_arch.GetMachine()) {
690   case llvm::Triple::x86:
691   case llvm::Triple::x86_64:
692     trap_opcode_bytes = g_i386_opcode;
693     actual_opcode_size = sizeof(g_i386_opcode);
694     return Status();
695   default:
696     assert(false && "CPU type not supported!");
697     return Status("CPU type not supported");
698   }
699 }
700 
701 Status NativeProcessNetBSD::GetLoadedModuleFileSpec(const char *module_path,
702                                                     FileSpec &file_spec) {
703   return Status("Unimplemented");
704 }
705 
706 Status NativeProcessNetBSD::GetFileLoadAddress(const llvm::StringRef &file_name,
707                                                lldb::addr_t &load_addr) {
708   load_addr = LLDB_INVALID_ADDRESS;
709   return Status();
710 }
711 
712 Status NativeProcessNetBSD::LaunchInferior(MainLoop &mainloop,
713                                            ProcessLaunchInfo &launch_info) {
714   Status error;
715   m_sigchld_handle = mainloop.RegisterSignal(
716       SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
717   if (!m_sigchld_handle)
718     return error;
719 
720   SetState(eStateLaunching);
721 
722   ::pid_t pid = ProcessLauncherPosixFork()
723                     .LaunchProcess(launch_info, error)
724                     .GetProcessId();
725   if (error.Fail())
726     return error;
727 
728   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
729 
730   // Wait for the child process to trap on its call to execve.
731   ::pid_t wpid;
732   int status;
733   if ((wpid = waitpid(pid, &status, 0)) < 0) {
734     error.SetErrorToErrno();
735     LLDB_LOG(log, "waitpid for inferior failed with %s", error);
736 
737     // Mark the inferior as invalid.
738     // FIXME this could really use a new state - eStateLaunchFailure.  For
739     // now, using eStateInvalid.
740     SetState(StateType::eStateInvalid);
741 
742     return error;
743   }
744   assert(WIFSTOPPED(status) && (wpid == static_cast<::pid_t>(pid)) &&
745          "Could not sync with inferior process.");
746 
747   LLDB_LOG(log, "inferior started, now in stopped state");
748 
749   // Release the master terminal descriptor and pass it off to the
750   // NativeProcessNetBSD instance.  Similarly stash the inferior pid.
751   m_terminal_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
752   m_pid = pid;
753   launch_info.SetProcessID(pid);
754 
755   if (m_terminal_fd != -1) {
756     error = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
757     if (error.Fail()) {
758       LLDB_LOG(log,
759                "inferior EnsureFDFlags failed for ensuring terminal "
760                "O_NONBLOCK setting: {0}",
761                error);
762 
763       // Mark the inferior as invalid.
764       // FIXME this could really use a new state - eStateLaunchFailure.  For
765       // now, using eStateInvalid.
766       SetState(StateType::eStateInvalid);
767 
768       return error;
769     }
770   }
771 
772   LLDB_LOG(log, "adding pid = {0}", pid);
773 
774   ResolveProcessArchitecture(m_pid, m_arch);
775 
776   error = ReinitializeThreads();
777   if (error.Fail()) {
778     SetState(StateType::eStateInvalid);
779     return error;
780   }
781 
782   for (const auto &thread_sp : m_threads) {
783     static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
784         SIGSTOP);
785   }
786 
787   /* Set process stopped */
788   SetState(StateType::eStateStopped);
789 
790   if (error.Fail())
791     LLDB_LOG(log, "inferior launching failed {0}", error);
792   return error;
793 }
794 
795 void NativeProcessNetBSD::AttachToInferior(MainLoop &mainloop, lldb::pid_t pid,
796                                            Status &error) {
797   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
798   LLDB_LOG(log, "pid = {0:x}", pid);
799 
800   m_sigchld_handle = mainloop.RegisterSignal(
801       SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
802   if (!m_sigchld_handle)
803     return;
804 
805   error = ResolveProcessArchitecture(pid, m_arch);
806   if (!error.Success())
807     return;
808 
809   // Set the architecture to the exe architecture.
810   LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,
811            m_arch.GetArchitectureName());
812 
813   m_pid = pid;
814   SetState(eStateAttaching);
815 
816   Attach(pid, error);
817 }
818 
819 void NativeProcessNetBSD::SigchldHandler() {
820   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
821   // Process all pending waitpid notifications.
822   int status;
823   ::pid_t wait_pid = waitpid(GetID(), &status, WALLSIG | WNOHANG);
824 
825   if (wait_pid == 0)
826     return; // We are done.
827 
828   if (wait_pid == -1) {
829     if (errno == EINTR)
830       return;
831 
832     Status error(errno, eErrorTypePOSIX);
833     LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error);
834   }
835 
836   WaitStatus wait_status = WaitStatus::Decode(status);
837   bool exited = wait_status.type == WaitStatus::Exit ||
838                 (wait_status.type == WaitStatus::Signal &&
839                  wait_pid == static_cast<::pid_t>(GetID()));
840 
841   LLDB_LOG(log,
842            "waitpid ({0}, &status, _) => pid = {1}, status = {2}, exited = {3}",
843            GetID(), wait_pid, status, exited);
844 
845   if (exited)
846     MonitorExited(wait_pid, wait_status);
847   else {
848     assert(wait_status.type == WaitStatus::Stop);
849     MonitorCallback(wait_pid, wait_status.status);
850   }
851 }
852 
853 bool NativeProcessNetBSD::HasThreadNoLock(lldb::tid_t thread_id) {
854   for (auto thread_sp : m_threads) {
855     assert(thread_sp && "thread list should not contain NULL threads");
856     if (thread_sp->GetID() == thread_id) {
857       // We have this thread.
858       return true;
859     }
860   }
861 
862   // We don't have this thread.
863   return false;
864 }
865 
866 NativeThreadNetBSDSP NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) {
867 
868   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
869   LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id);
870 
871   assert(!HasThreadNoLock(thread_id) &&
872          "attempted to add a thread by id that already exists");
873 
874   // If this is the first thread, save it as the current thread
875   if (m_threads.empty())
876     SetCurrentThreadID(thread_id);
877 
878   auto thread_sp = std::make_shared<NativeThreadNetBSD>(this, thread_id);
879   m_threads.push_back(thread_sp);
880   return thread_sp;
881 }
882 
883 ::pid_t NativeProcessNetBSD::Attach(lldb::pid_t pid, Status &error) {
884   if (pid <= 1) {
885     error.SetErrorToGenericError();
886     error.SetErrorString("Attaching to process 1 is not allowed.");
887     return -1;
888   }
889 
890   // Attach to the requested process.
891   // An attach will cause the thread to stop with a SIGSTOP.
892   error = PtraceWrapper(PT_ATTACH, pid);
893   if (error.Fail())
894     return -1;
895 
896   int status;
897   // Need to use WALLSIG otherwise we receive an error with errno=ECHLD
898   // At this point we should have a thread stopped if waitpid succeeds.
899   if ((status = waitpid(pid, NULL, WALLSIG)) < 0)
900     return -1;
901 
902   m_pid = pid;
903 
904   /* Initialize threads */
905   error = ReinitializeThreads();
906   if (error.Fail()) {
907     SetState(StateType::eStateInvalid);
908     return -1;
909   }
910 
911   for (const auto &thread_sp : m_threads) {
912     static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
913         SIGSTOP);
914   }
915 
916   // Let our process instance know the thread has stopped.
917   SetState(StateType::eStateStopped);
918 
919   return pid;
920 }
921 
922 Status NativeProcessNetBSD::ReadMemory(lldb::addr_t addr, void *buf,
923                                        size_t size, size_t &bytes_read) {
924   unsigned char *dst = static_cast<unsigned char *>(buf);
925   struct ptrace_io_desc io;
926 
927   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY));
928   LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
929 
930   bytes_read = 0;
931   io.piod_op = PIOD_READ_D;
932   io.piod_len = size;
933 
934   do {
935     io.piod_offs = (void *)(addr + bytes_read);
936     io.piod_addr = dst + bytes_read;
937 
938     Status error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io);
939     if (error.Fail())
940       return error;
941 
942     bytes_read = io.piod_len;
943     io.piod_len = size - bytes_read;
944   } while (bytes_read < size);
945 
946   return Status();
947 }
948 
949 Status NativeProcessNetBSD::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf,
950                                                   size_t size,
951                                                   size_t &bytes_read) {
952   Status error = ReadMemory(addr, buf, size, bytes_read);
953   if (error.Fail())
954     return error;
955   return m_breakpoint_list.RemoveTrapsFromBuffer(addr, buf, size);
956 }
957 
958 Status NativeProcessNetBSD::WriteMemory(lldb::addr_t addr, const void *buf,
959                                         size_t size, size_t &bytes_written) {
960   const unsigned char *src = static_cast<const unsigned char *>(buf);
961   Status error;
962   struct ptrace_io_desc io;
963 
964   Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY));
965   LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
966 
967   bytes_written = 0;
968   io.piod_op = PIOD_WRITE_D;
969   io.piod_len = size;
970 
971   do {
972     io.piod_addr = const_cast<void *>(static_cast<const void *>(src + bytes_written));
973     io.piod_offs = (void *)(addr + bytes_written);
974 
975     Status error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io);
976     if (error.Fail())
977       return error;
978 
979     bytes_written = io.piod_len;
980     io.piod_len = size - bytes_written;
981   } while (bytes_written < size);
982 
983   return error;
984 }
985 
986 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
987 NativeProcessNetBSD::GetAuxvData() const {
988   /*
989    * ELF_AUX_ENTRIES is currently restricted to kernel
990    * (<sys/exec_elf.h> r. 1.155 specifies 15)
991    *
992    * ptrace(2) returns the whole AUXV including extra fiels after AT_NULL this
993    * information isn't needed.
994    */
995   size_t auxv_size = 100 * sizeof(AuxInfo);
996 
997   ErrorOr<std::unique_ptr<MemoryBuffer>> buf =
998       llvm::MemoryBuffer::getNewMemBuffer(auxv_size);
999 
1000   struct ptrace_io_desc io;
1001   io.piod_op = PIOD_READ_AUXV;
1002   io.piod_offs = 0;
1003   io.piod_addr = const_cast<void *>(static_cast<const void *>(buf.get()->getBufferStart()));
1004   io.piod_len = auxv_size;
1005 
1006   Status error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io);
1007 
1008   if (error.Fail())
1009     return std::error_code(error.GetError(), std::generic_category());
1010 
1011   if (io.piod_len < 1)
1012     return std::error_code(ECANCELED, std::generic_category());
1013 
1014   return buf;
1015 }
1016 
1017 Status NativeProcessNetBSD::ReinitializeThreads() {
1018   // Clear old threads
1019   m_threads.clear();
1020 
1021   // Initialize new thread
1022   struct ptrace_lwpinfo info = {};
1023   Status error = PtraceWrapper(PT_LWPINFO, GetID(), &info, sizeof(info));
1024   if (error.Fail()) {
1025     return error;
1026   }
1027   // Reinitialize from scratch threads and register them in process
1028   while (info.pl_lwpid != 0) {
1029     NativeThreadNetBSDSP thread_sp = AddThread(info.pl_lwpid);
1030     error = PtraceWrapper(PT_LWPINFO, GetID(), &info, sizeof(info));
1031     if (error.Fail()) {
1032       return error;
1033     }
1034   }
1035 
1036   return error;
1037 }
1038