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