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