blob: 298faa48e1c3d55b7e056928869666f91de2c440 [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;
Kamil Rytarowski3eef2b52017-03-30 20:25:29 +0000238 case TRAP_TRACE:
239 for (const auto &thread_sp : m_threads) {
240 static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedByTrace();
241 }
242 SetState(StateType::eStateStopped, true);
243 break;
244 case TRAP_EXEC: {
245 Error error = ReinitializeThreads();
246 if (error.Fail()) {
247 SetState(StateType::eStateInvalid);
248 return;
249 }
250
251 // Let our delegate know we have just exec'd.
252 NotifyDidExec();
253
254 SetState(StateType::eStateStopped, true);
255 } break;
Kamil Rytarowskif07a9992017-03-28 22:43:17 +0000256 }
257 }
258}
259
260void NativeProcessNetBSD::MonitorSignal(lldb::pid_t pid, int signal) {
261 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
262
263 ptrace_siginfo_t info;
264 const auto siginfo_err =
265 PtraceWrapper(PT_GET_SIGINFO, pid, &info, sizeof(info));
266
267 for (const auto &thread_sp : m_threads) {
268 static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
269 info.psi_siginfo.si_signo, &info.psi_siginfo);
270 }
271 SetState(StateType::eStateStopped, true);
272}
273
274Error NativeProcessNetBSD::PtraceWrapper(int req, lldb::pid_t pid, void *addr,
275 int data, int *result) {
276 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
277 Error error;
278 int ret;
279
280 errno = 0;
281 ret = ptrace(req, static_cast<::pid_t>(pid), addr, data);
282
283 if (ret == -1)
284 error.SetErrorToErrno();
285
286 if (result)
287 *result = ret;
288
289 LLDB_LOG(log, "ptrace({0}, {1}, {2}, {3})={4:x}", req, pid, addr, data, ret);
290
291 if (error.Fail())
292 LLDB_LOG(log, "ptrace() failed: {0}", error);
293
294 return error;
295}
296
297Error NativeProcessNetBSD::GetSoftwareBreakpointPCOffset(
298 uint32_t &actual_opcode_size) {
299 // FIXME put this behind a breakpoint protocol class that can be
300 // set per architecture. Need ARM, MIPS support here.
301 static const uint8_t g_i386_opcode[] = {0xCC};
302 switch (m_arch.GetMachine()) {
303 case llvm::Triple::x86_64:
304 actual_opcode_size = static_cast<uint32_t>(sizeof(g_i386_opcode));
305 return Error();
306 default:
307 assert(false && "CPU type not supported!");
308 return Error("CPU type not supported");
309 }
310}
311
312Error NativeProcessNetBSD::FixupBreakpointPCAsNeeded(
313 NativeThreadNetBSD &thread) {
314 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
315 Error error;
316 // Find out the size of a breakpoint (might depend on where we are in the
317 // code).
318 NativeRegisterContextSP context_sp = thread.GetRegisterContext();
319 if (!context_sp) {
320 error.SetErrorString("cannot get a NativeRegisterContext for the thread");
321 LLDB_LOG(log, "failed: {0}", error);
322 return error;
323 }
324 uint32_t breakpoint_size = 0;
325 error = GetSoftwareBreakpointPCOffset(breakpoint_size);
326 if (error.Fail()) {
327 LLDB_LOG(log, "GetBreakpointSize() failed: {0}", error);
328 return error;
329 } else
330 LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size);
331 // First try probing for a breakpoint at a software breakpoint location: PC -
332 // breakpoint size.
333 const lldb::addr_t initial_pc_addr =
334 context_sp->GetPCfromBreakpointLocation();
335 lldb::addr_t breakpoint_addr = initial_pc_addr;
336 if (breakpoint_size > 0) {
337 // Do not allow breakpoint probe to wrap around.
338 if (breakpoint_addr >= breakpoint_size)
339 breakpoint_addr -= breakpoint_size;
340 }
341 // Check if we stopped because of a breakpoint.
342 NativeBreakpointSP breakpoint_sp;
343 error = m_breakpoint_list.GetBreakpoint(breakpoint_addr, breakpoint_sp);
344 if (!error.Success() || !breakpoint_sp) {
345 // We didn't find one at a software probe location. Nothing to do.
346 LLDB_LOG(log,
347 "pid {0} no lldb breakpoint found at current pc with "
348 "adjustment: {1}",
349 GetID(), breakpoint_addr);
350 return Error();
351 }
352 // If the breakpoint is not a software breakpoint, nothing to do.
353 if (!breakpoint_sp->IsSoftwareBreakpoint()) {
354 LLDB_LOG(
355 log,
356 "pid {0} breakpoint found at {1:x}, not software, nothing to adjust",
357 GetID(), breakpoint_addr);
358 return Error();
359 }
360 //
361 // We have a software breakpoint and need to adjust the PC.
362 //
363 // Sanity check.
364 if (breakpoint_size == 0) {
365 // Nothing to do! How did we get here?
366 LLDB_LOG(log,
367 "pid {0} breakpoint found at {1:x}, it is software, but the "
368 "size is zero, nothing to do (unexpected)",
369 GetID(), breakpoint_addr);
370 return Error();
371 }
372 //
373 // We have a software breakpoint and need to adjust the PC.
374 //
375 // Sanity check.
376 if (breakpoint_size == 0) {
377 // Nothing to do! How did we get here?
378 LLDB_LOG(log,
379 "pid {0} breakpoint found at {1:x}, it is software, but the "
380 "size is zero, nothing to do (unexpected)",
381 GetID(), breakpoint_addr);
382 return Error();
383 }
384 // Change the program counter.
385 LLDB_LOG(log, "pid {0} tid {1}: changing PC from {2:x} to {3:x}", GetID(),
386 thread.GetID(), initial_pc_addr, breakpoint_addr);
387 error = context_sp->SetPC(breakpoint_addr);
388 if (error.Fail()) {
389 LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(),
390 thread.GetID(), error);
391 return error;
392 }
393 return error;
394}
395
396Error NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
397 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
398 LLDB_LOG(log, "pid {0}", GetID());
399
400 const auto &thread_sp = m_threads[0];
401 const ResumeAction *const action =
402 resume_actions.GetActionForThread(thread_sp->GetID(), true);
403
404 if (action == nullptr) {
405 LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(),
406 thread_sp->GetID());
407 return Error();
408 }
409
Kamil Rytarowski3eef2b52017-03-30 20:25:29 +0000410 Error error;
411
Kamil Rytarowskif07a9992017-03-28 22:43:17 +0000412 switch (action->state) {
413 case eStateRunning: {
414 // Run the thread, possibly feeding it the signal.
Kamil Rytarowski3eef2b52017-03-30 20:25:29 +0000415 error = NativeProcessNetBSD::PtraceWrapper(PT_CONTINUE, GetID(), (void *)1,
416 action->signal);
Kamil Rytarowskif07a9992017-03-28 22:43:17 +0000417 if (!error.Success())
418 return error;
419 for (const auto &thread_sp : m_threads) {
420 static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetRunning();
421 }
422 SetState(eStateRunning, true);
423 break;
424 }
425 case eStateStepping:
Kamil Rytarowski3eef2b52017-03-30 20:25:29 +0000426 // Run the thread, possibly feeding it the signal.
427 error = NativeProcessNetBSD::PtraceWrapper(PT_STEP, GetID(), (void *)1,
428 action->signal);
429 if (!error.Success())
430 return error;
431 for (const auto &thread_sp : m_threads) {
432 static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStepping();
433 }
434 SetState(eStateStepping, true);
Kamil Rytarowskif07a9992017-03-28 22:43:17 +0000435 break;
436
437 case eStateSuspended:
438 case eStateStopped:
439 llvm_unreachable("Unexpected state");
440
441 default:
442 return Error("NativeProcessLinux::%s (): unexpected state %s specified "
443 "for pid %" PRIu64 ", tid %" PRIu64,
444 __FUNCTION__, StateAsCString(action->state), GetID(),
445 thread_sp->GetID());
446 }
447
448 return Error();
449}
450
451Error NativeProcessNetBSD::Halt() {
452 Error error;
453
454 if (kill(GetID(), SIGSTOP) != 0)
455 error.SetErrorToErrno();
456
457 return error;
458}
459
460Error NativeProcessNetBSD::Detach() {
461 Error error;
462
463 // Stop monitoring the inferior.
464 m_sigchld_handle.reset();
465
466 // Tell ptrace to detach from the process.
467 if (GetID() == LLDB_INVALID_PROCESS_ID)
468 return error;
469
470 return PtraceWrapper(PT_DETACH, GetID());
471}
472
473Error NativeProcessNetBSD::Signal(int signo) {
474 Error error;
475
476 if (kill(GetID(), signo))
477 error.SetErrorToErrno();
478
479 return error;
480}
481
482Error NativeProcessNetBSD::Kill() {
483 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
484 LLDB_LOG(log, "pid {0}", GetID());
485
486 Error error;
487
488 switch (m_state) {
489 case StateType::eStateInvalid:
490 case StateType::eStateExited:
491 case StateType::eStateCrashed:
492 case StateType::eStateDetached:
493 case StateType::eStateUnloaded:
494 // Nothing to do - the process is already dead.
495 LLDB_LOG(log, "ignored for PID {0} due to current state: {1}", GetID(),
496 StateAsCString(m_state));
497 return error;
498
499 case StateType::eStateConnected:
500 case StateType::eStateAttaching:
501 case StateType::eStateLaunching:
502 case StateType::eStateStopped:
503 case StateType::eStateRunning:
504 case StateType::eStateStepping:
505 case StateType::eStateSuspended:
506 // We can try to kill a process in these states.
507 break;
508 }
509
510 if (kill(GetID(), SIGKILL) != 0) {
511 error.SetErrorToErrno();
512 return error;
513 }
514
515 return error;
516}
517
518Error NativeProcessNetBSD::GetMemoryRegionInfo(lldb::addr_t load_addr,
519 MemoryRegionInfo &range_info) {
520
521 if (m_supports_mem_region == LazyBool::eLazyBoolNo) {
522 // We're done.
523 return Error("unsupported");
524 }
525
526 Error error = PopulateMemoryRegionCache();
527 if (error.Fail()) {
528 return error;
529 }
530
531 lldb::addr_t prev_base_address = 0;
532 // FIXME start by finding the last region that is <= target address using
533 // binary search. Data is sorted.
534 // There can be a ton of regions on pthreads apps with lots of threads.
535 for (auto it = m_mem_region_cache.begin(); it != m_mem_region_cache.end();
536 ++it) {
537 MemoryRegionInfo &proc_entry_info = it->first;
538 // Sanity check assumption that memory map entries are ascending.
539 assert((proc_entry_info.GetRange().GetRangeBase() >= prev_base_address) &&
540 "descending memory map entries detected, unexpected");
541 prev_base_address = proc_entry_info.GetRange().GetRangeBase();
542 UNUSED_IF_ASSERT_DISABLED(prev_base_address);
543 // If the target address comes before this entry, indicate distance to next
544 // region.
545 if (load_addr < proc_entry_info.GetRange().GetRangeBase()) {
546 range_info.GetRange().SetRangeBase(load_addr);
547 range_info.GetRange().SetByteSize(
548 proc_entry_info.GetRange().GetRangeBase() - load_addr);
549 range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
550 range_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
551 range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
552 range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
553 return error;
554 } else if (proc_entry_info.GetRange().Contains(load_addr)) {
555 // The target address is within the memory region we're processing here.
556 range_info = proc_entry_info;
557 return error;
558 }
559 // The target memory address comes somewhere after the region we just
560 // parsed.
561 }
562 // If we made it here, we didn't find an entry that contained the given
563 // address. Return the
564 // load_addr as start and the amount of bytes betwwen load address and the end
565 // of the memory as
566 // size.
567 range_info.GetRange().SetRangeBase(load_addr);
568 range_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
569 range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
570 range_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
571 range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
572 range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
573 return error;
574}
575
576Error NativeProcessNetBSD::PopulateMemoryRegionCache() {
577 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
578 // If our cache is empty, pull the latest. There should always be at least
579 // one memory region if memory region handling is supported.
580 if (!m_mem_region_cache.empty()) {
581 LLDB_LOG(log, "reusing {0} cached memory region entries",
582 m_mem_region_cache.size());
583 return Error();
584 }
585
586 struct kinfo_vmentry *vm;
587 size_t count, i;
588 vm = kinfo_getvmmap(GetID(), &count);
589 if (vm == NULL) {
590 m_supports_mem_region = LazyBool::eLazyBoolNo;
591 Error error;
592 error.SetErrorString("not supported");
593 return error;
594 }
595 for (i = 0; i < count; i++) {
596 MemoryRegionInfo info;
597 info.Clear();
598 info.GetRange().SetRangeBase(vm[i].kve_start);
599 info.GetRange().SetRangeEnd(vm[i].kve_end);
600 info.SetMapped(MemoryRegionInfo::OptionalBool::eYes);
601
602 if (vm[i].kve_protection & VM_PROT_READ)
603 info.SetReadable(MemoryRegionInfo::OptionalBool::eYes);
604 else
605 info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
606
607 if (vm[i].kve_protection & VM_PROT_WRITE)
608 info.SetWritable(MemoryRegionInfo::OptionalBool::eYes);
609 else
610 info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
611
612 if (vm[i].kve_protection & VM_PROT_EXECUTE)
613 info.SetExecutable(MemoryRegionInfo::OptionalBool::eYes);
614 else
615 info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
616
617 if (vm[i].kve_path[0])
618 info.SetName(vm[i].kve_path);
619
620 m_mem_region_cache.emplace_back(
621 info, FileSpec(info.GetName().GetCString(), true));
622 }
623 free(vm);
624
625 if (m_mem_region_cache.empty()) {
626 // No entries after attempting to read them. This shouldn't happen.
627 // Assume we don't support map entries.
628 LLDB_LOG(log, "failed to find any vmmap entries, assuming no support "
629 "for memory region metadata retrieval");
630 m_supports_mem_region = LazyBool::eLazyBoolNo;
631 Error error;
632 error.SetErrorString("not supported");
633 return error;
634 }
635 LLDB_LOG(log, "read {0} memory region entries from process {1}",
636 m_mem_region_cache.size(), GetID());
637 // We support memory retrieval, remember that.
638 m_supports_mem_region = LazyBool::eLazyBoolYes;
639 return Error();
640}
641
642Error NativeProcessNetBSD::AllocateMemory(size_t size, uint32_t permissions,
643 lldb::addr_t &addr) {
644 return Error("Unimplemented");
645}
646
647Error NativeProcessNetBSD::DeallocateMemory(lldb::addr_t addr) {
648 return Error("Unimplemented");
649}
650
651lldb::addr_t NativeProcessNetBSD::GetSharedLibraryInfoAddress() {
652 // punt on this for now
653 return LLDB_INVALID_ADDRESS;
654}
655
656size_t NativeProcessNetBSD::UpdateThreads() { return m_threads.size(); }
657
658bool NativeProcessNetBSD::GetArchitecture(ArchSpec &arch) const {
659 arch = m_arch;
660 return true;
661}
662
663Error NativeProcessNetBSD::SetBreakpoint(lldb::addr_t addr, uint32_t size,
664 bool hardware) {
665 if (hardware)
666 return Error("NativeProcessNetBSD does not support hardware breakpoints");
667 else
668 return SetSoftwareBreakpoint(addr, size);
669}
670
671Error NativeProcessNetBSD::GetSoftwareBreakpointTrapOpcode(
672 size_t trap_opcode_size_hint, size_t &actual_opcode_size,
673 const uint8_t *&trap_opcode_bytes) {
674 static const uint8_t g_i386_opcode[] = {0xCC};
675
676 switch (m_arch.GetMachine()) {
677 case llvm::Triple::x86:
678 case llvm::Triple::x86_64:
679 trap_opcode_bytes = g_i386_opcode;
680 actual_opcode_size = sizeof(g_i386_opcode);
681 return Error();
682 default:
683 assert(false && "CPU type not supported!");
684 return Error("CPU type not supported");
685 }
686}
687
688Error NativeProcessNetBSD::GetLoadedModuleFileSpec(const char *module_path,
689 FileSpec &file_spec) {
690 return Error("Unimplemented");
691}
692
693Error NativeProcessNetBSD::GetFileLoadAddress(const llvm::StringRef &file_name,
694 lldb::addr_t &load_addr) {
695 load_addr = LLDB_INVALID_ADDRESS;
696 return Error();
697}
698
699Error NativeProcessNetBSD::LaunchInferior(MainLoop &mainloop,
700 ProcessLaunchInfo &launch_info) {
701 Error error;
702 m_sigchld_handle = mainloop.RegisterSignal(
703 SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
704 if (!m_sigchld_handle)
705 return error;
706
707 SetState(eStateLaunching);
708
709 ::pid_t pid = ProcessLauncherPosixFork()
710 .LaunchProcess(launch_info, error)
711 .GetProcessId();
712 if (error.Fail())
713 return error;
714
715 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
716
717 // Wait for the child process to trap on its call to execve.
718 ::pid_t wpid;
719 int status;
720 if ((wpid = waitpid(pid, &status, 0)) < 0) {
721 error.SetErrorToErrno();
722 LLDB_LOG(log, "waitpid for inferior failed with %s", error);
723
724 // Mark the inferior as invalid.
725 // FIXME this could really use a new state - eStateLaunchFailure. For now,
726 // using eStateInvalid.
727 SetState(StateType::eStateInvalid);
728
729 return error;
730 }
731 assert(WIFSTOPPED(status) && (wpid == static_cast<::pid_t>(pid)) &&
732 "Could not sync with inferior process.");
733
734 LLDB_LOG(log, "inferior started, now in stopped state");
735
736 // Release the master terminal descriptor and pass it off to the
737 // NativeProcessNetBSD instance. Similarly stash the inferior pid.
738 m_terminal_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
739 m_pid = pid;
740 launch_info.SetProcessID(pid);
741
742 if (m_terminal_fd != -1) {
743 error = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
744 if (error.Fail()) {
745 LLDB_LOG(log,
746 "inferior EnsureFDFlags failed for ensuring terminal "
747 "O_NONBLOCK setting: {0}",
748 error);
749
750 // Mark the inferior as invalid.
751 // FIXME this could really use a new state - eStateLaunchFailure. For
752 // now, using eStateInvalid.
753 SetState(StateType::eStateInvalid);
754
755 return error;
756 }
757 }
758
759 LLDB_LOG(log, "adding pid = {0}", pid);
760
761 ResolveProcessArchitecture(m_pid, m_arch);
762
Kamil Rytarowski3eef2b52017-03-30 20:25:29 +0000763 error = ReinitializeThreads();
Kamil Rytarowskif07a9992017-03-28 22:43:17 +0000764 if (error.Fail()) {
765 SetState(StateType::eStateInvalid);
766 return error;
767 }
Kamil Rytarowskif07a9992017-03-28 22:43:17 +0000768
769 /* Set process stopped */
770 SetState(StateType::eStateStopped);
771
772 if (error.Fail())
773 LLDB_LOG(log, "inferior launching failed {0}", error);
774 return error;
775}
776
777void NativeProcessNetBSD::AttachToInferior(MainLoop &mainloop, lldb::pid_t pid,
778 Error &error) {
779 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
780 LLDB_LOG(log, "pid = {0:x}", pid);
781
782 m_sigchld_handle = mainloop.RegisterSignal(
783 SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
784 if (!m_sigchld_handle)
785 return;
786
787 error = ResolveProcessArchitecture(pid, m_arch);
788 if (!error.Success())
789 return;
790
791 // Set the architecture to the exe architecture.
792 LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,
793 m_arch.GetArchitectureName());
794
795 m_pid = pid;
796 SetState(eStateAttaching);
797
798 Attach(pid, error);
799}
800
801void NativeProcessNetBSD::SigchldHandler() {
802 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
803 // Process all pending waitpid notifications.
804 int status;
805 ::pid_t wait_pid = waitpid(GetID(), &status, WALLSIG | WNOHANG);
806
807 if (wait_pid == 0)
808 return; // We are done.
809
810 if (wait_pid == -1) {
811 if (errno == EINTR)
812 return;
813
814 Error error(errno, eErrorTypePOSIX);
815 LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error);
816 }
817
818 bool exited = false;
819 int signal = 0;
820 int exit_status = 0;
821 const char *status_cstr = nullptr;
822 if (WIFSTOPPED(status)) {
823 signal = WSTOPSIG(status);
824 status_cstr = "STOPPED";
825 } else if (WIFEXITED(status)) {
826 exit_status = WEXITSTATUS(status);
827 status_cstr = "EXITED";
828 exited = true;
829 } else if (WIFSIGNALED(status)) {
830 signal = WTERMSIG(status);
831 status_cstr = "SIGNALED";
832 if (wait_pid == static_cast<::pid_t>(GetID())) {
833 exited = true;
834 exit_status = -1;
835 }
836 } else
837 status_cstr = "(\?\?\?)";
838
839 LLDB_LOG(log,
840 "waitpid ({0}, &status, _) => pid = {1}, status = {2:x} "
841 "({3}), signal = {4}, exit_state = {5}",
842 GetID(), wait_pid, status, status_cstr, signal, exit_status);
843
844 if (exited)
845 MonitorExited(wait_pid, signal, exit_status);
846 else
847 MonitorCallback(wait_pid, signal);
848}
849
850NativeThreadNetBSDSP NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) {
851
852 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
853 LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id);
854
855 assert(!HasThreadNoLock(thread_id) &&
856 "attempted to add a thread by id that already exists");
857
858 // If this is the first thread, save it as the current thread
859 if (m_threads.empty())
860 SetCurrentThreadID(thread_id);
861
862 auto thread_sp = std::make_shared<NativeThreadNetBSD>(this, thread_id);
863 m_threads.push_back(thread_sp);
864 return thread_sp;
865}
866
867::pid_t NativeProcessNetBSD::Attach(lldb::pid_t pid, Error &error) {
868 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
869
Kamil Rytarowskif07a9992017-03-28 22:43:17 +0000870 if (pid <= 1) {
871 error.SetErrorToGenericError();
872 error.SetErrorString("Attaching to process 1 is not allowed.");
873 return -1;
874 }
875
876 // Attach to the requested process.
877 // An attach will cause the thread to stop with a SIGSTOP.
878 error = PtraceWrapper(PT_ATTACH, pid);
879 if (error.Fail())
880 return -1;
881
882 int status;
883 // Need to use WALLSIG otherwise we receive an error with errno=ECHLD
884 // At this point we should have a thread stopped if waitpid succeeds.
885 if ((status = waitpid(pid, NULL, WALLSIG)) < 0)
886 return -1;
887
888 m_pid = pid;
889
890 /* Initialize threads */
Kamil Rytarowski3eef2b52017-03-30 20:25:29 +0000891 error = ReinitializeThreads();
Kamil Rytarowskif07a9992017-03-28 22:43:17 +0000892 if (error.Fail()) {
893 SetState(StateType::eStateInvalid);
894 return -1;
895 }
Kamil Rytarowskif07a9992017-03-28 22:43:17 +0000896
897 // Let our process instance know the thread has stopped.
898 SetState(StateType::eStateStopped);
899
900 return pid;
901}
902
903Error NativeProcessNetBSD::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
904 size_t &bytes_read) {
905 unsigned char *dst = static_cast<unsigned char *>(buf);
906 struct ptrace_io_desc io;
907
908 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY));
909 LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
910
911 bytes_read = 0;
912 io.piod_op = PIOD_READ_D;
913 io.piod_len = size;
914
915 do {
916 io.piod_offs = (void *)(addr + bytes_read);
917 io.piod_addr = dst + bytes_read;
918
919 Error error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io);
920 if (error.Fail())
921 return error;
922
923 bytes_read = io.piod_len;
924 io.piod_len = size - bytes_read;
925 } while (bytes_read < size);
926
927 return Error();
928}
929
930Error NativeProcessNetBSD::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf,
931 size_t size,
932 size_t &bytes_read) {
933 Error error = ReadMemory(addr, buf, size, bytes_read);
934 if (error.Fail())
935 return error;
936 return m_breakpoint_list.RemoveTrapsFromBuffer(addr, buf, size);
937}
938
939Error NativeProcessNetBSD::WriteMemory(lldb::addr_t addr, const void *buf,
940 size_t size, size_t &bytes_written) {
941 const unsigned char *src = static_cast<const unsigned char *>(buf);
942 Error error;
943 struct ptrace_io_desc io;
944
945 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY));
946 LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
947
948 bytes_written = 0;
949 io.piod_op = PIOD_WRITE_D;
950 io.piod_len = size;
951
952 do {
953 io.piod_addr = (void *)(src + bytes_written);
954 io.piod_offs = (void *)(addr + bytes_written);
955
956 Error error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io);
957 if (error.Fail())
958 return error;
959
960 bytes_written = io.piod_len;
961 io.piod_len = size - bytes_written;
962 } while (bytes_written < size);
963
964 return error;
965}
966
967llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
968NativeProcessNetBSD::GetAuxvData() const {
969 /*
970 * ELF_AUX_ENTRIES is currently restricted to kernel
971 * (<sys/exec_elf.h> r. 1.155 specifies 15)
972 *
973 * ptrace(2) returns the whole AUXV including extra fiels after AT_NULL this
974 * information isn't needed.
975 */
976 size_t auxv_size = 100 * sizeof(AuxInfo);
977
978 ErrorOr<std::unique_ptr<MemoryBuffer>> buf =
979 llvm::MemoryBuffer::getNewMemBuffer(auxv_size);
980
981 struct ptrace_io_desc io = {.piod_op = PIOD_READ_AUXV,
982 .piod_offs = 0,
983 .piod_addr = (void *)buf.get()->getBufferStart(),
984 .piod_len = auxv_size};
985
986 Error error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io);
987
988 if (error.Fail())
989 return std::error_code(error.GetError(), std::generic_category());
990
991 if (io.piod_len < 1)
992 return std::error_code(ECANCELED, std::generic_category());
993
994 return buf;
995}
Kamil Rytarowski3eef2b52017-03-30 20:25:29 +0000996
997Error NativeProcessNetBSD::ReinitializeThreads() {
998 // Clear old threads
999 m_threads.clear();
1000
1001 // Initialize new thread
1002 struct ptrace_lwpinfo info = {};
1003 Error error = PtraceWrapper(PT_LWPINFO, GetID(), &info, sizeof(info));
1004 if (error.Fail()) {
1005 return error;
1006 }
1007 // Reinitialize from scratch threads and register them in process
1008 while (info.pl_lwpid != 0) {
1009 NativeThreadNetBSDSP thread_sp = AddThread(info.pl_lwpid);
1010 thread_sp->SetStoppedByExec();
1011 error = PtraceWrapper(PT_LWPINFO, GetID(), &info, sizeof(info));
1012 if (error.Fail()) {
1013 return error;
1014 }
1015 }
1016
1017 return error;
1018}