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