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