pkgsrc-WIP-changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lldb-netbsd: Add code for Attach and Launch



Module Name:	pkgsrc-wip
Committed By:	Kamil Rytarowski <n54%gmx.com@localhost>
Pushed By:	kamil
Date:		Sun Mar 26 04:49:49 2017 +0200
Changeset:	a613e93053a8e40f313572a8fa38962bb66af6a8

Modified Files:
	lldb-git/distinfo
	lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp
	lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.h
	lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp
	lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.h

Log Message:
lldb-netbsd: Add code for Attach and Launch

This patch adds missing functions in the virtual class NativeProcessNetBSD:
 - NativeProcessNetBSD::Resume
 - NativeProcessNetBSD::Halt
 - NativeProcessNetBSD::Detach
 - NativeProcessNetBSD::Signal
 - NativeProcessNetBSD::Kill
 - NativeProcessNetBSD::GetMemoryRegionInfo
 - NativeProcessNetBSD::PopulateMemoryRegionCache
 - NativeProcessNetBSD::AllocateMemory
 - NativeProcessNetBSD::DeallocateMemory
 - NativeProcessNetBSD::GetSharedLibraryInfoAddress
 - NativeProcessNetBSD::UpdateThreads
 - NativeProcessNetBSD::SetBreakpoint
 - NativeProcessNetBSD::GetSoftwareBreakpointTrapOpcode
 - NativeProcessNetBSD::GetLoadedModuleFileSpec
 - NativeProcessNetBSD::GetFileLoadAddress
 - NativeProcessNetBSD::LaunchInferior
 - NativeProcessNetBSD::AttachToInferior
 - NativeProcessNetBSD::SigchldHandler
 - NativeThreadNetBSD::SetRunning
 - EnsureFDFlags
 - NativeProcessNetBSD::AddThread
 - NativeProcessNetBSD::Attach
 - NativeThreadNetBSD::GetName
 - NativeThreadNetBSD::GetState
 - NativeThreadNetBSD::GetStopReason
 - NativeThreadNetBSD::GetRegisterContext
 - NativeThreadNetBSD::SetWatchpoint
 - NativeThreadNetBSD::RemoveWatchpoint
 - NativeThreadNetBSD::SetHardwareBreakpoint
 - NativeThreadNetBSD::RemoveHardwareBreakpoint
 - NativeProcessNetBSD::ReadMemory
 - NativeProcessNetBSD::ReadMemoryWithoutTrap
 - NativeProcessNetBSD::WriteMemory
 - NativeProcessNetBSD::GetAuxvData

Add missing body to functions:
 - NativeProcessProtocol::Launch
 - NativeProcessProtocol::Attach

Sponsored by <The NetBSD Foundation>

To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=a613e93053a8e40f313572a8fa38962bb66af6a8

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

diffstat:
 lldb-git/distinfo                                  |   8 +-
 ..._Plugins_Process_NetBSD_NativeProcessNetBSD.cpp | 728 ++++++++++++++++++++-
 ...ce_Plugins_Process_NetBSD_NativeProcessNetBSD.h |  71 +-
 ...e_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp | 103 ++-
 ...rce_Plugins_Process_NetBSD_NativeThreadNetBSD.h |  25 +-
 5 files changed, 924 insertions(+), 11 deletions(-)

diffs:
diff --git a/lldb-git/distinfo b/lldb-git/distinfo
index e2f99a21fe..dd4b601dc8 100644
--- a/lldb-git/distinfo
+++ b/lldb-git/distinfo
@@ -13,11 +13,11 @@ SHA1 (llvm-3.6.2.src.tar.xz) = 7a00257eb2bc9431e4c77c3a36b033072c54bc7e
 RMD160 (llvm-3.6.2.src.tar.xz) = 521cbc5fe2925ea3c6e90c7a31f752a04045c972
 Size (llvm-3.6.2.src.tar.xz) = 12802380 bytes
 SHA1 (patch-source_Plugins_Process_NetBSD_CMakeLists.txt) = 4af51b7cd3d344e503436a456ba4c3021f5ea420
-SHA1 (patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp) = c3edad360e4dea3f24b020656129b7fd9af42612
-SHA1 (patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.h) = 712c214fd695514f7ddb04aaeede6c7aa0f58f12
+SHA1 (patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp) = c0233356bd8b290e7f0cf3d18103ab57fb265615
+SHA1 (patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.h) = bcad5c8debb05c44f95a1d00d124314be824ec1d
 SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.cpp) = 85263360ba595a703b089a76af3b5ca54b689edc
 SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD.h) = 7ef78e3cc7e45ba79a66b5555d526efeefe29090
 SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.cpp) = 6ba98edbfffef92b87b8d93d438cae72ea11f392
 SHA1 (patch-source_Plugins_Process_NetBSD_NativeRegisterContextNetBSD__x86__64.h) = 6e1385ffe58efc8a39151df1ed57d7c253edda4e
-SHA1 (patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp) = 99031f666f449032ffd645edf6e92f25b790bfa6
-SHA1 (patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.h) = 0460e9f7cf9414cabfd0b70ff8311acd8280fb13
+SHA1 (patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp) = 7984820fd37e7e95e7d4827c4cc30310e4751d7e
+SHA1 (patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.h) = 2ad544c23cd6398c54b6d06a1b252aa19af8e5d5
diff --git a/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp
index 32b7a85844..9de7318d26 100644
--- a/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp
+++ b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.cpp
@@ -2,14 +2,17 @@ $NetBSD$
 
 --- source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp.orig	2017-03-21 17:54:57.000000000 +0000
 +++ source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
-@@ -14,18 +14,49 @@
+@@ -14,18 +14,75 @@
  // C++ Includes
  
  // Other libraries and framework includes
 -
  #include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
++#include "lldb/Core/State.h"
++#include "lldb/Host/HostProcess.h"
 +#include "lldb/Host/common/NativeBreakpoint.h"
 +#include "lldb/Host/common/NativeRegisterContext.h"
++#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
 +#include "lldb/Target/Process.h"
  
  // System includes - They have to be included after framework includes because
@@ -17,7 +20,11 @@ $NetBSD$
  // macros which collide with variable names in other modules
 +#include <sys/types.h>
 +#include <sys/ptrace.h>
++#include <sys/sysctl.h>
 +#include <sys/wait.h>
++#include <uvm/uvm_prot.h>
++#include <elf.h>
++#include <util.h>
  
  using namespace lldb;
  using namespace lldb_private;
@@ -50,10 +57,100 @@ $NetBSD$
 +  }
 +}
 +
++// Simple helper function to ensure flags are enabled on the given file
++// descriptor.
++static Error EnsureFDFlags(int fd, int flags) {
++  Error error;
++
++  int status = fcntl(fd, F_GETFL);
++  if (status == -1) {
++    error.SetErrorToErrno();
++    return error;
++  }
++
++  if (fcntl(fd, F_SETFL, status | flags) == -1) {
++    error.SetErrorToErrno();
++    return error;
++  }
++
++  return error;
++}
++
  // -----------------------------------------------------------------------------
  // Public Static Methods
  // -----------------------------------------------------------------------------
-@@ -48,4 +79,215 @@ Error NativeProcessProtocol::Attach(
+@@ -34,13 +91,68 @@ Error NativeProcessProtocol::Launch(
+     ProcessLaunchInfo &launch_info,
+     NativeProcessProtocol::NativeDelegate &native_delegate, MainLoop &mainloop,
+     NativeProcessProtocolSP &native_process_sp) {
+-  return Error();
++  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
++
++  Error error;
++
++  // Verify the working directory is valid if one was specified.
++  FileSpec working_dir{launch_info.GetWorkingDirectory()};
++  if (working_dir && (!working_dir.ResolvePath() ||
++                      !llvm::sys::fs::is_directory(working_dir.GetPath()))) {
++    error.SetErrorStringWithFormat("No such file or directory: %s",
++                                   working_dir.GetCString());
++    return error;
++  }
++
++  // Create the NativeProcessNetBSD in launch mode.
++  native_process_sp.reset(new NativeProcessNetBSD());
++
++  if (!native_process_sp->RegisterNativeDelegate(native_delegate)) {
++    native_process_sp.reset();
++    error.SetErrorStringWithFormat("failed to register the native delegate");
++    return error;
++  }
++
++  error = std::static_pointer_cast<NativeProcessNetBSD>(native_process_sp)
++              ->LaunchInferior(mainloop, launch_info);
++
++  if (error.Fail()) {
++    native_process_sp.reset();
++    LLDB_LOG(log, "failed to launch process: {0}", error);
++    return error;
++  }
++
++  launch_info.SetProcessID(native_process_sp->GetID());
++
++  return error;
+ }
+ 
+ Error NativeProcessProtocol::Attach(
+     lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
+     MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) {
+-  return Error();
++  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
++  LLDB_LOG(log, "pid = {0:x}", pid);
++
++  // Retrieve the architecture for the running process.
++  ArchSpec process_arch;
++  Error error = ResolveProcessArchitecture(pid, process_arch);
++  if (!error.Success())
++    return error;
++
++  std::shared_ptr<NativeProcessNetBSD> native_process_netbsd_sp(
++      new NativeProcessNetBSD());
++
++  if (!native_process_netbsd_sp->RegisterNativeDelegate(native_delegate)) {
++    error.SetErrorStringWithFormat("failed to register the native delegate");
++    return error;
++  }
++
++  native_process_netbsd_sp->AttachToInferior(mainloop, pid, error);
++  if (!error.Success())
++    return error;
++
++  native_process_sp = native_process_netbsd_sp;
++  return error;
+ }
+ 
+ // -----------------------------------------------------------------------------
+@@ -48,4 +160,842 @@ Error NativeProcessProtocol::Attach(
  // -----------------------------------------------------------------------------
  
  NativeProcessNetBSD::NativeProcessNetBSD()
@@ -270,3 +367,630 @@ $NetBSD$
 +  }
 +  return error;
 +}
++
++Error NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
++  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
++  LLDB_LOG(log, "pid {0}", GetID());
++
++  const auto &thread_sp = m_threads[0];
++  const ResumeAction *const action =
++      resume_actions.GetActionForThread(thread_sp->GetID(), true);
++
++  if (action == nullptr) {
++    LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(),
++             thread_sp->GetID());
++    return Error();
++  }
++
++  switch (action->state) {
++  case eStateRunning: {
++    // Run the thread, possibly feeding it the signal.
++    Error error = NativeProcessNetBSD::PtraceWrapper(PT_CONTINUE, GetID(),
++                                                     (void *)1, action->signal);
++    if (!error.Success())
++      return error;
++    for (const auto &thread_sp : m_threads) {
++      static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetRunning();
++    }
++    SetState(eStateRunning, true);
++    break;
++  }
++  case eStateStepping:
++    return Error("Not implemented");
++    break;
++
++  case eStateSuspended:
++  case eStateStopped:
++    llvm_unreachable("Unexpected state");
++
++  default:
++    return Error("NativeProcessLinux::%s (): unexpected state %s specified "
++                 "for pid %" PRIu64 ", tid %" PRIu64,
++                 __FUNCTION__, StateAsCString(action->state), GetID(),
++                 thread_sp->GetID());
++  }
++
++  return Error();
++}
++
++Error NativeProcessNetBSD::Halt() {
++  Error error;
++
++  if (kill(GetID(), SIGSTOP) != 0)
++    error.SetErrorToErrno();
++
++  return error;
++}
++
++Error NativeProcessNetBSD::Detach() {
++  Error error;
++
++  // Stop monitoring the inferior.
++  m_sigchld_handle.reset();
++
++  // Tell ptrace to detach from the process.
++  if (GetID() == LLDB_INVALID_PROCESS_ID)
++    return error;
++
++  return PtraceWrapper(PT_DETACH, GetID());
++}
++
++Error NativeProcessNetBSD::Signal(int signo) {
++  Error error;
++
++  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
++  LLDB_LOG(log, "selecting running thread for interrupt target");
++
++  if (kill(GetID(), signo))
++    error.SetErrorToErrno();
++
++  return error;
++}
++
++Error NativeProcessNetBSD::Kill() {
++  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
++  LLDB_LOG(log, "pid {0}", GetID());
++
++  Error error;
++
++  switch (m_state) {
++  case StateType::eStateInvalid:
++  case StateType::eStateExited:
++  case StateType::eStateCrashed:
++  case StateType::eStateDetached:
++  case StateType::eStateUnloaded:
++    // Nothing to do - the process is already dead.
++    LLDB_LOG(log, "ignored for PID {0} due to current state: {1}", GetID(),
++             StateAsCString(m_state));
++    return error;
++
++  case StateType::eStateConnected:
++  case StateType::eStateAttaching:
++  case StateType::eStateLaunching:
++  case StateType::eStateStopped:
++  case StateType::eStateRunning:
++  case StateType::eStateStepping:
++  case StateType::eStateSuspended:
++    // We can try to kill a process in these states.
++    break;
++  }
++
++  if (kill(GetID(), SIGKILL) != 0) {
++    error.SetErrorToErrno();
++    return error;
++  }
++
++  return error;
++}
++
++Error NativeProcessNetBSD::GetMemoryRegionInfo(lldb::addr_t load_addr,
++                                               MemoryRegionInfo &range_info) {
++
++  if (m_supports_mem_region == LazyBool::eLazyBoolNo) {
++    // We're done.
++    return Error("unsupported");
++  }
++
++  Error error = PopulateMemoryRegionCache();
++  if (error.Fail()) {
++    return error;
++  }
++
++  lldb::addr_t prev_base_address = 0;
++  // FIXME start by finding the last region that is <= target address using
++  // binary search.  Data is sorted.
++  // There can be a ton of regions on pthreads apps with lots of threads.
++  for (auto it = m_mem_region_cache.begin(); it != m_mem_region_cache.end();
++       ++it) {
++    MemoryRegionInfo &proc_entry_info = it->first;
++    // Sanity check assumption that /proc/{pid}/maps entries are ascending.
++    assert((proc_entry_info.GetRange().GetRangeBase() >= prev_base_address) &&
++           "descending /proc/pid/maps entries detected, unexpected");
++    prev_base_address = proc_entry_info.GetRange().GetRangeBase();
++    UNUSED_IF_ASSERT_DISABLED(prev_base_address);
++    // If the target address comes before this entry, indicate distance to next
++    // region.
++    if (load_addr < proc_entry_info.GetRange().GetRangeBase()) {
++      range_info.GetRange().SetRangeBase(load_addr);
++      range_info.GetRange().SetByteSize(
++          proc_entry_info.GetRange().GetRangeBase() - load_addr);
++      range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
++      range_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
++      range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
++      range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
++      return error;
++    } else if (proc_entry_info.GetRange().Contains(load_addr)) {
++      // The target address is within the memory region we're processing here.
++      range_info = proc_entry_info;
++      return error;
++    }
++    // The target memory address comes somewhere after the region we just
++    // parsed.
++  }
++  // If we made it here, we didn't find an entry that contained the given
++  // address. Return the
++  // load_addr as start and the amount of bytes betwwen load address and the end
++  // of the memory as
++  // size.
++  range_info.GetRange().SetRangeBase(load_addr);
++  range_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
++  range_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
++  range_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
++  range_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
++  range_info.SetMapped(MemoryRegionInfo::OptionalBool::eNo);
++  return error;
++}
++
++Error NativeProcessNetBSD::PopulateMemoryRegionCache() {
++  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
++  // If our cache is empty, pull the latest.  There should always be at least
++  // one memory region if memory region handling is supported.
++  if (!m_mem_region_cache.empty()) {
++    LLDB_LOG(log, "reusing {0} cached memory region entries",
++             m_mem_region_cache.size());
++    return Error();
++  }
++
++  struct kinfo_vmentry *vm;
++  size_t count, i;
++  vm = kinfo_getvmmap(GetID(), &count);
++  if (vm == NULL) {
++    m_supports_mem_region = LazyBool::eLazyBoolNo;
++    Error error;
++    error.SetErrorString("not supported");
++    return error;
++  }
++  for (i = 0; i < count; i++) {
++    MemoryRegionInfo info;
++    info.Clear();
++    info.GetRange().SetRangeBase(vm[i].kve_start);
++    info.GetRange().SetRangeEnd(vm[i].kve_end);
++    info.SetMapped(MemoryRegionInfo::OptionalBool::eYes);
++
++    if (vm[i].kve_protection & VM_PROT_READ)
++      info.SetReadable(MemoryRegionInfo::OptionalBool::eYes);
++    else
++      info.SetReadable(MemoryRegionInfo::OptionalBool::eNo);
++
++    if (vm[i].kve_protection & VM_PROT_WRITE)
++      info.SetWritable(MemoryRegionInfo::OptionalBool::eYes);
++    else
++      info.SetWritable(MemoryRegionInfo::OptionalBool::eNo);
++
++    if (vm[i].kve_protection & VM_PROT_EXECUTE)
++      info.SetExecutable(MemoryRegionInfo::OptionalBool::eYes);
++    else
++      info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo);
++
++    if (vm[i].kve_path[0])
++      info.SetName(vm[i].kve_path);
++
++    m_mem_region_cache.emplace_back(
++        info, FileSpec(info.GetName().GetCString(), true));
++  }
++  free(vm);
++
++  if (m_mem_region_cache.empty()) {
++    // No entries after attempting to read them.  This shouldn't happen.
++    // Assume we don't support map entries.
++    LLDB_LOG(log, "failed to find any vmmap entries, assuming no support "
++                  "for memory region metadata retrieval");
++    m_supports_mem_region = LazyBool::eLazyBoolNo;
++    Error error;
++    error.SetErrorString("not supported");
++    return error;
++  }
++  LLDB_LOG(log, "read {0} memory region entries from process {1}",
++           m_mem_region_cache.size(), GetID());
++  // We support memory retrieval, remember that.
++  m_supports_mem_region = LazyBool::eLazyBoolYes;
++  return Error();
++}
++
++Error NativeProcessNetBSD::AllocateMemory(size_t size, uint32_t permissions,
++                                          lldb::addr_t &addr) {
++  return Error();
++}
++
++Error NativeProcessNetBSD::DeallocateMemory(lldb::addr_t addr) {
++  return Error();
++}
++
++lldb::addr_t NativeProcessNetBSD::GetSharedLibraryInfoAddress() {
++  // punt on this for now
++  return LLDB_INVALID_ADDRESS;
++}
++
++size_t NativeProcessNetBSD::UpdateThreads() { return m_threads.size(); }
++
++bool NativeProcessNetBSD::GetArchitecture(ArchSpec &arch) const {
++  arch = m_arch;
++  return true;
++}
++
++Error NativeProcessNetBSD::SetBreakpoint(lldb::addr_t addr, uint32_t size,
++                                         bool hardware) {
++  if (hardware)
++    return Error("NativeProcessNetBSD does not support hardware breakpoints");
++  else
++    return SetSoftwareBreakpoint(addr, size);
++}
++
++Error NativeProcessNetBSD::GetSoftwareBreakpointTrapOpcode(
++    size_t trap_opcode_size_hint, size_t &actual_opcode_size,
++    const uint8_t *&trap_opcode_bytes) {
++  static const uint8_t g_i386_opcode[] = {0xCC};
++
++  switch (m_arch.GetMachine()) {
++  case llvm::Triple::x86:
++  case llvm::Triple::x86_64:
++    trap_opcode_bytes = g_i386_opcode;
++    actual_opcode_size = sizeof(g_i386_opcode);
++    return Error();
++  default:
++    assert(false && "CPU type not supported!");
++    return Error("CPU type not supported");
++  }
++}
++
++Error NativeProcessNetBSD::GetLoadedModuleFileSpec(const char *module_path,
++                                                   FileSpec &file_spec) {
++  FileSpec module_file_spec(module_path, true);
++
++  bool found = false;
++  file_spec.Clear();
++
++  if (!found)
++    return Error("Module file (%s) not found in /proc/%" PRIu64 "/maps file!",
++                 module_file_spec.GetFilename().AsCString(), GetID());
++
++  return Error();
++}
++
++Error NativeProcessNetBSD::GetFileLoadAddress(const llvm::StringRef &file_name,
++                                              lldb::addr_t &load_addr) {
++  load_addr = LLDB_INVALID_ADDRESS;
++  return Error();
++}
++
++Error NativeProcessNetBSD::LaunchInferior(MainLoop &mainloop,
++                                          ProcessLaunchInfo &launch_info) {
++  Error error;
++  m_sigchld_handle = mainloop.RegisterSignal(
++      SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
++  if (!m_sigchld_handle)
++    return error;
++
++  SetState(eStateLaunching);
++
++  ::pid_t pid = ProcessLauncherPosixFork()
++                    .LaunchProcess(launch_info, error)
++                    .GetProcessId();
++  if (error.Fail())
++    return error;
++
++  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
++
++  // Wait for the child process to trap on its call to execve.
++  ::pid_t wpid;
++  int status;
++  if ((wpid = waitpid(pid, &status, 0)) < 0) {
++    error.SetErrorToErrno();
++    LLDB_LOG(log, "waitpid for inferior failed with %s", error);
++
++    // Mark the inferior as invalid.
++    // FIXME this could really use a new state - eStateLaunchFailure.  For now,
++    // using eStateInvalid.
++    SetState(StateType::eStateInvalid);
++
++    return error;
++  }
++  assert(WIFSTOPPED(status) && (wpid == static_cast<::pid_t>(pid)) &&
++         "Could not sync with inferior process.");
++
++  LLDB_LOG(log, "inferior started, now in stopped state");
++
++  // Release the master terminal descriptor and pass it off to the
++  // NativeProcessNetBSD instance.  Similarly stash the inferior pid.
++  m_terminal_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
++  m_pid = pid;
++  launch_info.SetProcessID(pid);
++
++  if (m_terminal_fd != -1) {
++    error = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
++    if (error.Fail()) {
++      LLDB_LOG(log,
++               "inferior EnsureFDFlags failed for ensuring terminal "
++               "O_NONBLOCK setting: {0}",
++               error);
++
++      // Mark the inferior as invalid.
++      // FIXME this could really use a new state - eStateLaunchFailure.  For
++      // now, using eStateInvalid.
++      SetState(StateType::eStateInvalid);
++
++      return error;
++    }
++  }
++
++  LLDB_LOG(log, "adding pid = {0}", pid);
++
++  ResolveProcessArchitecture(m_pid, m_arch);
++
++  /* Initialize threads */
++  struct ptrace_lwpinfo info = {};
++  error = PtraceWrapper(PT_LWPINFO, pid, &info, sizeof(info));
++  if (error.Fail()) {
++    SetState(StateType::eStateInvalid);
++    return error;
++  }
++  while (info.pl_lwpid != 0) {
++    NativeThreadNetBSDSP thread_sp = AddThread(info.pl_lwpid);
++    thread_sp->SetStoppedBySignal(SIGSTOP);
++    error = PtraceWrapper(PT_LWPINFO, pid, &info, sizeof(info));
++    if (error.Fail()) {
++      SetState(StateType::eStateInvalid);
++      return error;
++    }
++  }
++
++  /* Set process stopped */
++  SetState(StateType::eStateStopped);
++
++  if (error.Fail())
++    LLDB_LOG(log, "inferior launching failed {0}", error);
++  return error;
++}
++
++void NativeProcessNetBSD::AttachToInferior(MainLoop &mainloop, lldb::pid_t pid,
++                                           Error &error) {
++  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
++  LLDB_LOG(log, "pid = {0:x}", pid);
++
++  m_sigchld_handle = mainloop.RegisterSignal(
++      SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
++  if (!m_sigchld_handle)
++    return;
++
++  error = ResolveProcessArchitecture(pid, m_arch);
++  if (!error.Success())
++    return;
++
++  // Set the architecture to the exe architecture.
++  LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,
++           m_arch.GetArchitectureName());
++
++  m_pid = pid;
++  SetState(eStateAttaching);
++
++  Attach(pid, error);
++}
++
++void NativeProcessNetBSD::SigchldHandler() {
++  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
++  // Process all pending waitpid notifications.
++  int status;
++  ::pid_t wait_pid = waitpid(WAIT_ANY, &status, WALLSIG | WNOHANG);
++
++  if (wait_pid == 0)
++    return; // We are done.
++
++  if (wait_pid == -1) {
++    if (errno == EINTR)
++      return;
++
++    Error error(errno, eErrorTypePOSIX);
++    LLDB_LOG(log, "waitpid (-1, &status, _) failed: {0}", error);
++  }
++
++  bool exited = false;
++  int signal = 0;
++  int exit_status = 0;
++  const char *status_cstr = nullptr;
++  if (WIFSTOPPED(status)) {
++    signal = WSTOPSIG(status);
++    status_cstr = "STOPPED";
++  } else if (WIFEXITED(status)) {
++    exit_status = WEXITSTATUS(status);
++    status_cstr = "EXITED";
++    exited = true;
++  } else if (WIFSIGNALED(status)) {
++    signal = WTERMSIG(status);
++    status_cstr = "SIGNALED";
++    if (wait_pid == static_cast<::pid_t>(GetID())) {
++      exited = true;
++      exit_status = -1;
++    }
++  } else
++    status_cstr = "(\?\?\?)";
++
++  LLDB_LOG(log,
++           "waitpid (-1, &status, _) => pid = {0}, status = {1:x} "
++           "({2}), signal = {3}, exit_state = {4}",
++           wait_pid, status, status_cstr, signal, exit_status);
++
++  if (exited)
++    MonitorExited(wait_pid, signal, exit_status);
++  else
++    MonitorCallback(wait_pid, signal);
++}
++
++NativeThreadNetBSDSP NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) {
++
++  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
++  LLDB_LOG(log, "pid {0} adding thread with tid {1}", GetID(), thread_id);
++
++  assert(!HasThreadNoLock(thread_id) &&
++         "attempted to add a thread by id that already exists");
++
++  // If this is the first thread, save it as the current thread
++  if (m_threads.empty())
++    SetCurrentThreadID(thread_id);
++
++  auto thread_sp = std::make_shared<NativeThreadNetBSD>(this, thread_id);
++  m_threads.push_back(thread_sp);
++  return thread_sp;
++}
++
++::pid_t NativeProcessNetBSD::Attach(lldb::pid_t pid, Error &error) {
++  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
++
++  // Use a map to keep track of the threads which we have attached/need to
++  // attach.
++  Host::TidMap tids_to_attach;
++  if (pid <= 1) {
++    error.SetErrorToGenericError();
++    error.SetErrorString("Attaching to process 1 is not allowed.");
++    return -1;
++  }
++
++  // Attach to the requested process.
++  // An attach will cause the thread to stop with a SIGSTOP.
++  error = PtraceWrapper(PT_ATTACH, pid);
++  if (error.Fail())
++    return -1;
++
++  int status;
++  // Need to use WALLSIG otherwise we receive an error with errno=ECHLD
++  // At this point we should have a thread stopped if waitpid succeeds.
++  if ((status = waitpid(pid, NULL, WALLSIG)) < 0)
++    return -1;
++
++  m_pid = pid;
++
++  /* Initialize threads */
++  struct ptrace_lwpinfo info = {};
++  error = PtraceWrapper(PT_LWPINFO, pid, &info, sizeof(info));
++  if (error.Fail()) {
++    SetState(StateType::eStateInvalid);
++    return -1;
++  }
++  while (info.pl_lwpid != 0) {
++    NativeThreadNetBSDSP thread_sp = AddThread(info.pl_lwpid);
++    thread_sp->SetStoppedBySignal(SIGSTOP);
++    error = PtraceWrapper(PT_LWPINFO, pid, &info, sizeof(info));
++    if (error.Fail()) {
++      SetState(StateType::eStateInvalid);
++      return -1;
++    }
++  }
++
++  // Let our process instance know the thread has stopped.
++  SetState(StateType::eStateStopped);
++
++  return pid;
++}
++
++Error NativeProcessNetBSD::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
++                                      size_t &bytes_read) {
++  unsigned char *dst = static_cast<unsigned char *>(buf);
++  struct ptrace_io_desc io;
++
++  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY));
++  LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
++
++  bytes_read = 0;
++  io.piod_op = PIOD_READ_D;
++  io.piod_len = size;
++
++  do {
++    io.piod_offs = (void *)(addr + bytes_read);
++    io.piod_addr = dst + bytes_read;
++
++    Error error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io);
++    if (error.Fail())
++      return error;
++
++    bytes_read = io.piod_len;
++    io.piod_len = size - bytes_read;
++  } while (bytes_read < size);
++
++  return Error();
++}
++
++Error NativeProcessNetBSD::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf,
++                                                 size_t size,
++                                                 size_t &bytes_read) {
++  Error error = ReadMemory(addr, buf, size, bytes_read);
++  if (error.Fail())
++    return error;
++  return m_breakpoint_list.RemoveTrapsFromBuffer(addr, buf, size);
++}
++
++Error NativeProcessNetBSD::WriteMemory(lldb::addr_t addr, const void *buf,
++                                       size_t size, size_t &bytes_written) {
++  const unsigned char *src = static_cast<const unsigned char *>(buf);
++  Error error;
++  struct ptrace_io_desc io;
++
++  Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY));
++  LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
++
++  bytes_written = 0;
++  io.piod_op = PIOD_WRITE_D;
++  io.piod_len = size;
++
++  do {
++    io.piod_addr = (void *)(src + bytes_written);
++    io.piod_offs = (void *)(addr + bytes_written);
++
++    Error error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io);
++    if (error.Fail())
++      return error;
++
++    bytes_written = io.piod_len;
++    io.piod_len = size - bytes_written;
++  } while (bytes_written < size);
++
++  return error;
++}
++
++llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
++NativeProcessNetBSD::GetAuxvData() const {
++  /*
++   * ELF_AUX_ENTRIES is currently restricted to kernel
++   * (<sys/exec_elf.h> r. 1.155 specifies 15)
++   *
++   * ptrace(2) returns the whole AUXV including extra fiels after AT_NULL this
++   * information isn't needed.
++   */
++  size_t auxv_size = 100 * sizeof(AuxInfo);
++
++  ErrorOr<std::unique_ptr<MemoryBuffer>> buf =
++      llvm::MemoryBuffer::getNewMemBuffer(auxv_size);
++
++  struct ptrace_io_desc io = {.piod_op = PIOD_READ_AUXV,
++                              .piod_offs = 0,
++                              .piod_addr = (void *)buf.get()->getBufferStart(),
++                              .piod_len = auxv_size};
++
++  Error error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io);
++
++  if (error.Fail())
++    return std::error_code(error.GetError(), std::generic_category());
++
++  if (io.piod_len < 1)
++    return std::error_code(ECANCELED, std::generic_category());
++
++  return buf;
++}
diff --git a/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.h b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.h
index 53b451ec80..0c958649e4 100644
--- a/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.h
+++ b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeProcessNetBSD.h
@@ -2,25 +2,90 @@ $NetBSD$
 
 --- source/Plugins/Process/NetBSD/NativeProcessNetBSD.h.orig	2017-03-21 17:54:57.000000000 +0000
 +++ source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
-@@ -39,8 +39,29 @@ class NativeProcessNetBSD : public Nativ
+@@ -39,8 +39,98 @@ class NativeProcessNetBSD : public Nativ
        lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
        MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
  
 +public:
 +  // ---------------------------------------------------------------------
++  // NativeProcessProtocol Interface
++  // ---------------------------------------------------------------------
++  Error Resume(const ResumeActionList &resume_actions) override;
++
++  Error Halt() override;
++
++  Error Detach() override;
++
++  Error Signal(int signo) override;
++
++  Error Kill() override;
++
++  Error GetMemoryRegionInfo(lldb::addr_t load_addr,
++                            MemoryRegionInfo &range_info) override;
++
++  Error ReadMemory(lldb::addr_t addr, void *buf, size_t size,
++                   size_t &bytes_read) override;
++
++  Error ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size,
++                              size_t &bytes_read) override;
++
++  Error WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
++                    size_t &bytes_written) override;
++
++  Error AllocateMemory(size_t size, uint32_t permissions,
++                       lldb::addr_t &addr) override;
++
++  Error DeallocateMemory(lldb::addr_t addr) override;
++
++  lldb::addr_t GetSharedLibraryInfoAddress() override;
++
++  size_t UpdateThreads() override;
++
++  bool GetArchitecture(ArchSpec &arch) const override;
++
++  Error SetBreakpoint(lldb::addr_t addr, uint32_t size, bool hardware) override;
++
++  Error GetLoadedModuleFileSpec(const char *module_path,
++                                FileSpec &file_spec) override;
++
++  Error GetFileLoadAddress(const llvm::StringRef &file_name,
++                           lldb::addr_t &load_addr) override;
++
++  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
++  GetAuxvData() const override;
++
++  // ---------------------------------------------------------------------
 +  // Interface used by NativeRegisterContext-derived classes.
 +  // ---------------------------------------------------------------------
 +  static Error PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
 +                             int data = 0, int *result = nullptr);
 +
++protected:
++  // ---------------------------------------------------------------------
++  // NativeProcessProtocol protected interface
++  // ---------------------------------------------------------------------
++
++  Error
++  GetSoftwareBreakpointTrapOpcode(size_t trap_opcode_size_hint,
++                                  size_t &actual_opcode_size,
++                                  const uint8_t *&trap_opcode_bytes) override;
++
  private:
++  MainLoop::SignalHandleUP m_sigchld_handle;
 +  ArchSpec m_arch;
++  LazyBool m_supports_mem_region;
++  std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
 +
 +  // ---------------------------------------------------------------------
 +  // Private Instance Methods
 +  // ---------------------------------------------------------------------
    NativeProcessNetBSD();
 +
++  NativeThreadNetBSDSP AddThread(lldb::tid_t thread_id);
++
++  Error LaunchInferior(MainLoop &mainloop, ProcessLaunchInfo &launch_info);
++  void AttachToInferior(MainLoop &mainloop, lldb::pid_t pid, Error &error);
++
 +  void MonitorCallback(lldb::pid_t pid, int signal);
 +  void MonitorExited(lldb::pid_t pid, int signal, int status);
 +  void MonitorSIGSTOP(lldb::pid_t pid);
@@ -29,6 +94,10 @@ $NetBSD$
 +
 +  Error GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size);
 +  Error FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread);
++  Error PopulateMemoryRegionCache();
++  void SigchldHandler();
++
++  ::pid_t Attach(lldb::pid_t pid, Error &error);
  };
  
  } // namespace process_netbsd
diff --git a/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp
index 9797be2e26..9aa76961c5 100644
--- a/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp
+++ b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.cpp
@@ -2,7 +2,7 @@ $NetBSD$
 
 --- source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp.orig	2017-03-21 17:54:57.000000000 +0000
 +++ source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
-@@ -12,6 +12,11 @@
+@@ -12,10 +12,152 @@
  
  #include "NativeProcessNetBSD.h"
  
@@ -14,10 +14,12 @@ $NetBSD$
  using namespace lldb;
  using namespace lldb_private;
  using namespace lldb_private::process_netbsd;
-@@ -19,3 +24,44 @@ using namespace lldb_private::process_ne
+ 
  NativeThreadNetBSD::NativeThreadNetBSD(NativeProcessNetBSD *process,
                                         lldb::tid_t tid)
-     : NativeThreadProtocol(process, tid) {}
+-    : NativeThreadProtocol(process, tid) {}
++    : NativeThreadProtocol(process, tid), m_state(StateType::eStateInvalid),
++      m_stop_info(), m_reg_context_sp(), m_stop_description() {}
 +
 +void NativeThreadNetBSD::SetStoppedBySignal(uint32_t signo,
 +                                            const siginfo_t *info) {
@@ -59,3 +61,98 @@ $NetBSD$
 +  m_state = new_state;
 +  m_stop_description.clear();
 +}
++
++void NativeThreadNetBSD::SetRunning() {
++  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
++  if (log)
++    log->Printf("NativeThreadNetBSD::%s()", __FUNCTION__);
++
++  m_state = StateType::eStateRunning;
++  m_stop_info.reason = StopReason::eStopReasonNone;
++}
++
++std::string NativeThreadNetBSD::GetName() {
++  NativeProcessProtocolSP process_sp = m_process_wp.lock();
++  if (!process_sp)
++    return "<unknown: no process>";
++
++  // const NativeProcessNetBSD *const process =
++  // reinterpret_cast<NativeProcessNetBSD*> (process_sp->get ());
++  llvm::SmallString<32> thread_name;
++  return std::string("");
++}
++
++lldb::StateType NativeThreadNetBSD::GetState() { return m_state; }
++
++bool NativeThreadNetBSD::GetStopReason(ThreadStopInfo &stop_info,
++                                       std::string &description) {
++  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
++
++  description.clear();
++
++  switch (m_state) {
++  case eStateStopped:
++  case eStateCrashed:
++  case eStateExited:
++  case eStateSuspended:
++  case eStateUnloaded:
++    stop_info = m_stop_info;
++    description = m_stop_description;
++
++    return true;
++
++  case eStateInvalid:
++  case eStateConnected:
++  case eStateAttaching:
++  case eStateLaunching:
++  case eStateRunning:
++  case eStateStepping:
++  case eStateDetached:
++    if (log) {
++      log->Printf("NativeThreadNetBSD::%s tid %" PRIu64
++                  " in state %s cannot answer stop reason",
++                  __FUNCTION__, GetID(), StateAsCString(m_state));
++    }
++    return false;
++  }
++  llvm_unreachable("unhandled StateType!");
++}
++
++NativeRegisterContextSP NativeThreadNetBSD::GetRegisterContext() {
++  // Return the register context if we already created it.
++  if (m_reg_context_sp)
++    return m_reg_context_sp;
++
++  NativeProcessProtocolSP m_process_sp = m_process_wp.lock();
++  if (!m_process_sp)
++    return NativeRegisterContextSP();
++
++  ArchSpec target_arch;
++  if (!m_process_sp->GetArchitecture(target_arch))
++    return NativeRegisterContextSP();
++
++  const uint32_t concrete_frame_idx = 0;
++  m_reg_context_sp.reset(
++      NativeRegisterContextNetBSD::CreateHostNativeRegisterContextNetBSD(
++          target_arch, *this, concrete_frame_idx));
++
++  return m_reg_context_sp;
++}
++
++Error NativeThreadNetBSD::SetWatchpoint(lldb::addr_t addr, size_t size,
++                                        uint32_t watch_flags, bool hardware) {
++  return Error();
++}
++
++Error NativeThreadNetBSD::RemoveWatchpoint(lldb::addr_t addr) {
++  return Error();
++}
++
++Error NativeThreadNetBSD::SetHardwareBreakpoint(lldb::addr_t addr,
++                                                size_t size) {
++  return Error();
++}
++
++Error NativeThreadNetBSD::RemoveHardwareBreakpoint(lldb::addr_t addr) {
++  return Error();
++}
diff --git a/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.h b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.h
index 3cc9a22b9f..2a8c2b781d 100644
--- a/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.h
+++ b/lldb-git/patches/patch-source_Plugins_Process_NetBSD_NativeThreadNetBSD.h
@@ -2,11 +2,32 @@ $NetBSD$
 
 --- source/Plugins/Process/NetBSD/NativeThreadNetBSD.h.orig	2017-03-21 17:54:57.000000000 +0000
 +++ source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
-@@ -22,6 +22,22 @@ class NativeThreadNetBSD : public Native
+@@ -22,6 +22,45 @@ class NativeThreadNetBSD : public Native
  
  public:
    NativeThreadNetBSD(NativeProcessNetBSD *process, lldb::tid_t tid);
 +
++  // ---------------------------------------------------------------------
++  // NativeThreadProtocol Interface
++  // ---------------------------------------------------------------------
++  std::string GetName() override;
++
++  lldb::StateType GetState() override;
++
++  bool GetStopReason(ThreadStopInfo &stop_info,
++                     std::string &description) override;
++
++  NativeRegisterContextSP GetRegisterContext() override;
++
++  Error SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags,
++                      bool hardware) override;
++
++  Error RemoveWatchpoint(lldb::addr_t addr) override;
++
++  Error SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
++
++  Error RemoveHardwareBreakpoint(lldb::addr_t addr) override;
++
 +private:
 +  // ---------------------------------------------------------------------
 +  // Interface for friend classes
@@ -15,12 +36,14 @@ $NetBSD$
 +  void SetStoppedBySignal(uint32_t signo, const siginfo_t *info = nullptr);
 +  void SetStoppedByBreakpoint();
 +  void SetStopped();
++  void SetRunning();
 +
 +  // ---------------------------------------------------------------------
 +  // Member Variables
 +  // ---------------------------------------------------------------------
 +  lldb::StateType m_state;
 +  ThreadStopInfo m_stop_info;
++  NativeRegisterContextSP m_reg_context_sp;
 +  std::string m_stop_description;
  };
  



Home | Main Index | Thread Index | Old Index