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