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