1 //===-- NativeProcessNetBSD.cpp ------------------------------- -*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "NativeProcessNetBSD.h" 11 12 // C Includes 13 14 // C++ Includes 15 16 // Other libraries and framework includes 17 #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" 18 #include "lldb/Core/State.h" 19 #include "lldb/Host/HostProcess.h" 20 #include "lldb/Host/common/NativeBreakpoint.h" 21 #include "lldb/Host/common/NativeRegisterContext.h" 22 #include "lldb/Host/posix/ProcessLauncherPosixFork.h" 23 #include "lldb/Target/Process.h" 24 25 // System includes - They have to be included after framework includes because 26 // they define some 27 // macros which collide with variable names in other modules 28 // clang-format off 29 #include <sys/types.h> 30 #include <sys/ptrace.h> 31 #include <sys/sysctl.h> 32 #include <sys/wait.h> 33 #include <uvm/uvm_prot.h> 34 #include <elf.h> 35 #include <util.h> 36 // clang-format on 37 38 using namespace lldb; 39 using namespace lldb_private; 40 using namespace lldb_private::process_netbsd; 41 using namespace llvm; 42 43 static 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 56 static 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. 71 static 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 88 // ----------------------------------------------------------------------------- 89 // Public Static Methods 90 // ----------------------------------------------------------------------------- 91 92 Error NativeProcessProtocol::Launch( 93 ProcessLaunchInfo &launch_info, 94 NativeProcessProtocol::NativeDelegate &native_delegate, MainLoop &mainloop, 95 NativeProcessProtocolSP &native_process_sp) { 96 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; 130 } 131 132 Error NativeProcessProtocol::Attach( 133 lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate, 134 MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) { 135 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; 158 } 159 160 // ----------------------------------------------------------------------------- 161 // Public Instance Methods 162 // ----------------------------------------------------------------------------- 163 164 NativeProcessNetBSD::NativeProcessNetBSD() 165 : 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. 169 void 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 182 void 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 198 void 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 219 void 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 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; 256 } 257 } 258 } 259 260 void 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 274 Error 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 297 Error 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 312 Error 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 396 Error 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 410 Error error; 411 412 switch (action->state) { 413 case eStateRunning: { 414 // Run the thread, possibly feeding it the signal. 415 error = NativeProcessNetBSD::PtraceWrapper(PT_CONTINUE, GetID(), (void *)1, 416 action->signal); 417 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: 426 // 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); 435 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 451 Error NativeProcessNetBSD::Halt() { 452 Error error; 453 454 if (kill(GetID(), SIGSTOP) != 0) 455 error.SetErrorToErrno(); 456 457 return error; 458 } 459 460 Error 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 473 Error NativeProcessNetBSD::Signal(int signo) { 474 Error error; 475 476 if (kill(GetID(), signo)) 477 error.SetErrorToErrno(); 478 479 return error; 480 } 481 482 Error 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 518 Error 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 576 Error 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 642 Error NativeProcessNetBSD::AllocateMemory(size_t size, uint32_t permissions, 643 lldb::addr_t &addr) { 644 return Error("Unimplemented"); 645 } 646 647 Error NativeProcessNetBSD::DeallocateMemory(lldb::addr_t addr) { 648 return Error("Unimplemented"); 649 } 650 651 lldb::addr_t NativeProcessNetBSD::GetSharedLibraryInfoAddress() { 652 // punt on this for now 653 return LLDB_INVALID_ADDRESS; 654 } 655 656 size_t NativeProcessNetBSD::UpdateThreads() { return m_threads.size(); } 657 658 bool NativeProcessNetBSD::GetArchitecture(ArchSpec &arch) const { 659 arch = m_arch; 660 return true; 661 } 662 663 Error 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 671 Error 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 688 Error NativeProcessNetBSD::GetLoadedModuleFileSpec(const char *module_path, 689 FileSpec &file_spec) { 690 return Error("Unimplemented"); 691 } 692 693 Error NativeProcessNetBSD::GetFileLoadAddress(const llvm::StringRef &file_name, 694 lldb::addr_t &load_addr) { 695 load_addr = LLDB_INVALID_ADDRESS; 696 return Error(); 697 } 698 699 Error 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 763 error = ReinitializeThreads(); 764 if (error.Fail()) { 765 SetState(StateType::eStateInvalid); 766 return error; 767 } 768 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 777 void 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 801 void 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 850 NativeThreadNetBSDSP 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 870 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 */ 891 error = ReinitializeThreads(); 892 if (error.Fail()) { 893 SetState(StateType::eStateInvalid); 894 return -1; 895 } 896 897 // Let our process instance know the thread has stopped. 898 SetState(StateType::eStateStopped); 899 900 return pid; 901 } 902 903 Error 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 930 Error 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 939 Error 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 967 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> 968 NativeProcessNetBSD::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 } 996 997 Error 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 } 1019