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