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