summaryrefslogtreecommitdiff
path: root/source/Plugins/Process
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-20 18:01:57 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-20 18:01:57 +0000
commit88c643b6fec27eec436c8d138fee6346e92337d6 (patch)
tree82cd13b2f3cde1c9e5f79689ba4e6ba67694843f /source/Plugins/Process
parent94994d372d014ce4c8758b9605d63fae651bd8aa (diff)
Notes
Diffstat (limited to 'source/Plugins/Process')
-rw-r--r--source/Plugins/Process/CMakeLists.txt19
-rw-r--r--source/Plugins/Process/FreeBSD/CMakeLists.txt24
-rw-r--r--source/Plugins/Process/Linux/CMakeLists.txt24
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.cpp2097
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.h261
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp196
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux.h85
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp975
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h169
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp985
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h169
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp1053
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h140
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp804
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h149
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp638
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h115
-rwxr-xr-xsource/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp1213
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h149
-rw-r--r--source/Plugins/Process/Linux/NativeThreadLinux.cpp451
-rw-r--r--source/Plugins/Process/Linux/NativeThreadLinux.h119
-rw-r--r--source/Plugins/Process/Linux/ProcessorTrace.cpp395
-rw-r--r--source/Plugins/Process/Linux/ProcessorTrace.h141
-rw-r--r--source/Plugins/Process/Linux/Procfs.h31
-rw-r--r--source/Plugins/Process/Linux/SingleStepCheck.cpp182
-rw-r--r--source/Plugins/Process/Linux/SingleStepCheck.h57
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/CMakeLists.txt22
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp1289
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h260
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp1037
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h220
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp35
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h43
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp147
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h44
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp148
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h45
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp115
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h39
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp118
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h39
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp170
-rw-r--r--source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h77
-rw-r--r--source/Plugins/Process/NetBSD/CMakeLists.txt16
-rw-r--r--source/Plugins/Process/POSIX/CMakeLists.txt10
-rw-r--r--source/Plugins/Process/Utility/CMakeLists.txt64
-rw-r--r--source/Plugins/Process/Windows/Common/CMakeLists.txt33
-rw-r--r--source/Plugins/Process/Windows/Common/DebuggerThread.cpp520
-rw-r--r--source/Plugins/Process/Windows/Common/DebuggerThread.h106
-rw-r--r--source/Plugins/Process/Windows/Common/ExceptionRecord.h80
-rw-r--r--source/Plugins/Process/Windows/Common/ForwardDecl.h42
-rw-r--r--source/Plugins/Process/Windows/Common/IDebugDelegate.h46
-rw-r--r--source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp73
-rw-r--r--source/Plugins/Process/Windows/Common/LocalDebugDelegate.h67
-rw-r--r--source/Plugins/Process/Windows/Common/NtStructures.h31
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindows.cpp1119
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindows.h121
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp41
-rw-r--r--source/Plugins/Process/Windows/Common/ProcessWindowsLog.h36
-rw-r--r--source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp136
-rw-r--r--source/Plugins/Process/Windows/Common/RegisterContextWindows.h67
-rw-r--r--source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp147
-rw-r--r--source/Plugins/Process/Windows/Common/TargetThreadWindows.h50
-rw-r--r--source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp341
-rw-r--r--source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h48
-rw-r--r--source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp287
-rw-r--r--source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h52
-rw-r--r--source/Plugins/Process/elf-core/CMakeLists.txt22
-rw-r--r--source/Plugins/Process/gdb-remote/CMakeLists.txt42
-rw-r--r--source/Plugins/Process/mach-core/CMakeLists.txt17
-rw-r--r--source/Plugins/Process/mach-core/ProcessMachCore.cpp635
-rw-r--r--source/Plugins/Process/mach-core/ProcessMachCore.h149
-rw-r--r--source/Plugins/Process/mach-core/ThreadMachCore.cpp103
-rw-r--r--source/Plugins/Process/mach-core/ThreadMachCore.h70
-rw-r--r--source/Plugins/Process/minidump/CMakeLists.txt19
75 files changed, 0 insertions, 19079 deletions
diff --git a/source/Plugins/Process/CMakeLists.txt b/source/Plugins/Process/CMakeLists.txt
deleted file mode 100644
index fdeb211fe7a20..0000000000000
--- a/source/Plugins/Process/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-if (CMAKE_SYSTEM_NAME MATCHES "Linux|Android")
- add_subdirectory(Linux)
- add_subdirectory(POSIX)
-elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
- add_subdirectory(FreeBSD)
- add_subdirectory(POSIX)
-elseif (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
- add_subdirectory(NetBSD)
- add_subdirectory(POSIX)
-elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
- add_subdirectory(Windows/Common)
-elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
- add_subdirectory(MacOSX-Kernel)
-endif()
-add_subdirectory(gdb-remote)
-add_subdirectory(Utility)
-add_subdirectory(elf-core)
-add_subdirectory(mach-core)
-add_subdirectory(minidump)
diff --git a/source/Plugins/Process/FreeBSD/CMakeLists.txt b/source/Plugins/Process/FreeBSD/CMakeLists.txt
deleted file mode 100644
index c8301f350e076..0000000000000
--- a/source/Plugins/Process/FreeBSD/CMakeLists.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-add_lldb_library(lldbPluginProcessFreeBSD PLUGIN
- ProcessFreeBSD.cpp
- FreeBSDThread.cpp
- ProcessMonitor.cpp
-
- POSIXStopInfo.cpp
- RegisterContextPOSIXProcessMonitor_arm.cpp
- RegisterContextPOSIXProcessMonitor_arm64.cpp
- RegisterContextPOSIXProcessMonitor_powerpc.cpp
- RegisterContextPOSIXProcessMonitor_x86.cpp
- RegisterContextPOSIXProcessMonitor_mips64.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbHost
- lldbSymbol
- lldbTarget
- lldbUtility
- lldbPluginProcessUtility
- lldbPluginProcessPOSIX
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Process/Linux/CMakeLists.txt b/source/Plugins/Process/Linux/CMakeLists.txt
deleted file mode 100644
index b4b4c401a271f..0000000000000
--- a/source/Plugins/Process/Linux/CMakeLists.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-add_lldb_library(lldbPluginProcessLinux PLUGIN
- NativeProcessLinux.cpp
- NativeRegisterContextLinux.cpp
- NativeRegisterContextLinux_arm.cpp
- NativeRegisterContextLinux_arm64.cpp
- NativeRegisterContextLinux_mips64.cpp
- NativeRegisterContextLinux_ppc64le.cpp
- NativeRegisterContextLinux_s390x.cpp
- NativeRegisterContextLinux_x86_64.cpp
- NativeThreadLinux.cpp
- ProcessorTrace.cpp
- SingleStepCheck.cpp
-
- LINK_LIBS
- lldbCore
- lldbHost
- lldbSymbol
- lldbTarget
- lldbUtility
- lldbPluginProcessPOSIX
- lldbPluginProcessUtility
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/source/Plugins/Process/Linux/NativeProcessLinux.cpp
deleted file mode 100644
index 8c6c95380e814..0000000000000
--- a/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ /dev/null
@@ -1,2097 +0,0 @@
-//===-- NativeProcessLinux.cpp -------------------------------- -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "NativeProcessLinux.h"
-
-#include <errno.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <fstream>
-#include <mutex>
-#include <sstream>
-#include <string>
-#include <unordered_map>
-
-#include "lldb/Core/EmulateInstruction.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/HostProcess.h"
-#include "lldb/Host/PseudoTerminal.h"
-#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Host/common/NativeRegisterContext.h"
-#include "lldb/Host/linux/Ptrace.h"
-#include "lldb/Host/linux/Uio.h"
-#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/ProcessLaunchInfo.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/LLDBAssert.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/State.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StringExtractor.h"
-#include "llvm/Support/Errno.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Threading.h"
-
-#include "NativeThreadLinux.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/LinuxProcMaps.h"
-#include "Procfs.h"
-
-#include <linux/unistd.h>
-#include <sys/socket.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <sys/user.h>
-#include <sys/wait.h>
-
-// Support hardware breakpoints in case it has not been defined
-#ifndef TRAP_HWBKPT
-#define TRAP_HWBKPT 4
-#endif
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::process_linux;
-using namespace llvm;
-
-// Private bits we only need internally.
-
-static bool ProcessVmReadvSupported() {
- static bool is_supported;
- static llvm::once_flag flag;
-
- llvm::call_once(flag, [] {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
- uint32_t source = 0x47424742;
- uint32_t dest = 0;
-
- struct iovec local, remote;
- remote.iov_base = &source;
- local.iov_base = &dest;
- remote.iov_len = local.iov_len = sizeof source;
-
- // We shall try if cross-process-memory reads work by attempting to read a
- // value from our own process.
- ssize_t res = process_vm_readv(getpid(), &local, 1, &remote, 1, 0);
- is_supported = (res == sizeof(source) && source == dest);
- if (is_supported)
- LLDB_LOG(log,
- "Detected kernel support for process_vm_readv syscall. "
- "Fast memory reads enabled.");
- else
- LLDB_LOG(log,
- "syscall process_vm_readv failed (error: {0}). Fast memory "
- "reads disabled.",
- llvm::sys::StrError());
- });
-
- return is_supported;
-}
-
-namespace {
-void MaybeLogLaunchInfo(const ProcessLaunchInfo &info) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- if (!log)
- return;
-
- if (const FileAction *action = info.GetFileActionForFD(STDIN_FILENO))
- LLDB_LOG(log, "setting STDIN to '{0}'", action->GetFileSpec());
- else
- LLDB_LOG(log, "leaving STDIN as is");
-
- if (const FileAction *action = info.GetFileActionForFD(STDOUT_FILENO))
- LLDB_LOG(log, "setting STDOUT to '{0}'", action->GetFileSpec());
- else
- LLDB_LOG(log, "leaving STDOUT as is");
-
- if (const FileAction *action = info.GetFileActionForFD(STDERR_FILENO))
- LLDB_LOG(log, "setting STDERR to '{0}'", action->GetFileSpec());
- else
- LLDB_LOG(log, "leaving STDERR as is");
-
- int i = 0;
- for (const char **args = info.GetArguments().GetConstArgumentVector(); *args;
- ++args, ++i)
- LLDB_LOG(log, "arg {0}: '{1}'", i, *args);
-}
-
-void DisplayBytes(StreamString &s, void *bytes, uint32_t count) {
- uint8_t *ptr = (uint8_t *)bytes;
- const uint32_t loop_count = std::min<uint32_t>(DEBUG_PTRACE_MAXBYTES, count);
- for (uint32_t i = 0; i < loop_count; i++) {
- s.Printf("[%x]", *ptr);
- ptr++;
- }
-}
-
-void PtraceDisplayBytes(int &req, void *data, size_t data_size) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
- if (!log)
- return;
- StreamString buf;
-
- switch (req) {
- case PTRACE_POKETEXT: {
- DisplayBytes(buf, &data, 8);
- LLDB_LOGV(log, "PTRACE_POKETEXT {0}", buf.GetData());
- break;
- }
- case PTRACE_POKEDATA: {
- DisplayBytes(buf, &data, 8);
- LLDB_LOGV(log, "PTRACE_POKEDATA {0}", buf.GetData());
- break;
- }
- case PTRACE_POKEUSER: {
- DisplayBytes(buf, &data, 8);
- LLDB_LOGV(log, "PTRACE_POKEUSER {0}", buf.GetData());
- break;
- }
- case PTRACE_SETREGS: {
- DisplayBytes(buf, data, data_size);
- LLDB_LOGV(log, "PTRACE_SETREGS {0}", buf.GetData());
- break;
- }
- case PTRACE_SETFPREGS: {
- DisplayBytes(buf, data, data_size);
- LLDB_LOGV(log, "PTRACE_SETFPREGS {0}", buf.GetData());
- break;
- }
- case PTRACE_SETSIGINFO: {
- DisplayBytes(buf, data, sizeof(siginfo_t));
- LLDB_LOGV(log, "PTRACE_SETSIGINFO {0}", buf.GetData());
- break;
- }
- case PTRACE_SETREGSET: {
- // Extract iov_base from data, which is a pointer to the struct iovec
- DisplayBytes(buf, *(void **)data, data_size);
- LLDB_LOGV(log, "PTRACE_SETREGSET {0}", buf.GetData());
- break;
- }
- default: {}
- }
-}
-
-static constexpr unsigned k_ptrace_word_size = sizeof(void *);
-static_assert(sizeof(long) >= k_ptrace_word_size,
- "Size of long must be larger than ptrace word size");
-} // end of anonymous namespace
-
-// Simple helper function to ensure flags are enabled on the given file
-// descriptor.
-static Status EnsureFDFlags(int fd, int flags) {
- Status 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
-// -----------------------------------------------------------------------------
-
-llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
-NativeProcessLinux::Factory::Launch(ProcessLaunchInfo &launch_info,
- NativeDelegate &native_delegate,
- MainLoop &mainloop) const {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
- MaybeLogLaunchInfo(launch_info);
-
- Status status;
- ::pid_t pid = ProcessLauncherPosixFork()
- .LaunchProcess(launch_info, status)
- .GetProcessId();
- LLDB_LOG(log, "pid = {0:x}", pid);
- if (status.Fail()) {
- LLDB_LOG(log, "failed to launch process: {0}", status);
- return status.ToError();
- }
-
- // Wait for the child process to trap on its call to execve.
- int wstatus;
- ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
- assert(wpid == pid);
- (void)wpid;
- if (!WIFSTOPPED(wstatus)) {
- LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}",
- WaitStatus::Decode(wstatus));
- return llvm::make_error<StringError>("Could not sync with inferior process",
- llvm::inconvertibleErrorCode());
- }
- LLDB_LOG(log, "inferior started, now in stopped state");
-
- ProcessInstanceInfo Info;
- if (!Host::GetProcessInfo(pid, Info)) {
- return llvm::make_error<StringError>("Cannot get process architecture",
- llvm::inconvertibleErrorCode());
- }
-
- // Set the architecture to the exe architecture.
- LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,
- Info.GetArchitecture().GetArchitectureName());
-
- status = SetDefaultPtraceOpts(pid);
- if (status.Fail()) {
- LLDB_LOG(log, "failed to set default ptrace options: {0}", status);
- return status.ToError();
- }
-
- return std::unique_ptr<NativeProcessLinux>(new NativeProcessLinux(
- pid, launch_info.GetPTY().ReleaseMasterFileDescriptor(), native_delegate,
- Info.GetArchitecture(), mainloop, {pid}));
-}
-
-llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
-NativeProcessLinux::Factory::Attach(
- lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
- MainLoop &mainloop) const {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOG(log, "pid = {0:x}", pid);
-
- // Retrieve the architecture for the running process.
- ProcessInstanceInfo Info;
- if (!Host::GetProcessInfo(pid, Info)) {
- return llvm::make_error<StringError>("Cannot get process architecture",
- llvm::inconvertibleErrorCode());
- }
-
- auto tids_or = NativeProcessLinux::Attach(pid);
- if (!tids_or)
- return tids_or.takeError();
-
- return std::unique_ptr<NativeProcessLinux>(new NativeProcessLinux(
- pid, -1, native_delegate, Info.GetArchitecture(), mainloop, *tids_or));
-}
-
-// -----------------------------------------------------------------------------
-// Public Instance Methods
-// -----------------------------------------------------------------------------
-
-NativeProcessLinux::NativeProcessLinux(::pid_t pid, int terminal_fd,
- NativeDelegate &delegate,
- const ArchSpec &arch, MainLoop &mainloop,
- llvm::ArrayRef<::pid_t> tids)
- : NativeProcessProtocol(pid, terminal_fd, delegate), m_arch(arch) {
- if (m_terminal_fd != -1) {
- Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
- assert(status.Success());
- }
-
- Status status;
- m_sigchld_handle = mainloop.RegisterSignal(
- SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status);
- assert(m_sigchld_handle && status.Success());
-
- for (const auto &tid : tids) {
- NativeThreadLinux &thread = AddThread(tid);
- thread.SetStoppedBySignal(SIGSTOP);
- ThreadWasCreated(thread);
- }
-
- // Let our process instance know the thread has stopped.
- SetCurrentThreadID(tids[0]);
- SetState(StateType::eStateStopped, false);
-
- // Proccess any signals we received before installing our handler
- SigchldHandler();
-}
-
-llvm::Expected<std::vector<::pid_t>> NativeProcessLinux::Attach(::pid_t pid) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
- Status status;
- // Use a map to keep track of the threads which we have attached/need to
- // attach.
- Host::TidMap tids_to_attach;
- while (Host::FindProcessThreads(pid, tids_to_attach)) {
- for (Host::TidMap::iterator it = tids_to_attach.begin();
- it != tids_to_attach.end();) {
- if (it->second == false) {
- lldb::tid_t tid = it->first;
-
- // Attach to the requested process.
- // An attach will cause the thread to stop with a SIGSTOP.
- if ((status = PtraceWrapper(PTRACE_ATTACH, tid)).Fail()) {
- // No such thread. The thread may have exited. More error handling
- // may be needed.
- if (status.GetError() == ESRCH) {
- it = tids_to_attach.erase(it);
- continue;
- }
- return status.ToError();
- }
-
- int wpid =
- llvm::sys::RetryAfterSignal(-1, ::waitpid, tid, nullptr, __WALL);
- // Need to use __WALL otherwise we receive an error with errno=ECHLD At
- // this point we should have a thread stopped if waitpid succeeds.
- if (wpid < 0) {
- // No such thread. The thread may have exited. More error handling
- // may be needed.
- if (errno == ESRCH) {
- it = tids_to_attach.erase(it);
- continue;
- }
- return llvm::errorCodeToError(
- std::error_code(errno, std::generic_category()));
- }
-
- if ((status = SetDefaultPtraceOpts(tid)).Fail())
- return status.ToError();
-
- LLDB_LOG(log, "adding tid = {0}", tid);
- it->second = true;
- }
-
- // move the loop forward
- ++it;
- }
- }
-
- size_t tid_count = tids_to_attach.size();
- if (tid_count == 0)
- return llvm::make_error<StringError>("No such process",
- llvm::inconvertibleErrorCode());
-
- std::vector<::pid_t> tids;
- tids.reserve(tid_count);
- for (const auto &p : tids_to_attach)
- tids.push_back(p.first);
- return std::move(tids);
-}
-
-Status NativeProcessLinux::SetDefaultPtraceOpts(lldb::pid_t pid) {
- long ptrace_opts = 0;
-
- // Have the child raise an event on exit. This is used to keep the child in
- // limbo until it is destroyed.
- ptrace_opts |= PTRACE_O_TRACEEXIT;
-
- // Have the tracer trace threads which spawn in the inferior process.
- // TODO: if we want to support tracing the inferiors' child, add the
- // appropriate ptrace flags here (PTRACE_O_TRACEFORK, PTRACE_O_TRACEVFORK)
- ptrace_opts |= PTRACE_O_TRACECLONE;
-
- // Have the tracer notify us before execve returns (needed to disable legacy
- // SIGTRAP generation)
- ptrace_opts |= PTRACE_O_TRACEEXEC;
-
- return PtraceWrapper(PTRACE_SETOPTIONS, pid, nullptr, (void *)ptrace_opts);
-}
-
-// Handles all waitpid events from the inferior process.
-void NativeProcessLinux::MonitorCallback(lldb::pid_t pid, bool exited,
- WaitStatus status) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- // Certain activities differ based on whether the pid is the tid of the main
- // thread.
- const bool is_main_thread = (pid == GetID());
-
- // Handle when the thread exits.
- if (exited) {
- LLDB_LOG(log,
- "got exit signal({0}) , tid = {1} ({2} main thread), process "
- "state = {3}",
- signal, pid, is_main_thread ? "is" : "is not", GetState());
-
- // This is a thread that exited. Ensure we're not tracking it anymore.
- StopTrackingThread(pid);
-
- if (is_main_thread) {
- // The main thread exited. We're done monitoring. Report to delegate.
- SetExitStatus(status, true);
-
- // Notify delegate that our process has exited.
- SetState(StateType::eStateExited, true);
- }
- return;
- }
-
- siginfo_t info;
- const auto info_err = GetSignalInfo(pid, &info);
- auto thread_sp = GetThreadByID(pid);
-
- if (!thread_sp) {
- // Normally, the only situation when we cannot find the thread is if we
- // have just received a new thread notification. This is indicated by
- // GetSignalInfo() returning si_code == SI_USER and si_pid == 0
- LLDB_LOG(log, "received notification about an unknown tid {0}.", pid);
-
- if (info_err.Fail()) {
- LLDB_LOG(log,
- "(tid {0}) GetSignalInfo failed ({1}). "
- "Ingoring this notification.",
- pid, info_err);
- return;
- }
-
- LLDB_LOG(log, "tid {0}, si_code: {1}, si_pid: {2}", pid, info.si_code,
- info.si_pid);
-
- NativeThreadLinux &thread = AddThread(pid);
-
- // Resume the newly created thread.
- ResumeThread(thread, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
- ThreadWasCreated(thread);
- return;
- }
-
- // Get details on the signal raised.
- if (info_err.Success()) {
- // We have retrieved the signal info. Dispatch appropriately.
- if (info.si_signo == SIGTRAP)
- MonitorSIGTRAP(info, *thread_sp);
- else
- MonitorSignal(info, *thread_sp, exited);
- } else {
- if (info_err.GetError() == EINVAL) {
- // This is a group stop reception for this tid. We can reach here if we
- // reinject SIGSTOP, SIGSTP, SIGTTIN or SIGTTOU into the tracee,
- // triggering the group-stop mechanism. Normally receiving these would
- // stop the process, pending a SIGCONT. Simulating this state in a
- // debugger is hard and is generally not needed (one use case is
- // debugging background task being managed by a shell). For general use,
- // it is sufficient to stop the process in a signal-delivery stop which
- // happens before the group stop. This done by MonitorSignal and works
- // correctly for all signals.
- LLDB_LOG(log,
- "received a group stop for pid {0} tid {1}. Transparent "
- "handling of group stops not supported, resuming the "
- "thread.",
- GetID(), pid);
- ResumeThread(*thread_sp, thread_sp->GetState(),
- LLDB_INVALID_SIGNAL_NUMBER);
- } else {
- // ptrace(GETSIGINFO) failed (but not due to group-stop).
-
- // A return value of ESRCH means the thread/process is no longer on the
- // system, so it was killed somehow outside of our control. Either way,
- // we can't do anything with it anymore.
-
- // Stop tracking the metadata for the thread since it's entirely off the
- // system now.
- const bool thread_found = StopTrackingThread(pid);
-
- LLDB_LOG(log,
- "GetSignalInfo failed: {0}, tid = {1}, signal = {2}, "
- "status = {3}, main_thread = {4}, thread_found: {5}",
- info_err, pid, signal, status, is_main_thread, thread_found);
-
- if (is_main_thread) {
- // Notify the delegate - our process is not available but appears to
- // have been killed outside our control. Is eStateExited the right
- // exit state in this case?
- SetExitStatus(status, true);
- SetState(StateType::eStateExited, true);
- } else {
- // This thread was pulled out from underneath us. Anything to do here?
- // Do we want to do an all stop?
- LLDB_LOG(log,
- "pid {0} tid {1} non-main thread exit occurred, didn't "
- "tell delegate anything since thread disappeared out "
- "from underneath us",
- GetID(), pid);
- }
- }
- }
-}
-
-void NativeProcessLinux::WaitForNewThread(::pid_t tid) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
- if (GetThreadByID(tid)) {
- // We are already tracking the thread - we got the event on the new thread
- // (see MonitorSignal) before this one. We are done.
- return;
- }
-
- // The thread is not tracked yet, let's wait for it to appear.
- int status = -1;
- LLDB_LOG(log,
- "received thread creation event for tid {0}. tid not tracked "
- "yet, waiting for thread to appear...",
- tid);
- ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, ::waitpid, tid, &status, __WALL);
- // Since we are waiting on a specific tid, this must be the creation event.
- // But let's do some checks just in case.
- if (wait_pid != tid) {
- LLDB_LOG(log,
- "waiting for tid {0} failed. Assuming the thread has "
- "disappeared in the meantime",
- tid);
- // The only way I know of this could happen is if the whole process was
- // SIGKILLed in the mean time. In any case, we can't do anything about that
- // now.
- return;
- }
- if (WIFEXITED(status)) {
- LLDB_LOG(log,
- "waiting for tid {0} returned an 'exited' event. Not "
- "tracking the thread.",
- tid);
- // Also a very improbable event.
- return;
- }
-
- LLDB_LOG(log, "pid = {0}: tracking new thread tid {1}", GetID(), tid);
- NativeThreadLinux &new_thread = AddThread(tid);
-
- ResumeThread(new_thread, eStateRunning, LLDB_INVALID_SIGNAL_NUMBER);
- ThreadWasCreated(new_thread);
-}
-
-void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
- NativeThreadLinux &thread) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- const bool is_main_thread = (thread.GetID() == GetID());
-
- assert(info.si_signo == SIGTRAP && "Unexpected child signal!");
-
- switch (info.si_code) {
- // TODO: these two cases are required if we want to support tracing of the
- // inferiors' children. We'd need this to debug a monitor. case (SIGTRAP |
- // (PTRACE_EVENT_FORK << 8)): case (SIGTRAP | (PTRACE_EVENT_VFORK << 8)):
-
- case (SIGTRAP | (PTRACE_EVENT_CLONE << 8)): {
- // This is the notification on the parent thread which informs us of new
- // thread creation. We don't want to do anything with the parent thread so
- // we just resume it. In case we want to implement "break on thread
- // creation" functionality, we would need to stop here.
-
- unsigned long event_message = 0;
- if (GetEventMessage(thread.GetID(), &event_message).Fail()) {
- LLDB_LOG(log,
- "pid {0} received thread creation event but "
- "GetEventMessage failed so we don't know the new tid",
- thread.GetID());
- } else
- WaitForNewThread(event_message);
-
- ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
- break;
- }
-
- case (SIGTRAP | (PTRACE_EVENT_EXEC << 8)): {
- LLDB_LOG(log, "received exec event, code = {0}", info.si_code ^ SIGTRAP);
-
- // Exec clears any pending notifications.
- m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
-
- // Remove all but the main thread here. Linux fork creates a new process
- // which only copies the main thread.
- LLDB_LOG(log, "exec received, stop tracking all but main thread");
-
- for (auto i = m_threads.begin(); i != m_threads.end();) {
- if ((*i)->GetID() == GetID())
- i = m_threads.erase(i);
- else
- ++i;
- }
- assert(m_threads.size() == 1);
- auto *main_thread = static_cast<NativeThreadLinux *>(m_threads[0].get());
-
- SetCurrentThreadID(main_thread->GetID());
- main_thread->SetStoppedByExec();
-
- // Tell coordinator about about the "new" (since exec) stopped main thread.
- ThreadWasCreated(*main_thread);
-
- // Let our delegate know we have just exec'd.
- NotifyDidExec();
-
- // Let the process know we're stopped.
- StopRunningThreads(main_thread->GetID());
-
- break;
- }
-
- case (SIGTRAP | (PTRACE_EVENT_EXIT << 8)): {
- // The inferior process or one of its threads is about to exit. We don't
- // want to do anything with the thread so we just resume it. In case we
- // want to implement "break on thread exit" functionality, we would need to
- // stop here.
-
- unsigned long data = 0;
- if (GetEventMessage(thread.GetID(), &data).Fail())
- data = -1;
-
- LLDB_LOG(log,
- "received PTRACE_EVENT_EXIT, data = {0:x}, WIFEXITED={1}, "
- "WIFSIGNALED={2}, pid = {3}, main_thread = {4}",
- data, WIFEXITED(data), WIFSIGNALED(data), thread.GetID(),
- is_main_thread);
-
-
- StateType state = thread.GetState();
- if (!StateIsRunningState(state)) {
- // Due to a kernel bug, we may sometimes get this stop after the inferior
- // gets a SIGKILL. This confuses our state tracking logic in
- // ResumeThread(), since normally, we should not be receiving any ptrace
- // events while the inferior is stopped. This makes sure that the
- // inferior is resumed and exits normally.
- state = eStateRunning;
- }
- ResumeThread(thread, state, LLDB_INVALID_SIGNAL_NUMBER);
-
- break;
- }
-
- case 0:
- case TRAP_TRACE: // We receive this on single stepping.
- case TRAP_HWBKPT: // We receive this on watchpoint hit
- {
- // If a watchpoint was hit, report it
- uint32_t wp_index;
- Status error = thread.GetRegisterContext().GetWatchpointHitIndex(
- wp_index, (uintptr_t)info.si_addr);
- if (error.Fail())
- LLDB_LOG(log,
- "received error while checking for watchpoint hits, pid = "
- "{0}, error = {1}",
- thread.GetID(), error);
- if (wp_index != LLDB_INVALID_INDEX32) {
- MonitorWatchpoint(thread, wp_index);
- break;
- }
-
- // If a breakpoint was hit, report it
- uint32_t bp_index;
- error = thread.GetRegisterContext().GetHardwareBreakHitIndex(
- bp_index, (uintptr_t)info.si_addr);
- if (error.Fail())
- LLDB_LOG(log, "received error while checking for hardware "
- "breakpoint hits, pid = {0}, error = {1}",
- thread.GetID(), error);
- if (bp_index != LLDB_INVALID_INDEX32) {
- MonitorBreakpoint(thread);
- break;
- }
-
- // Otherwise, report step over
- MonitorTrace(thread);
- break;
- }
-
- case SI_KERNEL:
-#if defined __mips__
- // For mips there is no special signal for watchpoint So we check for
- // watchpoint in kernel trap
- {
- // If a watchpoint was hit, report it
- uint32_t wp_index;
- Status error = thread.GetRegisterContext().GetWatchpointHitIndex(
- wp_index, LLDB_INVALID_ADDRESS);
- if (error.Fail())
- LLDB_LOG(log,
- "received error while checking for watchpoint hits, pid = "
- "{0}, error = {1}",
- thread.GetID(), error);
- if (wp_index != LLDB_INVALID_INDEX32) {
- MonitorWatchpoint(thread, wp_index);
- break;
- }
- }
-// NO BREAK
-#endif
- case TRAP_BRKPT:
- MonitorBreakpoint(thread);
- break;
-
- case SIGTRAP:
- case (SIGTRAP | 0x80):
- LLDB_LOG(
- log,
- "received unknown SIGTRAP stop event ({0}, pid {1} tid {2}, resuming",
- info.si_code, GetID(), thread.GetID());
-
- // Ignore these signals until we know more about them.
- ResumeThread(thread, thread.GetState(), LLDB_INVALID_SIGNAL_NUMBER);
- break;
-
- default:
- LLDB_LOG(log, "received unknown SIGTRAP stop event ({0}, pid {1} tid {2}",
- info.si_code, GetID(), thread.GetID());
- MonitorSignal(info, thread, false);
- break;
- }
-}
-
-void NativeProcessLinux::MonitorTrace(NativeThreadLinux &thread) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOG(log, "received trace event, pid = {0}", thread.GetID());
-
- // This thread is currently stopped.
- thread.SetStoppedByTrace();
-
- StopRunningThreads(thread.GetID());
-}
-
-void NativeProcessLinux::MonitorBreakpoint(NativeThreadLinux &thread) {
- Log *log(
- GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_BREAKPOINTS));
- LLDB_LOG(log, "received breakpoint event, pid = {0}", thread.GetID());
-
- // Mark the thread as stopped at breakpoint.
- thread.SetStoppedByBreakpoint();
- FixupBreakpointPCAsNeeded(thread);
-
- if (m_threads_stepping_with_breakpoint.find(thread.GetID()) !=
- m_threads_stepping_with_breakpoint.end())
- thread.SetStoppedByTrace();
-
- StopRunningThreads(thread.GetID());
-}
-
-void NativeProcessLinux::MonitorWatchpoint(NativeThreadLinux &thread,
- uint32_t wp_index) {
- Log *log(
- GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_WATCHPOINTS));
- LLDB_LOG(log, "received watchpoint event, pid = {0}, wp_index = {1}",
- thread.GetID(), wp_index);
-
- // Mark the thread as stopped at watchpoint. The address is at
- // (lldb::addr_t)info->si_addr if we need it.
- thread.SetStoppedByWatchpoint(wp_index);
-
- // We need to tell all other running threads before we notify the delegate
- // about this stop.
- StopRunningThreads(thread.GetID());
-}
-
-void NativeProcessLinux::MonitorSignal(const siginfo_t &info,
- NativeThreadLinux &thread, bool exited) {
- const int signo = info.si_signo;
- const bool is_from_llgs = info.si_pid == getpid();
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
- // POSIX says that process behaviour is undefined after it ignores a SIGFPE,
- // SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a kill(2)
- // or raise(3). Similarly for tgkill(2) on Linux.
- //
- // IOW, user generated signals never generate what we consider to be a
- // "crash".
- //
- // Similarly, ACK signals generated by this monitor.
-
- // Handle the signal.
- LLDB_LOG(log,
- "received signal {0} ({1}) with code {2}, (siginfo pid = {3}, "
- "waitpid pid = {4})",
- Host::GetSignalAsCString(signo), signo, info.si_code,
- thread.GetID());
-
- // Check for thread stop notification.
- if (is_from_llgs && (info.si_code == SI_TKILL) && (signo == SIGSTOP)) {
- // This is a tgkill()-based stop.
- LLDB_LOG(log, "pid {0} tid {1}, thread stopped", GetID(), thread.GetID());
-
- // Check that we're not already marked with a stop reason. Note this thread
- // really shouldn't already be marked as stopped - if we were, that would
- // imply that the kernel signaled us with the thread stopping which we
- // handled and marked as stopped, and that, without an intervening resume,
- // we received another stop. It is more likely that we are missing the
- // marking of a run state somewhere if we find that the thread was marked
- // as stopped.
- const StateType thread_state = thread.GetState();
- if (!StateIsStoppedState(thread_state, false)) {
- // An inferior thread has stopped because of a SIGSTOP we have sent it.
- // Generally, these are not important stops and we don't want to report
- // them as they are just used to stop other threads when one thread (the
- // one with the *real* stop reason) hits a breakpoint (watchpoint,
- // etc...). However, in the case of an asynchronous Interrupt(), this
- // *is* the real stop reason, so we leave the signal intact if this is
- // the thread that was chosen as the triggering thread.
- if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID) {
- if (m_pending_notification_tid == thread.GetID())
- thread.SetStoppedBySignal(SIGSTOP, &info);
- else
- thread.SetStoppedWithNoReason();
-
- SetCurrentThreadID(thread.GetID());
- SignalIfAllThreadsStopped();
- } else {
- // We can end up here if stop was initiated by LLGS but by this time a
- // thread stop has occurred - maybe initiated by another event.
- Status error = ResumeThread(thread, thread.GetState(), 0);
- if (error.Fail())
- LLDB_LOG(log, "failed to resume thread {0}: {1}", thread.GetID(),
- error);
- }
- } else {
- LLDB_LOG(log,
- "pid {0} tid {1}, thread was already marked as a stopped "
- "state (state={2}), leaving stop signal as is",
- GetID(), thread.GetID(), thread_state);
- SignalIfAllThreadsStopped();
- }
-
- // Done handling.
- return;
- }
-
- // Check if debugger should stop at this signal or just ignore it and resume
- // the inferior.
- if (m_signals_to_ignore.find(signo) != m_signals_to_ignore.end()) {
- ResumeThread(thread, thread.GetState(), signo);
- return;
- }
-
- // This thread is stopped.
- LLDB_LOG(log, "received signal {0}", Host::GetSignalAsCString(signo));
- thread.SetStoppedBySignal(signo, &info);
-
- // Send a stop to the debugger after we get all other threads to stop.
- StopRunningThreads(thread.GetID());
-}
-
-namespace {
-
-struct EmulatorBaton {
- NativeProcessLinux &m_process;
- NativeRegisterContext &m_reg_context;
-
- // eRegisterKindDWARF -> RegsiterValue
- std::unordered_map<uint32_t, RegisterValue> m_register_values;
-
- EmulatorBaton(NativeProcessLinux &process, NativeRegisterContext &reg_context)
- : m_process(process), m_reg_context(reg_context) {}
-};
-
-} // anonymous namespace
-
-static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr, void *dst, size_t length) {
- EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
-
- size_t bytes_read;
- emulator_baton->m_process.ReadMemory(addr, dst, length, bytes_read);
- return bytes_read;
-}
-
-static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton,
- const RegisterInfo *reg_info,
- RegisterValue &reg_value) {
- EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
-
- auto it = emulator_baton->m_register_values.find(
- reg_info->kinds[eRegisterKindDWARF]);
- if (it != emulator_baton->m_register_values.end()) {
- reg_value = it->second;
- return true;
- }
-
- // The emulator only fill in the dwarf regsiter numbers (and in some case the
- // generic register numbers). Get the full register info from the register
- // context based on the dwarf register numbers.
- const RegisterInfo *full_reg_info =
- emulator_baton->m_reg_context.GetRegisterInfo(
- eRegisterKindDWARF, reg_info->kinds[eRegisterKindDWARF]);
-
- Status error =
- emulator_baton->m_reg_context.ReadRegister(full_reg_info, reg_value);
- if (error.Success())
- return true;
-
- return false;
-}
-
-static bool WriteRegisterCallback(EmulateInstruction *instruction, void *baton,
- const EmulateInstruction::Context &context,
- const RegisterInfo *reg_info,
- const RegisterValue &reg_value) {
- EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
- emulator_baton->m_register_values[reg_info->kinds[eRegisterKindDWARF]] =
- reg_value;
- return true;
-}
-
-static size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr, const void *dst,
- size_t length) {
- return length;
-}
-
-static lldb::addr_t ReadFlags(NativeRegisterContext &regsiter_context) {
- const RegisterInfo *flags_info = regsiter_context.GetRegisterInfo(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
- return regsiter_context.ReadRegisterAsUnsigned(flags_info,
- LLDB_INVALID_ADDRESS);
-}
-
-Status
-NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread) {
- Status error;
- NativeRegisterContext& register_context = thread.GetRegisterContext();
-
- std::unique_ptr<EmulateInstruction> emulator_ap(
- EmulateInstruction::FindPlugin(m_arch, eInstructionTypePCModifying,
- nullptr));
-
- if (emulator_ap == nullptr)
- return Status("Instruction emulator not found!");
-
- EmulatorBaton baton(*this, register_context);
- emulator_ap->SetBaton(&baton);
- emulator_ap->SetReadMemCallback(&ReadMemoryCallback);
- emulator_ap->SetReadRegCallback(&ReadRegisterCallback);
- emulator_ap->SetWriteMemCallback(&WriteMemoryCallback);
- emulator_ap->SetWriteRegCallback(&WriteRegisterCallback);
-
- if (!emulator_ap->ReadInstruction())
- return Status("Read instruction failed!");
-
- bool emulation_result =
- emulator_ap->EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC);
-
- const RegisterInfo *reg_info_pc = register_context.GetRegisterInfo(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
- const RegisterInfo *reg_info_flags = register_context.GetRegisterInfo(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
-
- auto pc_it =
- baton.m_register_values.find(reg_info_pc->kinds[eRegisterKindDWARF]);
- auto flags_it =
- baton.m_register_values.find(reg_info_flags->kinds[eRegisterKindDWARF]);
-
- lldb::addr_t next_pc;
- lldb::addr_t next_flags;
- if (emulation_result) {
- assert(pc_it != baton.m_register_values.end() &&
- "Emulation was successfull but PC wasn't updated");
- next_pc = pc_it->second.GetAsUInt64();
-
- if (flags_it != baton.m_register_values.end())
- next_flags = flags_it->second.GetAsUInt64();
- else
- next_flags = ReadFlags(register_context);
- } else if (pc_it == baton.m_register_values.end()) {
- // Emulate instruction failed and it haven't changed PC. Advance PC with
- // the size of the current opcode because the emulation of all
- // PC modifying instruction should be successful. The failure most
- // likely caused by a not supported instruction which don't modify PC.
- next_pc = register_context.GetPC() + emulator_ap->GetOpcode().GetByteSize();
- next_flags = ReadFlags(register_context);
- } else {
- // The instruction emulation failed after it modified the PC. It is an
- // unknown error where we can't continue because the next instruction is
- // modifying the PC but we don't know how.
- return Status("Instruction emulation failed unexpectedly.");
- }
-
- if (m_arch.GetMachine() == llvm::Triple::arm) {
- if (next_flags & 0x20) {
- // Thumb mode
- error = SetSoftwareBreakpoint(next_pc, 2);
- } else {
- // Arm mode
- error = SetSoftwareBreakpoint(next_pc, 4);
- }
- } else if (m_arch.GetMachine() == llvm::Triple::mips64 ||
- m_arch.GetMachine() == llvm::Triple::mips64el ||
- m_arch.GetMachine() == llvm::Triple::mips ||
- m_arch.GetMachine() == llvm::Triple::mipsel ||
- m_arch.GetMachine() == llvm::Triple::ppc64le)
- error = SetSoftwareBreakpoint(next_pc, 4);
- else {
- // No size hint is given for the next breakpoint
- error = SetSoftwareBreakpoint(next_pc, 0);
- }
-
- // If setting the breakpoint fails because next_pc is out of the address
- // space, ignore it and let the debugee segfault.
- if (error.GetError() == EIO || error.GetError() == EFAULT) {
- return Status();
- } else if (error.Fail())
- return error;
-
- m_threads_stepping_with_breakpoint.insert({thread.GetID(), next_pc});
-
- return Status();
-}
-
-bool NativeProcessLinux::SupportHardwareSingleStepping() const {
- if (m_arch.GetMachine() == llvm::Triple::arm ||
- m_arch.GetMachine() == llvm::Triple::mips64 ||
- m_arch.GetMachine() == llvm::Triple::mips64el ||
- m_arch.GetMachine() == llvm::Triple::mips ||
- m_arch.GetMachine() == llvm::Triple::mipsel)
- return false;
- return true;
-}
-
-Status NativeProcessLinux::Resume(const ResumeActionList &resume_actions) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOG(log, "pid {0}", GetID());
-
- bool software_single_step = !SupportHardwareSingleStepping();
-
- if (software_single_step) {
- for (const auto &thread : m_threads) {
- assert(thread && "thread list should not contain NULL threads");
-
- const ResumeAction *const action =
- resume_actions.GetActionForThread(thread->GetID(), true);
- if (action == nullptr)
- continue;
-
- if (action->state == eStateStepping) {
- Status error = SetupSoftwareSingleStepping(
- static_cast<NativeThreadLinux &>(*thread));
- if (error.Fail())
- return error;
- }
- }
- }
-
- for (const auto &thread : m_threads) {
- assert(thread && "thread list should not contain NULL threads");
-
- const ResumeAction *const action =
- resume_actions.GetActionForThread(thread->GetID(), true);
-
- if (action == nullptr) {
- LLDB_LOG(log, "no action specified for pid {0} tid {1}", GetID(),
- thread->GetID());
- continue;
- }
-
- LLDB_LOG(log, "processing resume action state {0} for pid {1} tid {2}",
- action->state, GetID(), thread->GetID());
-
- switch (action->state) {
- case eStateRunning:
- case eStateStepping: {
- // Run the thread, possibly feeding it the signal.
- const int signo = action->signal;
- ResumeThread(static_cast<NativeThreadLinux &>(*thread), action->state,
- signo);
- break;
- }
-
- case eStateSuspended:
- case eStateStopped:
- llvm_unreachable("Unexpected state");
-
- default:
- return Status("NativeProcessLinux::%s (): unexpected state %s specified "
- "for pid %" PRIu64 ", tid %" PRIu64,
- __FUNCTION__, StateAsCString(action->state), GetID(),
- thread->GetID());
- }
- }
-
- return Status();
-}
-
-Status NativeProcessLinux::Halt() {
- Status error;
-
- if (kill(GetID(), SIGSTOP) != 0)
- error.SetErrorToErrno();
-
- return error;
-}
-
-Status NativeProcessLinux::Detach() {
- Status error;
-
- // Stop monitoring the inferior.
- m_sigchld_handle.reset();
-
- // Tell ptrace to detach from the process.
- if (GetID() == LLDB_INVALID_PROCESS_ID)
- return error;
-
- for (const auto &thread : m_threads) {
- Status e = Detach(thread->GetID());
- if (e.Fail())
- error =
- e; // Save the error, but still attempt to detach from other threads.
- }
-
- m_processor_trace_monitor.clear();
- m_pt_proces_trace_id = LLDB_INVALID_UID;
-
- return error;
-}
-
-Status NativeProcessLinux::Signal(int signo) {
- Status error;
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOG(log, "sending signal {0} ({1}) to pid {1}", signo,
- Host::GetSignalAsCString(signo), GetID());
-
- if (kill(GetID(), signo))
- error.SetErrorToErrno();
-
- return error;
-}
-
-Status NativeProcessLinux::Interrupt() {
- // Pick a running thread (or if none, a not-dead stopped thread) as the
- // chosen thread that will be the stop-reason thread.
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
- NativeThreadProtocol *running_thread = nullptr;
- NativeThreadProtocol *stopped_thread = nullptr;
-
- LLDB_LOG(log, "selecting running thread for interrupt target");
- for (const auto &thread : m_threads) {
- // If we have a running or stepping thread, we'll call that the target of
- // the interrupt.
- const auto thread_state = thread->GetState();
- if (thread_state == eStateRunning || thread_state == eStateStepping) {
- running_thread = thread.get();
- break;
- } else if (!stopped_thread && StateIsStoppedState(thread_state, true)) {
- // Remember the first non-dead stopped thread. We'll use that as a
- // backup if there are no running threads.
- stopped_thread = thread.get();
- }
- }
-
- if (!running_thread && !stopped_thread) {
- Status error("found no running/stepping or live stopped threads as target "
- "for interrupt");
- LLDB_LOG(log, "skipping due to error: {0}", error);
-
- return error;
- }
-
- NativeThreadProtocol *deferred_signal_thread =
- running_thread ? running_thread : stopped_thread;
-
- LLDB_LOG(log, "pid {0} {1} tid {2} chosen for interrupt target", GetID(),
- running_thread ? "running" : "stopped",
- deferred_signal_thread->GetID());
-
- StopRunningThreads(deferred_signal_thread->GetID());
-
- return Status();
-}
-
-Status NativeProcessLinux::Kill() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOG(log, "pid {0}", GetID());
-
- Status 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(),
- 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;
-}
-
-Status NativeProcessLinux::GetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &range_info) {
- // FIXME review that the final memory region returned extends to the end of
- // the virtual address space,
- // with no perms if it is not mapped.
-
- // Use an approach that reads memory regions from /proc/{pid}/maps. Assume
- // proc maps entries are in ascending order.
- // FIXME assert if we find differently.
-
- if (m_supports_mem_region == LazyBool::eLazyBoolNo) {
- // We're done.
- return Status("unsupported");
- }
-
- Status 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;
-}
-
-Status NativeProcessLinux::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 Status();
- }
-
- auto BufferOrError = getProcFile(GetID(), "maps");
- if (!BufferOrError) {
- m_supports_mem_region = LazyBool::eLazyBoolNo;
- return BufferOrError.getError();
- }
- Status Result;
- ParseLinuxMapRegions(BufferOrError.get()->getBuffer(),
- [&](const MemoryRegionInfo &Info, const Status &ST) {
- if (ST.Success()) {
- FileSpec file_spec(Info.GetName().GetCString());
- FileSystem::Instance().Resolve(file_spec);
- m_mem_region_cache.emplace_back(Info, file_spec);
- return true;
- } else {
- m_supports_mem_region = LazyBool::eLazyBoolNo;
- LLDB_LOG(log, "failed to parse proc maps: {0}", ST);
- Result = ST;
- return false;
- }
- });
- if (Result.Fail())
- return Result;
-
- if (m_mem_region_cache.empty()) {
- // No entries after attempting to read them. This shouldn't happen if
- // /proc/{pid}/maps is supported. Assume we don't support map entries via
- // procfs.
- m_supports_mem_region = LazyBool::eLazyBoolNo;
- LLDB_LOG(log,
- "failed to find any procfs maps entries, assuming no support "
- "for memory region metadata retrieval");
- return Status("not supported");
- }
-
- LLDB_LOG(log, "read {0} memory region entries from /proc/{1}/maps",
- m_mem_region_cache.size(), GetID());
-
- // We support memory retrieval, remember that.
- m_supports_mem_region = LazyBool::eLazyBoolYes;
- return Status();
-}
-
-void NativeProcessLinux::DoStopIDBumped(uint32_t newBumpId) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOG(log, "newBumpId={0}", newBumpId);
- LLDB_LOG(log, "clearing {0} entries from memory region cache",
- m_mem_region_cache.size());
- m_mem_region_cache.clear();
-}
-
-Status NativeProcessLinux::AllocateMemory(size_t size, uint32_t permissions,
- lldb::addr_t &addr) {
-// FIXME implementing this requires the equivalent of
-// InferiorCallPOSIX::InferiorCallMmap, which depends on functional ThreadPlans
-// working with Native*Protocol.
-#if 1
- return Status("not implemented yet");
-#else
- addr = LLDB_INVALID_ADDRESS;
-
- unsigned prot = 0;
- if (permissions & lldb::ePermissionsReadable)
- prot |= eMmapProtRead;
- if (permissions & lldb::ePermissionsWritable)
- prot |= eMmapProtWrite;
- if (permissions & lldb::ePermissionsExecutable)
- prot |= eMmapProtExec;
-
- // TODO implement this directly in NativeProcessLinux
- // (and lift to NativeProcessPOSIX if/when that class is refactored out).
- if (InferiorCallMmap(this, addr, 0, size, prot,
- eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) {
- m_addr_to_mmap_size[addr] = size;
- return Status();
- } else {
- addr = LLDB_INVALID_ADDRESS;
- return Status("unable to allocate %" PRIu64
- " bytes of memory with permissions %s",
- size, GetPermissionsAsCString(permissions));
- }
-#endif
-}
-
-Status NativeProcessLinux::DeallocateMemory(lldb::addr_t addr) {
- // FIXME see comments in AllocateMemory - required lower-level
- // bits not in place yet (ThreadPlans)
- return Status("not implemented");
-}
-
-lldb::addr_t NativeProcessLinux::GetSharedLibraryInfoAddress() {
- // punt on this for now
- return LLDB_INVALID_ADDRESS;
-}
-
-size_t NativeProcessLinux::UpdateThreads() {
- // The NativeProcessLinux monitoring threads are always up to date with
- // respect to thread state and they keep the thread list populated properly.
- // All this method needs to do is return the thread count.
- return m_threads.size();
-}
-
-Status NativeProcessLinux::SetBreakpoint(lldb::addr_t addr, uint32_t size,
- bool hardware) {
- if (hardware)
- return SetHardwareBreakpoint(addr, size);
- else
- return SetSoftwareBreakpoint(addr, size);
-}
-
-Status NativeProcessLinux::RemoveBreakpoint(lldb::addr_t addr, bool hardware) {
- if (hardware)
- return RemoveHardwareBreakpoint(addr);
- else
- return NativeProcessProtocol::RemoveBreakpoint(addr);
-}
-
-llvm::Expected<llvm::ArrayRef<uint8_t>>
-NativeProcessLinux::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
- // The ARM reference recommends the use of 0xe7fddefe and 0xdefe but the
- // linux kernel does otherwise.
- static const uint8_t g_arm_opcode[] = {0xf0, 0x01, 0xf0, 0xe7};
- static const uint8_t g_thumb_opcode[] = {0x01, 0xde};
-
- switch (GetArchitecture().GetMachine()) {
- case llvm::Triple::arm:
- switch (size_hint) {
- case 2:
- return llvm::makeArrayRef(g_thumb_opcode);
- case 4:
- return llvm::makeArrayRef(g_arm_opcode);
- default:
- return llvm::createStringError(llvm::inconvertibleErrorCode(),
- "Unrecognised trap opcode size hint!");
- }
- default:
- return NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_hint);
- }
-}
-
-Status NativeProcessLinux::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
- size_t &bytes_read) {
- if (ProcessVmReadvSupported()) {
- // The process_vm_readv path is about 50 times faster than ptrace api. We
- // want to use this syscall if it is supported.
-
- const ::pid_t pid = GetID();
-
- struct iovec local_iov, remote_iov;
- local_iov.iov_base = buf;
- local_iov.iov_len = size;
- remote_iov.iov_base = reinterpret_cast<void *>(addr);
- remote_iov.iov_len = size;
-
- bytes_read = process_vm_readv(pid, &local_iov, 1, &remote_iov, 1, 0);
- const bool success = bytes_read == size;
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOG(log,
- "using process_vm_readv to read {0} bytes from inferior "
- "address {1:x}: {2}",
- size, addr, success ? "Success" : llvm::sys::StrError(errno));
-
- if (success)
- return Status();
- // else the call failed for some reason, let's retry the read using ptrace
- // api.
- }
-
- unsigned char *dst = static_cast<unsigned char *>(buf);
- size_t remainder;
- long data;
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY));
- LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
-
- for (bytes_read = 0; bytes_read < size; bytes_read += remainder) {
- Status error = NativeProcessLinux::PtraceWrapper(
- PTRACE_PEEKDATA, GetID(), (void *)addr, nullptr, 0, &data);
- if (error.Fail())
- return error;
-
- remainder = size - bytes_read;
- remainder = remainder > k_ptrace_word_size ? k_ptrace_word_size : remainder;
-
- // Copy the data into our buffer
- memcpy(dst, &data, remainder);
-
- LLDB_LOG(log, "[{0:x}]:{1:x}", addr, data);
- addr += k_ptrace_word_size;
- dst += k_ptrace_word_size;
- }
- return Status();
-}
-
-Status NativeProcessLinux::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);
- size_t remainder;
- Status error;
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY));
- LLDB_LOG(log, "addr = {0}, buf = {1}, size = {2}", addr, buf, size);
-
- for (bytes_written = 0; bytes_written < size; bytes_written += remainder) {
- remainder = size - bytes_written;
- remainder = remainder > k_ptrace_word_size ? k_ptrace_word_size : remainder;
-
- if (remainder == k_ptrace_word_size) {
- unsigned long data = 0;
- memcpy(&data, src, k_ptrace_word_size);
-
- LLDB_LOG(log, "[{0:x}]:{1:x}", addr, data);
- error = NativeProcessLinux::PtraceWrapper(PTRACE_POKEDATA, GetID(),
- (void *)addr, (void *)data);
- if (error.Fail())
- return error;
- } else {
- unsigned char buff[8];
- size_t bytes_read;
- error = ReadMemory(addr, buff, k_ptrace_word_size, bytes_read);
- if (error.Fail())
- return error;
-
- memcpy(buff, src, remainder);
-
- size_t bytes_written_rec;
- error = WriteMemory(addr, buff, k_ptrace_word_size, bytes_written_rec);
- if (error.Fail())
- return error;
-
- LLDB_LOG(log, "[{0:x}]:{1:x} ({2:x})", addr, *(const unsigned long *)src,
- *(unsigned long *)buff);
- }
-
- addr += k_ptrace_word_size;
- src += k_ptrace_word_size;
- }
- return error;
-}
-
-Status NativeProcessLinux::GetSignalInfo(lldb::tid_t tid, void *siginfo) {
- return PtraceWrapper(PTRACE_GETSIGINFO, tid, nullptr, siginfo);
-}
-
-Status NativeProcessLinux::GetEventMessage(lldb::tid_t tid,
- unsigned long *message) {
- return PtraceWrapper(PTRACE_GETEVENTMSG, tid, nullptr, message);
-}
-
-Status NativeProcessLinux::Detach(lldb::tid_t tid) {
- if (tid == LLDB_INVALID_THREAD_ID)
- return Status();
-
- return PtraceWrapper(PTRACE_DETACH, tid);
-}
-
-bool NativeProcessLinux::HasThreadNoLock(lldb::tid_t thread_id) {
- for (const auto &thread : m_threads) {
- assert(thread && "thread list should not contain NULL threads");
- if (thread->GetID() == thread_id) {
- // We have this thread.
- return true;
- }
- }
-
- // We don't have this thread.
- return false;
-}
-
-bool NativeProcessLinux::StopTrackingThread(lldb::tid_t thread_id) {
- Log *const log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD);
- LLDB_LOG(log, "tid: {0})", thread_id);
-
- bool found = false;
- for (auto it = m_threads.begin(); it != m_threads.end(); ++it) {
- if (*it && ((*it)->GetID() == thread_id)) {
- m_threads.erase(it);
- found = true;
- break;
- }
- }
-
- if (found)
- StopTracingForThread(thread_id);
- SignalIfAllThreadsStopped();
- return found;
-}
-
-NativeThreadLinux &NativeProcessLinux::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);
-
- m_threads.push_back(llvm::make_unique<NativeThreadLinux>(*this, thread_id));
-
- if (m_pt_proces_trace_id != LLDB_INVALID_UID) {
- auto traceMonitor = ProcessorTraceMonitor::Create(
- GetID(), thread_id, m_pt_process_trace_config, true);
- if (traceMonitor) {
- m_pt_traced_thread_group.insert(thread_id);
- m_processor_trace_monitor.insert(
- std::make_pair(thread_id, std::move(*traceMonitor)));
- } else {
- LLDB_LOG(log, "failed to start trace on thread {0}", thread_id);
- Status error(traceMonitor.takeError());
- LLDB_LOG(log, "error {0}", error);
- }
- }
-
- return static_cast<NativeThreadLinux &>(*m_threads.back());
-}
-
-Status NativeProcessLinux::GetLoadedModuleFileSpec(const char *module_path,
- FileSpec &file_spec) {
- Status error = PopulateMemoryRegionCache();
- if (error.Fail())
- return error;
-
- FileSpec module_file_spec(module_path);
- FileSystem::Instance().Resolve(module_file_spec);
-
- file_spec.Clear();
- for (const auto &it : m_mem_region_cache) {
- if (it.second.GetFilename() == module_file_spec.GetFilename()) {
- file_spec = it.second;
- return Status();
- }
- }
- return Status("Module file (%s) not found in /proc/%" PRIu64 "/maps file!",
- module_file_spec.GetFilename().AsCString(), GetID());
-}
-
-Status NativeProcessLinux::GetFileLoadAddress(const llvm::StringRef &file_name,
- lldb::addr_t &load_addr) {
- load_addr = LLDB_INVALID_ADDRESS;
- Status error = PopulateMemoryRegionCache();
- if (error.Fail())
- return error;
-
- FileSpec file(file_name);
- for (const auto &it : m_mem_region_cache) {
- if (it.second == file) {
- load_addr = it.first.GetRange().GetRangeBase();
- return Status();
- }
- }
- return Status("No load address found for specified file.");
-}
-
-NativeThreadLinux *NativeProcessLinux::GetThreadByID(lldb::tid_t tid) {
- return static_cast<NativeThreadLinux *>(
- NativeProcessProtocol::GetThreadByID(tid));
-}
-
-Status NativeProcessLinux::ResumeThread(NativeThreadLinux &thread,
- lldb::StateType state, int signo) {
- Log *const log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD);
- LLDB_LOG(log, "tid: {0}", thread.GetID());
-
- // Before we do the resume below, first check if we have a pending stop
- // notification that is currently waiting for all threads to stop. This is
- // potentially a buggy situation since we're ostensibly waiting for threads
- // to stop before we send out the pending notification, and here we are
- // resuming one before we send out the pending stop notification.
- if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID) {
- LLDB_LOG(log,
- "about to resume tid {0} per explicit request but we have a "
- "pending stop notification (tid {1}) that is actively "
- "waiting for this thread to stop. Valid sequence of events?",
- thread.GetID(), m_pending_notification_tid);
- }
-
- // Request a resume. We expect this to be synchronous and the system to
- // reflect it is running after this completes.
- switch (state) {
- case eStateRunning: {
- const auto resume_result = thread.Resume(signo);
- if (resume_result.Success())
- SetState(eStateRunning, true);
- return resume_result;
- }
- case eStateStepping: {
- const auto step_result = thread.SingleStep(signo);
- if (step_result.Success())
- SetState(eStateRunning, true);
- return step_result;
- }
- default:
- LLDB_LOG(log, "Unhandled state {0}.", state);
- llvm_unreachable("Unhandled state for resume");
- }
-}
-
-//===----------------------------------------------------------------------===//
-
-void NativeProcessLinux::StopRunningThreads(const lldb::tid_t triggering_tid) {
- Log *const log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD);
- LLDB_LOG(log, "about to process event: (triggering_tid: {0})",
- triggering_tid);
-
- m_pending_notification_tid = triggering_tid;
-
- // Request a stop for all the thread stops that need to be stopped and are
- // not already known to be stopped.
- for (const auto &thread : m_threads) {
- if (StateIsRunningState(thread->GetState()))
- static_cast<NativeThreadLinux *>(thread.get())->RequestStop();
- }
-
- SignalIfAllThreadsStopped();
- LLDB_LOG(log, "event processing done");
-}
-
-void NativeProcessLinux::SignalIfAllThreadsStopped() {
- if (m_pending_notification_tid == LLDB_INVALID_THREAD_ID)
- return; // No pending notification. Nothing to do.
-
- for (const auto &thread_sp : m_threads) {
- if (StateIsRunningState(thread_sp->GetState()))
- return; // Some threads are still running. Don't signal yet.
- }
-
- // We have a pending notification and all threads have stopped.
- Log *log(
- GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_BREAKPOINTS));
-
- // Clear any temporary breakpoints we used to implement software single
- // stepping.
- for (const auto &thread_info : m_threads_stepping_with_breakpoint) {
- Status error = RemoveBreakpoint(thread_info.second);
- if (error.Fail())
- LLDB_LOG(log, "pid = {0} remove stepping breakpoint: {1}",
- thread_info.first, error);
- }
- m_threads_stepping_with_breakpoint.clear();
-
- // Notify the delegate about the stop
- SetCurrentThreadID(m_pending_notification_tid);
- SetState(StateType::eStateStopped, true);
- m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
-}
-
-void NativeProcessLinux::ThreadWasCreated(NativeThreadLinux &thread) {
- Log *const log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD);
- LLDB_LOG(log, "tid: {0}", thread.GetID());
-
- if (m_pending_notification_tid != LLDB_INVALID_THREAD_ID &&
- StateIsRunningState(thread.GetState())) {
- // We will need to wait for this new thread to stop as well before firing
- // the notification.
- thread.RequestStop();
- }
-}
-
-void NativeProcessLinux::SigchldHandler() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- // Process all pending waitpid notifications.
- while (true) {
- int status = -1;
- ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, ::waitpid, -1, &status,
- __WALL | __WNOTHREAD | WNOHANG);
-
- if (wait_pid == 0)
- break; // We are done.
-
- if (wait_pid == -1) {
- Status error(errno, eErrorTypePOSIX);
- LLDB_LOG(log, "waitpid (-1, &status, _) failed: {0}", error);
- break;
- }
-
- WaitStatus wait_status = WaitStatus::Decode(status);
- bool exited = wait_status.type == WaitStatus::Exit ||
- (wait_status.type == WaitStatus::Signal &&
- wait_pid == static_cast<::pid_t>(GetID()));
-
- LLDB_LOG(
- log,
- "waitpid (-1, &status, _) => pid = {0}, status = {1}, exited = {2}",
- wait_pid, wait_status, exited);
-
- MonitorCallback(wait_pid, exited, wait_status);
- }
-}
-
-// Wrapper for ptrace to catch errors and log calls. Note that ptrace sets
-// errno on error because -1 can be a valid result (i.e. for PTRACE_PEEK*)
-Status NativeProcessLinux::PtraceWrapper(int req, lldb::pid_t pid, void *addr,
- void *data, size_t data_size,
- long *result) {
- Status error;
- long int ret;
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
- PtraceDisplayBytes(req, data, data_size);
-
- errno = 0;
- if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
- ret = ptrace(static_cast<__ptrace_request>(req), static_cast<::pid_t>(pid),
- *(unsigned int *)addr, data);
- else
- ret = ptrace(static_cast<__ptrace_request>(req), static_cast<::pid_t>(pid),
- addr, data);
-
- if (ret == -1)
- error.SetErrorToErrno();
-
- if (result)
- *result = ret;
-
- LLDB_LOG(log, "ptrace({0}, {1}, {2}, {3}, {4})={5:x}", req, pid, addr, data,
- data_size, ret);
-
- PtraceDisplayBytes(req, data, data_size);
-
- if (error.Fail())
- LLDB_LOG(log, "ptrace() failed: {0}", error);
-
- return error;
-}
-
-llvm::Expected<ProcessorTraceMonitor &>
-NativeProcessLinux::LookupProcessorTraceInstance(lldb::user_id_t traceid,
- lldb::tid_t thread) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
- if (thread == LLDB_INVALID_THREAD_ID && traceid == m_pt_proces_trace_id) {
- LLDB_LOG(log, "thread not specified: {0}", traceid);
- return Status("tracing not active thread not specified").ToError();
- }
-
- for (auto& iter : m_processor_trace_monitor) {
- if (traceid == iter.second->GetTraceID() &&
- (thread == iter.first || thread == LLDB_INVALID_THREAD_ID))
- return *(iter.second);
- }
-
- LLDB_LOG(log, "traceid not being traced: {0}", traceid);
- return Status("tracing not active for this thread").ToError();
-}
-
-Status NativeProcessLinux::GetMetaData(lldb::user_id_t traceid,
- lldb::tid_t thread,
- llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset) {
- TraceOptions trace_options;
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
- Status error;
-
- LLDB_LOG(log, "traceid {0}", traceid);
-
- auto perf_monitor = LookupProcessorTraceInstance(traceid, thread);
- if (!perf_monitor) {
- LLDB_LOG(log, "traceid not being traced: {0}", traceid);
- buffer = buffer.slice(buffer.size());
- error = perf_monitor.takeError();
- return error;
- }
- return (*perf_monitor).ReadPerfTraceData(buffer, offset);
-}
-
-Status NativeProcessLinux::GetData(lldb::user_id_t traceid, lldb::tid_t thread,
- llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
- Status error;
-
- LLDB_LOG(log, "traceid {0}", traceid);
-
- auto perf_monitor = LookupProcessorTraceInstance(traceid, thread);
- if (!perf_monitor) {
- LLDB_LOG(log, "traceid not being traced: {0}", traceid);
- buffer = buffer.slice(buffer.size());
- error = perf_monitor.takeError();
- return error;
- }
- return (*perf_monitor).ReadPerfTraceAux(buffer, offset);
-}
-
-Status NativeProcessLinux::GetTraceConfig(lldb::user_id_t traceid,
- TraceOptions &config) {
- Status error;
- if (config.getThreadID() == LLDB_INVALID_THREAD_ID &&
- m_pt_proces_trace_id == traceid) {
- if (m_pt_proces_trace_id == LLDB_INVALID_UID) {
- error.SetErrorString("tracing not active for this process");
- return error;
- }
- config = m_pt_process_trace_config;
- } else {
- auto perf_monitor =
- LookupProcessorTraceInstance(traceid, config.getThreadID());
- if (!perf_monitor) {
- error = perf_monitor.takeError();
- return error;
- }
- error = (*perf_monitor).GetTraceConfig(config);
- }
- return error;
-}
-
-lldb::user_id_t
-NativeProcessLinux::StartTraceGroup(const TraceOptions &config,
- Status &error) {
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
- if (config.getType() != TraceType::eTraceTypeProcessorTrace)
- return LLDB_INVALID_UID;
-
- if (m_pt_proces_trace_id != LLDB_INVALID_UID) {
- error.SetErrorString("tracing already active on this process");
- return m_pt_proces_trace_id;
- }
-
- for (const auto &thread_sp : m_threads) {
- if (auto traceInstance = ProcessorTraceMonitor::Create(
- GetID(), thread_sp->GetID(), config, true)) {
- m_pt_traced_thread_group.insert(thread_sp->GetID());
- m_processor_trace_monitor.insert(
- std::make_pair(thread_sp->GetID(), std::move(*traceInstance)));
- }
- }
-
- m_pt_process_trace_config = config;
- error = ProcessorTraceMonitor::GetCPUType(m_pt_process_trace_config);
-
- // Trace on Complete process will have traceid of 0
- m_pt_proces_trace_id = 0;
-
- LLDB_LOG(log, "Process Trace ID {0}", m_pt_proces_trace_id);
- return m_pt_proces_trace_id;
-}
-
-lldb::user_id_t NativeProcessLinux::StartTrace(const TraceOptions &config,
- Status &error) {
- if (config.getType() != TraceType::eTraceTypeProcessorTrace)
- return NativeProcessProtocol::StartTrace(config, error);
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
- lldb::tid_t threadid = config.getThreadID();
-
- if (threadid == LLDB_INVALID_THREAD_ID)
- return StartTraceGroup(config, error);
-
- auto thread_sp = GetThreadByID(threadid);
- if (!thread_sp) {
- // Thread not tracked by lldb so don't trace.
- error.SetErrorString("invalid thread id");
- return LLDB_INVALID_UID;
- }
-
- const auto &iter = m_processor_trace_monitor.find(threadid);
- if (iter != m_processor_trace_monitor.end()) {
- LLDB_LOG(log, "Thread already being traced");
- error.SetErrorString("tracing already active on this thread");
- return LLDB_INVALID_UID;
- }
-
- auto traceMonitor =
- ProcessorTraceMonitor::Create(GetID(), threadid, config, false);
- if (!traceMonitor) {
- error = traceMonitor.takeError();
- LLDB_LOG(log, "error {0}", error);
- return LLDB_INVALID_UID;
- }
- lldb::user_id_t ret_trace_id = (*traceMonitor)->GetTraceID();
- m_processor_trace_monitor.insert(
- std::make_pair(threadid, std::move(*traceMonitor)));
- return ret_trace_id;
-}
-
-Status NativeProcessLinux::StopTracingForThread(lldb::tid_t thread) {
- Status error;
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
- LLDB_LOG(log, "Thread {0}", thread);
-
- const auto& iter = m_processor_trace_monitor.find(thread);
- if (iter == m_processor_trace_monitor.end()) {
- error.SetErrorString("tracing not active for this thread");
- return error;
- }
-
- if (iter->second->GetTraceID() == m_pt_proces_trace_id) {
- // traceid maps to the whole process so we have to erase it from the thread
- // group.
- LLDB_LOG(log, "traceid maps to process");
- m_pt_traced_thread_group.erase(thread);
- }
- m_processor_trace_monitor.erase(iter);
-
- return error;
-}
-
-Status NativeProcessLinux::StopTrace(lldb::user_id_t traceid,
- lldb::tid_t thread) {
- Status error;
-
- TraceOptions trace_options;
- trace_options.setThreadID(thread);
- error = NativeProcessLinux::GetTraceConfig(traceid, trace_options);
-
- if (error.Fail())
- return error;
-
- switch (trace_options.getType()) {
- case lldb::TraceType::eTraceTypeProcessorTrace:
- if (traceid == m_pt_proces_trace_id &&
- thread == LLDB_INVALID_THREAD_ID)
- StopProcessorTracingOnProcess();
- else
- error = StopProcessorTracingOnThread(traceid, thread);
- break;
- default:
- error.SetErrorString("trace not supported");
- break;
- }
-
- return error;
-}
-
-void NativeProcessLinux::StopProcessorTracingOnProcess() {
- for (auto thread_id_iter : m_pt_traced_thread_group)
- m_processor_trace_monitor.erase(thread_id_iter);
- m_pt_traced_thread_group.clear();
- m_pt_proces_trace_id = LLDB_INVALID_UID;
-}
-
-Status NativeProcessLinux::StopProcessorTracingOnThread(lldb::user_id_t traceid,
- lldb::tid_t thread) {
- Status error;
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
- if (thread == LLDB_INVALID_THREAD_ID) {
- for (auto& iter : m_processor_trace_monitor) {
- if (iter.second->GetTraceID() == traceid) {
- // Stopping a trace instance for an individual thread hence there will
- // only be one traceid that can match.
- m_processor_trace_monitor.erase(iter.first);
- return error;
- }
- LLDB_LOG(log, "Trace ID {0}", iter.second->GetTraceID());
- }
-
- LLDB_LOG(log, "Invalid TraceID");
- error.SetErrorString("invalid trace id");
- return error;
- }
-
- // thread is specified so we can use find function on the map.
- const auto& iter = m_processor_trace_monitor.find(thread);
- if (iter == m_processor_trace_monitor.end()) {
- // thread not found in our map.
- LLDB_LOG(log, "thread not being traced");
- error.SetErrorString("tracing not active for this thread");
- return error;
- }
- if (iter->second->GetTraceID() != traceid) {
- // traceid did not match so it has to be invalid.
- LLDB_LOG(log, "Invalid TraceID");
- error.SetErrorString("invalid trace id");
- return error;
- }
-
- LLDB_LOG(log, "UID - {0} , Thread -{1}", traceid, thread);
-
- if (traceid == m_pt_proces_trace_id) {
- // traceid maps to the whole process so we have to erase it from the thread
- // group.
- LLDB_LOG(log, "traceid maps to process");
- m_pt_traced_thread_group.erase(thread);
- }
- m_processor_trace_monitor.erase(iter);
-
- return error;
-}
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.h b/source/Plugins/Process/Linux/NativeProcessLinux.h
deleted file mode 100644
index 69f2b528d3300..0000000000000
--- a/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ /dev/null
@@ -1,261 +0,0 @@
-//===-- NativeProcessLinux.h ---------------------------------- -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_NativeProcessLinux_H_
-#define liblldb_NativeProcessLinux_H_
-
-#include <csignal>
-#include <unordered_set>
-
-#include "lldb/Host/Debug.h"
-#include "lldb/Host/HostThread.h"
-#include "lldb/Host/linux/Support.h"
-#include "lldb/Target/MemoryRegionInfo.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/lldb-types.h"
-
-#include "NativeThreadLinux.h"
-#include "ProcessorTrace.h"
-#include "lldb/Host/common/NativeProcessProtocol.h"
-
-namespace lldb_private {
-class Status;
-class Scalar;
-
-namespace process_linux {
-/// @class NativeProcessLinux
-/// Manages communication with the inferior (debugee) process.
-///
-/// Upon construction, this class prepares and launches an inferior process
-/// for debugging.
-///
-/// Changes in the inferior process state are broadcasted.
-class NativeProcessLinux : public NativeProcessProtocol {
-public:
- class Factory : public NativeProcessProtocol::Factory {
- public:
- llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
- Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
- MainLoop &mainloop) const override;
-
- llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
- Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
- MainLoop &mainloop) const override;
- };
-
- // ---------------------------------------------------------------------
- // NativeProcessProtocol Interface
- // ---------------------------------------------------------------------
- Status Resume(const ResumeActionList &resume_actions) override;
-
- Status Halt() override;
-
- Status Detach() override;
-
- Status Signal(int signo) override;
-
- Status Interrupt() override;
-
- Status Kill() override;
-
- Status GetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &range_info) override;
-
- Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
- size_t &bytes_read) override;
-
- Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
- size_t &bytes_written) override;
-
- Status AllocateMemory(size_t size, uint32_t permissions,
- lldb::addr_t &addr) override;
-
- Status DeallocateMemory(lldb::addr_t addr) override;
-
- lldb::addr_t GetSharedLibraryInfoAddress() override;
-
- size_t UpdateThreads() override;
-
- const ArchSpec &GetArchitecture() const override { return m_arch; }
-
- Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
- bool hardware) override;
-
- Status RemoveBreakpoint(lldb::addr_t addr, bool hardware = false) override;
-
- void DoStopIDBumped(uint32_t newBumpId) override;
-
- Status GetLoadedModuleFileSpec(const char *module_path,
- FileSpec &file_spec) override;
-
- Status GetFileLoadAddress(const llvm::StringRef &file_name,
- lldb::addr_t &load_addr) override;
-
- NativeThreadLinux *GetThreadByID(lldb::tid_t id);
-
- llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
- GetAuxvData() const override {
- return getProcFile(GetID(), "auxv");
- }
-
- lldb::user_id_t StartTrace(const TraceOptions &config,
- Status &error) override;
-
- Status StopTrace(lldb::user_id_t traceid,
- lldb::tid_t thread) override;
-
- Status GetData(lldb::user_id_t traceid, lldb::tid_t thread,
- llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset = 0) override;
-
- Status GetMetaData(lldb::user_id_t traceid, lldb::tid_t thread,
- llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset = 0) override;
-
- Status GetTraceConfig(lldb::user_id_t traceid, TraceOptions &config) override;
-
- // ---------------------------------------------------------------------
- // Interface used by NativeRegisterContext-derived classes.
- // ---------------------------------------------------------------------
- static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
- void *data = nullptr, size_t data_size = 0,
- long *result = nullptr);
-
- bool SupportHardwareSingleStepping() const;
-
-protected:
- llvm::Expected<llvm::ArrayRef<uint8_t>>
- GetSoftwareBreakpointTrapOpcode(size_t size_hint) override;
-
-private:
- MainLoop::SignalHandleUP m_sigchld_handle;
- ArchSpec m_arch;
-
- LazyBool m_supports_mem_region = eLazyBoolCalculate;
- std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
-
- lldb::tid_t m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
-
- // List of thread ids stepping with a breakpoint with the address of
- // the relevan breakpoint
- std::map<lldb::tid_t, lldb::addr_t> m_threads_stepping_with_breakpoint;
-
- // ---------------------------------------------------------------------
- // Private Instance Methods
- // ---------------------------------------------------------------------
- NativeProcessLinux(::pid_t pid, int terminal_fd, NativeDelegate &delegate,
- const ArchSpec &arch, MainLoop &mainloop,
- llvm::ArrayRef<::pid_t> tids);
-
- // Returns a list of process threads that we have attached to.
- static llvm::Expected<std::vector<::pid_t>> Attach(::pid_t pid);
-
- static Status SetDefaultPtraceOpts(const lldb::pid_t);
-
- void MonitorCallback(lldb::pid_t pid, bool exited, WaitStatus status);
-
- void WaitForNewThread(::pid_t tid);
-
- void MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread);
-
- void MonitorTrace(NativeThreadLinux &thread);
-
- void MonitorBreakpoint(NativeThreadLinux &thread);
-
- void MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index);
-
- void MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread,
- bool exited);
-
- Status SetupSoftwareSingleStepping(NativeThreadLinux &thread);
-
- bool HasThreadNoLock(lldb::tid_t thread_id);
-
- bool StopTrackingThread(lldb::tid_t thread_id);
-
- NativeThreadLinux &AddThread(lldb::tid_t thread_id);
-
- /// Writes a siginfo_t structure corresponding to the given thread ID to the
- /// memory region pointed to by @p siginfo.
- Status GetSignalInfo(lldb::tid_t tid, void *siginfo);
-
- /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
- /// corresponding to the given thread ID to the memory pointed to by @p
- /// message.
- Status GetEventMessage(lldb::tid_t tid, unsigned long *message);
-
- void NotifyThreadDeath(lldb::tid_t tid);
-
- Status Detach(lldb::tid_t tid);
-
- // This method is requests a stop on all threads which are still running. It
- // sets up a
- // deferred delegate notification, which will fire once threads report as
- // stopped. The
- // triggerring_tid will be set as the current thread (main stop reason).
- void StopRunningThreads(lldb::tid_t triggering_tid);
-
- // Notify the delegate if all threads have stopped.
- void SignalIfAllThreadsStopped();
-
- // Resume the given thread, optionally passing it the given signal. The type
- // of resume
- // operation (continue, single-step) depends on the state parameter.
- Status ResumeThread(NativeThreadLinux &thread, lldb::StateType state,
- int signo);
-
- void ThreadWasCreated(NativeThreadLinux &thread);
-
- void SigchldHandler();
-
- Status PopulateMemoryRegionCache();
-
- lldb::user_id_t StartTraceGroup(const TraceOptions &config,
- Status &error);
-
- // This function is intended to be used to stop tracing
- // on a thread that exited.
- Status StopTracingForThread(lldb::tid_t thread);
-
- // The below function as the name suggests, looks up a ProcessorTrace
- // instance from the m_processor_trace_monitor map. In the case of
- // process tracing where the traceid passed would map to the complete
- // process, it is mandatory to provide a threadid to obtain a trace
- // instance (since ProcessorTrace is tied to a thread). In the other
- // scenario that an individual thread is being traced, just the traceid
- // is sufficient to obtain the actual ProcessorTrace instance.
- llvm::Expected<ProcessorTraceMonitor &>
- LookupProcessorTraceInstance(lldb::user_id_t traceid, lldb::tid_t thread);
-
- // Stops tracing on individual threads being traced. Not intended
- // to be used to stop tracing on complete process.
- Status StopProcessorTracingOnThread(lldb::user_id_t traceid,
- lldb::tid_t thread);
-
- // Intended to stop tracing on complete process.
- // Should not be used for stopping trace on
- // individual threads.
- void StopProcessorTracingOnProcess();
-
- llvm::DenseMap<lldb::tid_t, ProcessorTraceMonitorUP>
- m_processor_trace_monitor;
-
- // Set for tracking threads being traced under
- // same process user id.
- llvm::DenseSet<lldb::tid_t> m_pt_traced_thread_group;
-
- lldb::user_id_t m_pt_proces_trace_id = LLDB_INVALID_UID;
- TraceOptions m_pt_process_trace_config;
-};
-
-} // namespace process_linux
-} // namespace lldb_private
-
-#endif // #ifndef liblldb_NativeProcessLinux_H_
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
deleted file mode 100644
index 79f635c88985b..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-//===-- NativeRegisterContextLinux.cpp --------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "NativeRegisterContextLinux.h"
-
-#include "lldb/Host/common/NativeProcessProtocol.h"
-#include "lldb/Host/common/NativeThreadProtocol.h"
-#include "lldb/Host/linux/Ptrace.h"
-#include "lldb/Utility/RegisterValue.h"
-
-#include "Plugins/Process/Linux/NativeProcessLinux.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-
-using namespace lldb_private;
-using namespace lldb_private::process_linux;
-
-NativeRegisterContextLinux::NativeRegisterContextLinux(
- NativeThreadProtocol &native_thread,
- RegisterInfoInterface *reg_info_interface_p)
- : NativeRegisterContextRegisterInfo(native_thread, reg_info_interface_p) {}
-
-lldb::ByteOrder NativeRegisterContextLinux::GetByteOrder() const {
- return m_thread.GetProcess().GetByteOrder();
-}
-
-Status NativeRegisterContextLinux::ReadRegisterRaw(uint32_t reg_index,
- RegisterValue &reg_value) {
- const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
- if (!reg_info)
- return Status("register %" PRIu32 " not found", reg_index);
-
- return DoReadRegisterValue(reg_info->byte_offset, reg_info->name,
- reg_info->byte_size, reg_value);
-}
-
-Status
-NativeRegisterContextLinux::WriteRegisterRaw(uint32_t reg_index,
- const RegisterValue &reg_value) {
- uint32_t reg_to_write = reg_index;
- RegisterValue value_to_write = reg_value;
-
- // Check if this is a subregister of a full register.
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_index);
- if (reg_info->invalidate_regs &&
- (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) {
- Status error;
-
- RegisterValue full_value;
- uint32_t full_reg = reg_info->invalidate_regs[0];
- const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
-
- // Read the full register.
- error = ReadRegister(full_reg_info, full_value);
- if (error.Fail())
- return error;
-
- lldb::ByteOrder byte_order = GetByteOrder();
- uint8_t dst[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the full register.
- const uint32_t dest_size = full_value.GetAsMemoryData(
- full_reg_info, dst, sizeof(dst), byte_order, error);
- if (error.Success() && dest_size) {
- uint8_t src[RegisterValue::kMaxRegisterByteSize];
-
- // Get the bytes for the source data.
- const uint32_t src_size = reg_value.GetAsMemoryData(
- reg_info, src, sizeof(src), byte_order, error);
- if (error.Success() && src_size && (src_size < dest_size)) {
- // Copy the src bytes to the destination.
- memcpy(dst + (reg_info->byte_offset & 0x1), src, src_size);
- // Set this full register as the value to write.
- value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
- value_to_write.SetType(full_reg_info);
- reg_to_write = full_reg;
- }
- }
- }
-
- const RegisterInfo *const register_to_write_info_p =
- GetRegisterInfoAtIndex(reg_to_write);
- assert(register_to_write_info_p &&
- "register to write does not have valid RegisterInfo");
- if (!register_to_write_info_p)
- return Status("NativeRegisterContextLinux::%s failed to get RegisterInfo "
- "for write register index %" PRIu32,
- __FUNCTION__, reg_to_write);
-
- return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, reg_value);
-}
-
-Status NativeRegisterContextLinux::ReadGPR() {
- void *buf = GetGPRBuffer();
- if (!buf)
- return Status("GPR buffer is NULL");
- size_t buf_size = GetGPRSize();
-
- return DoReadGPR(buf, buf_size);
-}
-
-Status NativeRegisterContextLinux::WriteGPR() {
- void *buf = GetGPRBuffer();
- if (!buf)
- return Status("GPR buffer is NULL");
- size_t buf_size = GetGPRSize();
-
- return DoWriteGPR(buf, buf_size);
-}
-
-Status NativeRegisterContextLinux::ReadFPR() {
- void *buf = GetFPRBuffer();
- if (!buf)
- return Status("FPR buffer is NULL");
- size_t buf_size = GetFPRSize();
-
- return DoReadFPR(buf, buf_size);
-}
-
-Status NativeRegisterContextLinux::WriteFPR() {
- void *buf = GetFPRBuffer();
- if (!buf)
- return Status("FPR buffer is NULL");
- size_t buf_size = GetFPRSize();
-
- return DoWriteFPR(buf, buf_size);
-}
-
-Status NativeRegisterContextLinux::ReadRegisterSet(void *buf, size_t buf_size,
- unsigned int regset) {
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(),
- static_cast<void *>(&regset), buf,
- buf_size);
-}
-
-Status NativeRegisterContextLinux::WriteRegisterSet(void *buf, size_t buf_size,
- unsigned int regset) {
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
- static_cast<void *>(&regset), buf,
- buf_size);
-}
-
-Status NativeRegisterContextLinux::DoReadRegisterValue(uint32_t offset,
- const char *reg_name,
- uint32_t size,
- RegisterValue &value) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_REGISTERS));
-
- long data;
- Status error = NativeProcessLinux::PtraceWrapper(
- PTRACE_PEEKUSER, m_thread.GetID(), reinterpret_cast<void *>(offset),
- nullptr, 0, &data);
-
- if (error.Success())
- // First cast to an unsigned of the same size to avoid sign extension.
- value.SetUInt(static_cast<unsigned long>(data), size);
-
- LLDB_LOG(log, "{0}: {1:x}", reg_name, data);
- return error;
-}
-
-Status NativeRegisterContextLinux::DoWriteRegisterValue(
- uint32_t offset, const char *reg_name, const RegisterValue &value) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_REGISTERS));
-
- void *buf = reinterpret_cast<void *>(value.GetAsUInt64());
- LLDB_LOG(log, "{0}: {1}", reg_name, buf);
-
- return NativeProcessLinux::PtraceWrapper(
- PTRACE_POKEUSER, m_thread.GetID(), reinterpret_cast<void *>(offset), buf);
-}
-
-Status NativeRegisterContextLinux::DoReadGPR(void *buf, size_t buf_size) {
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(),
- nullptr, buf, buf_size);
-}
-
-Status NativeRegisterContextLinux::DoWriteGPR(void *buf, size_t buf_size) {
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGS, m_thread.GetID(),
- nullptr, buf, buf_size);
-}
-
-Status NativeRegisterContextLinux::DoReadFPR(void *buf, size_t buf_size) {
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETFPREGS, m_thread.GetID(),
- nullptr, buf, buf_size);
-}
-
-Status NativeRegisterContextLinux::DoWriteFPR(void *buf, size_t buf_size) {
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETFPREGS, m_thread.GetID(),
- nullptr, buf, buf_size);
-}
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
deleted file mode 100644
index 2cea497b53bcd..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux.h
+++ /dev/null
@@ -1,85 +0,0 @@
-//===-- NativeRegisterContextLinux.h ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef lldb_NativeRegisterContextLinux_h
-#define lldb_NativeRegisterContextLinux_h
-
-#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h"
-#include "lldb/Host/common/NativeThreadProtocol.h"
-
-namespace lldb_private {
-namespace process_linux {
-
-class NativeRegisterContextLinux : public NativeRegisterContextRegisterInfo {
-public:
- NativeRegisterContextLinux(NativeThreadProtocol &native_thread,
- RegisterInfoInterface *reg_info_interface_p);
-
- // This function is implemented in the NativeRegisterContextLinux_* subclasses
- // to create a new instance of the host specific NativeRegisterContextLinux.
- // The implementations can't collide as only one NativeRegisterContextLinux_*
- // variant should be compiled into the final executable.
- static std::unique_ptr<NativeRegisterContextLinux>
- CreateHostNativeRegisterContextLinux(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread);
-
-protected:
- lldb::ByteOrder GetByteOrder() const;
-
- virtual Status ReadRegisterRaw(uint32_t reg_index, RegisterValue &reg_value);
-
- virtual Status WriteRegisterRaw(uint32_t reg_index,
- const RegisterValue &reg_value);
-
- virtual Status ReadRegisterSet(void *buf, size_t buf_size,
- unsigned int regset);
-
- virtual Status WriteRegisterSet(void *buf, size_t buf_size,
- unsigned int regset);
-
- virtual Status ReadGPR();
-
- virtual Status WriteGPR();
-
- virtual Status ReadFPR();
-
- virtual Status WriteFPR();
-
- virtual void *GetGPRBuffer() { return nullptr; }
-
- virtual size_t GetGPRSize() {
- return GetRegisterInfoInterface().GetGPRSize();
- }
-
- virtual void *GetFPRBuffer() { return nullptr; }
-
- virtual size_t GetFPRSize() { return 0; }
-
- // The Do*** functions are executed on the privileged thread and can perform
- // ptrace
- // operations directly.
- virtual Status DoReadRegisterValue(uint32_t offset, const char *reg_name,
- uint32_t size, RegisterValue &value);
-
- virtual Status DoWriteRegisterValue(uint32_t offset, const char *reg_name,
- const RegisterValue &value);
-
- virtual Status DoReadGPR(void *buf, size_t buf_size);
-
- virtual Status DoWriteGPR(void *buf, size_t buf_size);
-
- virtual Status DoReadFPR(void *buf, size_t buf_size);
-
- virtual Status DoWriteFPR(void *buf, size_t buf_size);
-};
-
-} // namespace process_linux
-} // namespace lldb_private
-
-#endif // #ifndef lldb_NativeRegisterContextLinux_h
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
deleted file mode 100644
index 09d3a12942f05..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
+++ /dev/null
@@ -1,975 +0,0 @@
-//===-- NativeRegisterContextLinux_arm.cpp --------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
-
-#include "NativeRegisterContextLinux_arm.h"
-
-#include "Plugins/Process/Linux/NativeProcessLinux.h"
-#include "Plugins/Process/Linux/Procfs.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Status.h"
-
-#include <elf.h>
-#include <sys/socket.h>
-
-#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof(m_fpr))
-
-#ifndef PTRACE_GETVFPREGS
-#define PTRACE_GETVFPREGS 27
-#define PTRACE_SETVFPREGS 28
-#endif
-#ifndef PTRACE_GETHBPREGS
-#define PTRACE_GETHBPREGS 29
-#define PTRACE_SETHBPREGS 30
-#endif
-#if !defined(PTRACE_TYPE_ARG3)
-#define PTRACE_TYPE_ARG3 void *
-#endif
-#if !defined(PTRACE_TYPE_ARG4)
-#define PTRACE_TYPE_ARG4 void *
-#endif
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::process_linux;
-
-// arm general purpose registers.
-static const uint32_t g_gpr_regnums_arm[] = {
- gpr_r0_arm, gpr_r1_arm, gpr_r2_arm, gpr_r3_arm, gpr_r4_arm,
- gpr_r5_arm, gpr_r6_arm, gpr_r7_arm, gpr_r8_arm, gpr_r9_arm,
- gpr_r10_arm, gpr_r11_arm, gpr_r12_arm, gpr_sp_arm, gpr_lr_arm,
- gpr_pc_arm, gpr_cpsr_arm,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) ==
- k_num_gpr_registers_arm,
- "g_gpr_regnums_arm has wrong number of register infos");
-
-// arm floating point registers.
-static const uint32_t g_fpu_regnums_arm[] = {
- fpu_s0_arm, fpu_s1_arm, fpu_s2_arm, fpu_s3_arm, fpu_s4_arm,
- fpu_s5_arm, fpu_s6_arm, fpu_s7_arm, fpu_s8_arm, fpu_s9_arm,
- fpu_s10_arm, fpu_s11_arm, fpu_s12_arm, fpu_s13_arm, fpu_s14_arm,
- fpu_s15_arm, fpu_s16_arm, fpu_s17_arm, fpu_s18_arm, fpu_s19_arm,
- fpu_s20_arm, fpu_s21_arm, fpu_s22_arm, fpu_s23_arm, fpu_s24_arm,
- fpu_s25_arm, fpu_s26_arm, fpu_s27_arm, fpu_s28_arm, fpu_s29_arm,
- fpu_s30_arm, fpu_s31_arm, fpu_fpscr_arm, fpu_d0_arm, fpu_d1_arm,
- fpu_d2_arm, fpu_d3_arm, fpu_d4_arm, fpu_d5_arm, fpu_d6_arm,
- fpu_d7_arm, fpu_d8_arm, fpu_d9_arm, fpu_d10_arm, fpu_d11_arm,
- fpu_d12_arm, fpu_d13_arm, fpu_d14_arm, fpu_d15_arm, fpu_d16_arm,
- fpu_d17_arm, fpu_d18_arm, fpu_d19_arm, fpu_d20_arm, fpu_d21_arm,
- fpu_d22_arm, fpu_d23_arm, fpu_d24_arm, fpu_d25_arm, fpu_d26_arm,
- fpu_d27_arm, fpu_d28_arm, fpu_d29_arm, fpu_d30_arm, fpu_d31_arm,
- fpu_q0_arm, fpu_q1_arm, fpu_q2_arm, fpu_q3_arm, fpu_q4_arm,
- fpu_q5_arm, fpu_q6_arm, fpu_q7_arm, fpu_q8_arm, fpu_q9_arm,
- fpu_q10_arm, fpu_q11_arm, fpu_q12_arm, fpu_q13_arm, fpu_q14_arm,
- fpu_q15_arm,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) ==
- k_num_fpr_registers_arm,
- "g_fpu_regnums_arm has wrong number of register infos");
-
-namespace {
-// Number of register sets provided by this context.
-enum { k_num_register_sets = 2 };
-}
-
-// Register sets for arm.
-static const RegisterSet g_reg_sets_arm[k_num_register_sets] = {
- {"General Purpose Registers", "gpr", k_num_gpr_registers_arm,
- g_gpr_regnums_arm},
- {"Floating Point Registers", "fpu", k_num_fpr_registers_arm,
- g_fpu_regnums_arm}};
-
-#if defined(__arm__)
-
-std::unique_ptr<NativeRegisterContextLinux>
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
- return llvm::make_unique<NativeRegisterContextLinux_arm>(target_arch,
- native_thread);
-}
-
-#endif // defined(__arm__)
-
-NativeRegisterContextLinux_arm::NativeRegisterContextLinux_arm(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
- : NativeRegisterContextLinux(native_thread,
- new RegisterInfoPOSIX_arm(target_arch)) {
- switch (target_arch.GetMachine()) {
- case llvm::Triple::arm:
- m_reg_info.num_registers = k_num_registers_arm;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_arm;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_arm;
- m_reg_info.last_gpr = k_last_gpr_arm;
- m_reg_info.first_fpr = k_first_fpr_arm;
- m_reg_info.last_fpr = k_last_fpr_arm;
- m_reg_info.first_fpr_v = fpu_s0_arm;
- m_reg_info.last_fpr_v = fpu_s31_arm;
- m_reg_info.gpr_flags = gpr_cpsr_arm;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
-
- ::memset(&m_fpr, 0, sizeof(m_fpr));
- ::memset(&m_gpr_arm, 0, sizeof(m_gpr_arm));
- ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
- ::memset(&m_hbr_regs, 0, sizeof(m_hbr_regs));
-
- // 16 is just a maximum value, query hardware for actual watchpoint count
- m_max_hwp_supported = 16;
- m_max_hbp_supported = 16;
- m_refresh_hwdebug_info = true;
-}
-
-uint32_t NativeRegisterContextLinux_arm::GetRegisterSetCount() const {
- return k_num_register_sets;
-}
-
-uint32_t NativeRegisterContextLinux_arm::GetUserRegisterCount() const {
- uint32_t count = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
- count += g_reg_sets_arm[set_index].num_registers;
- return count;
-}
-
-const RegisterSet *
-NativeRegisterContextLinux_arm::GetRegisterSet(uint32_t set_index) const {
- if (set_index < k_num_register_sets)
- return &g_reg_sets_arm[set_index];
-
- return nullptr;
-}
-
-Status
-NativeRegisterContextLinux_arm::ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) {
- Status error;
-
- if (!reg_info) {
- error.SetErrorString("reg_info NULL");
- return error;
- }
-
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
-
- if (IsFPR(reg)) {
- error = ReadFPR();
- if (error.Fail())
- return error;
- } else {
- uint32_t full_reg = reg;
- bool is_subreg = reg_info->invalidate_regs &&
- (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
-
- if (is_subreg) {
- // Read the full aligned 64-bit register.
- full_reg = reg_info->invalidate_regs[0];
- }
-
- error = ReadRegisterRaw(full_reg, reg_value);
-
- if (error.Success()) {
- // If our read was not aligned (for ah,bh,ch,dh), shift our returned
- // value one byte to the right.
- if (is_subreg && (reg_info->byte_offset & 0x1))
- reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
-
- // If our return byte size was greater than the return value reg size,
- // then use the type specified by reg_info rather than the uint64_t
- // default
- if (reg_value.GetByteSize() > reg_info->byte_size)
- reg_value.SetType(reg_info);
- }
- return error;
- }
-
- // Get pointer to m_fpr variable and set the data from it.
- uint32_t fpr_offset = CalculateFprOffset(reg_info);
- assert(fpr_offset < sizeof m_fpr);
- uint8_t *src = (uint8_t *)&m_fpr + fpr_offset;
- switch (reg_info->byte_size) {
- case 2:
- reg_value.SetUInt16(*(uint16_t *)src);
- break;
- case 4:
- reg_value.SetUInt32(*(uint32_t *)src);
- break;
- case 8:
- reg_value.SetUInt64(*(uint64_t *)src);
- break;
- case 16:
- reg_value.SetBytes(src, 16, GetByteOrder());
- break;
- default:
- assert(false && "Unhandled data size.");
- error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
- reg_info->byte_size);
- break;
- }
-
- return error;
-}
-
-Status
-NativeRegisterContextLinux_arm::WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &reg_value) {
- if (!reg_info)
- return Status("reg_info NULL");
-
- const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg_index == LLDB_INVALID_REGNUM)
- return Status("no lldb regnum for %s", reg_info && reg_info->name
- ? reg_info->name
- : "<unknown register>");
-
- if (IsGPR(reg_index))
- return WriteRegisterRaw(reg_index, reg_value);
-
- if (IsFPR(reg_index)) {
- // Get pointer to m_fpr variable and set the data to it.
- uint32_t fpr_offset = CalculateFprOffset(reg_info);
- assert(fpr_offset < sizeof m_fpr);
- uint8_t *dst = (uint8_t *)&m_fpr + fpr_offset;
- switch (reg_info->byte_size) {
- case 2:
- *(uint16_t *)dst = reg_value.GetAsUInt16();
- break;
- case 4:
- *(uint32_t *)dst = reg_value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = reg_value.GetAsUInt64();
- break;
- default:
- assert(false && "Unhandled data size.");
- return Status("unhandled register data size %" PRIu32,
- reg_info->byte_size);
- }
-
- Status error = WriteFPR();
- if (error.Fail())
- return error;
-
- return Status();
- }
-
- return Status("failed - register wasn't recognized to be a GPR or an FPR, "
- "write strategy unknown");
-}
-
-Status NativeRegisterContextLinux_arm::ReadAllRegisterValues(
- lldb::DataBufferSP &data_sp) {
- Status error;
-
- data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
- if (!data_sp)
- return Status("failed to allocate DataBufferHeap instance of size %" PRIu64,
- (uint64_t)REG_CONTEXT_SIZE);
-
- error = ReadGPR();
- if (error.Fail())
- return error;
-
- error = ReadFPR();
- if (error.Fail())
- return error;
-
- uint8_t *dst = data_sp->GetBytes();
- if (dst == nullptr) {
- error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
- " returned a null pointer",
- (uint64_t)REG_CONTEXT_SIZE);
- return error;
- }
-
- ::memcpy(dst, &m_gpr_arm, GetGPRSize());
- dst += GetGPRSize();
- ::memcpy(dst, &m_fpr, sizeof(m_fpr));
-
- return error;
-}
-
-Status NativeRegisterContextLinux_arm::WriteAllRegisterValues(
- const lldb::DataBufferSP &data_sp) {
- Status error;
-
- if (!data_sp) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided",
- __FUNCTION__);
- return error;
- }
-
- if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched "
- "data size, expected %" PRIu64 ", actual %" PRIu64,
- __FUNCTION__, (uint64_t)REG_CONTEXT_SIZE, data_sp->GetByteSize());
- return error;
- }
-
- uint8_t *src = data_sp->GetBytes();
- if (src == nullptr) {
- error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s "
- "DataBuffer::GetBytes() returned a null "
- "pointer",
- __FUNCTION__);
- return error;
- }
- ::memcpy(&m_gpr_arm, src, GetRegisterInfoInterface().GetGPRSize());
-
- error = WriteGPR();
- if (error.Fail())
- return error;
-
- src += GetRegisterInfoInterface().GetGPRSize();
- ::memcpy(&m_fpr, src, sizeof(m_fpr));
-
- error = WriteFPR();
- if (error.Fail())
- return error;
-
- return error;
-}
-
-bool NativeRegisterContextLinux_arm::IsGPR(unsigned reg) const {
- return reg <= m_reg_info.last_gpr; // GPR's come first.
-}
-
-bool NativeRegisterContextLinux_arm::IsFPR(unsigned reg) const {
- return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
-}
-
-uint32_t NativeRegisterContextLinux_arm::NumSupportedHardwareBreakpoints() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
-
- if (log)
- log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
-
- Status error;
-
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return 0;
-
- LLDB_LOG(log, "{0}", m_max_hbp_supported);
- return m_max_hbp_supported;
-}
-
-uint32_t
-NativeRegisterContextLinux_arm::SetHardwareBreakpoint(lldb::addr_t addr,
- size_t size) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
- LLDB_LOG(log, "addr: {0:x}, size: {1:x}", addr, size);
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
-
- uint32_t control_value = 0, bp_index = 0;
-
- // Setup address and control values.
- // Use size to get a hint of arm vs thumb modes.
- switch (size) {
- case 2:
- control_value = (0x3 << 5) | 7;
- addr &= ~1;
- break;
- case 4:
- control_value = (0xfu << 5) | 7;
- addr &= ~3;
- break;
- default:
- return LLDB_INVALID_INDEX32;
- }
-
- // Iterate over stored breakpoints and find a free bp_index
- bp_index = LLDB_INVALID_INDEX32;
- for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
- if ((m_hbr_regs[i].control & 1) == 0) {
- bp_index = i; // Mark last free slot
- } else if (m_hbr_regs[i].address == addr) {
- return LLDB_INVALID_INDEX32; // We do not support duplicate breakpoints.
- }
- }
-
- if (bp_index == LLDB_INVALID_INDEX32)
- return LLDB_INVALID_INDEX32;
-
- // Update breakpoint in local cache
- m_hbr_regs[bp_index].real_addr = addr;
- m_hbr_regs[bp_index].address = addr;
- m_hbr_regs[bp_index].control = control_value;
-
- // PTRACE call to set corresponding hardware breakpoint register.
- error = WriteHardwareDebugRegs(eDREGTypeBREAK, bp_index);
-
- if (error.Fail()) {
- m_hbr_regs[bp_index].address = 0;
- m_hbr_regs[bp_index].control &= ~1;
-
- return LLDB_INVALID_INDEX32;
- }
-
- return bp_index;
-}
-
-bool NativeRegisterContextLinux_arm::ClearHardwareBreakpoint(uint32_t hw_idx) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
- LLDB_LOG(log, "hw_idx: {0}", hw_idx);
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return false;
-
- if (hw_idx >= m_max_hbp_supported)
- return false;
-
- // Create a backup we can revert to in case of failure.
- lldb::addr_t tempAddr = m_hbr_regs[hw_idx].address;
- uint32_t tempControl = m_hbr_regs[hw_idx].control;
-
- m_hbr_regs[hw_idx].control &= ~1;
- m_hbr_regs[hw_idx].address = 0;
-
- // PTRACE call to clear corresponding hardware breakpoint register.
- error = WriteHardwareDebugRegs(eDREGTypeBREAK, hw_idx);
-
- if (error.Fail()) {
- m_hbr_regs[hw_idx].control = tempControl;
- m_hbr_regs[hw_idx].address = tempAddr;
-
- return false;
- }
-
- return true;
-}
-
-Status NativeRegisterContextLinux_arm::GetHardwareBreakHitIndex(
- uint32_t &bp_index, lldb::addr_t trap_addr) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
-
- if (log)
- log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-
- lldb::addr_t break_addr;
-
- for (bp_index = 0; bp_index < m_max_hbp_supported; ++bp_index) {
- break_addr = m_hbr_regs[bp_index].address;
-
- if ((m_hbr_regs[bp_index].control & 0x1) && (trap_addr == break_addr)) {
- m_hbr_regs[bp_index].hit_addr = trap_addr;
- return Status();
- }
- }
-
- bp_index = LLDB_INVALID_INDEX32;
- return Status();
-}
-
-Status NativeRegisterContextLinux_arm::ClearAllHardwareBreakpoints() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
-
- if (log)
- log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__);
-
- Status error;
-
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return error;
-
- lldb::addr_t tempAddr = 0;
- uint32_t tempControl = 0;
-
- for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
- if (m_hbr_regs[i].control & 0x01) {
- // Create a backup we can revert to in case of failure.
- tempAddr = m_hbr_regs[i].address;
- tempControl = m_hbr_regs[i].control;
-
- // Clear breakpoints in local cache
- m_hbr_regs[i].control &= ~1;
- m_hbr_regs[i].address = 0;
-
- // Ptrace call to update hardware debug registers
- error = WriteHardwareDebugRegs(eDREGTypeBREAK, i);
-
- if (error.Fail()) {
- m_hbr_regs[i].control = tempControl;
- m_hbr_regs[i].address = tempAddr;
-
- return error;
- }
- }
- }
-
- return Status();
-}
-
-uint32_t NativeRegisterContextLinux_arm::NumSupportedHardwareWatchpoints() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return 0;
-
- LLDB_LOG(log, "{0}", m_max_hwp_supported);
- return m_max_hwp_supported;
-}
-
-uint32_t NativeRegisterContextLinux_arm::SetHardwareWatchpoint(
- lldb::addr_t addr, size_t size, uint32_t watch_flags) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "addr: {0:x}, size: {1:x} watch_flags: {2:x}", addr, size,
- watch_flags);
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
-
- uint32_t control_value = 0, wp_index = 0, addr_word_offset = 0, byte_mask = 0;
- lldb::addr_t real_addr = addr;
-
- // Check if we are setting watchpoint other than read/write/access Also
- // update watchpoint flag to match Arm write-read bit configuration.
- switch (watch_flags) {
- case 1:
- watch_flags = 2;
- break;
- case 2:
- watch_flags = 1;
- break;
- case 3:
- break;
- default:
- return LLDB_INVALID_INDEX32;
- }
-
- // Can't watch zero bytes
- // Can't watch more than 4 bytes per WVR/WCR pair
-
- if (size == 0 || size > 4)
- return LLDB_INVALID_INDEX32;
-
- // Check 4-byte alignment for hardware watchpoint target address. Below is a
- // hack to recalculate address and size in order to make sure we can watch
- // non 4-byte alligned addresses as well.
- if (addr & 0x03) {
- uint8_t watch_mask = (addr & 0x03) + size;
-
- if (watch_mask > 0x04)
- return LLDB_INVALID_INDEX32;
- else if (watch_mask <= 0x02)
- size = 2;
- else if (watch_mask <= 0x04)
- size = 4;
-
- addr = addr & (~0x03);
- }
-
- // We can only watch up to four bytes that follow a 4 byte aligned address
- // per watchpoint register pair, so make sure we can properly encode this.
- addr_word_offset = addr % 4;
- byte_mask = ((1u << size) - 1u) << addr_word_offset;
-
- // Check if we need multiple watchpoint register
- if (byte_mask > 0xfu)
- return LLDB_INVALID_INDEX32;
-
- // Setup control value
- // Make the byte_mask into a valid Byte Address Select mask
- control_value = byte_mask << 5;
-
- // Turn on appropriate watchpoint flags read or write
- control_value |= (watch_flags << 3);
-
- // Enable this watchpoint and make it stop in privileged or user mode;
- control_value |= 7;
-
- // Make sure bits 1:0 are clear in our address
- addr &= ~((lldb::addr_t)3);
-
- // Iterate over stored watchpoints and find a free wp_index
- wp_index = LLDB_INVALID_INDEX32;
- for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
- if ((m_hwp_regs[i].control & 1) == 0) {
- wp_index = i; // Mark last free slot
- } else if (m_hwp_regs[i].address == addr) {
- return LLDB_INVALID_INDEX32; // We do not support duplicate watchpoints.
- }
- }
-
- if (wp_index == LLDB_INVALID_INDEX32)
- return LLDB_INVALID_INDEX32;
-
- // Update watchpoint in local cache
- m_hwp_regs[wp_index].real_addr = real_addr;
- m_hwp_regs[wp_index].address = addr;
- m_hwp_regs[wp_index].control = control_value;
-
- // PTRACE call to set corresponding watchpoint register.
- error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index);
-
- if (error.Fail()) {
- m_hwp_regs[wp_index].address = 0;
- m_hwp_regs[wp_index].control &= ~1;
-
- return LLDB_INVALID_INDEX32;
- }
-
- return wp_index;
-}
-
-bool NativeRegisterContextLinux_arm::ClearHardwareWatchpoint(
- uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return false;
-
- if (wp_index >= m_max_hwp_supported)
- return false;
-
- // Create a backup we can revert to in case of failure.
- lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
- uint32_t tempControl = m_hwp_regs[wp_index].control;
-
- // Update watchpoint in local cache
- m_hwp_regs[wp_index].control &= ~1;
- m_hwp_regs[wp_index].address = 0;
-
- // Ptrace call to update hardware debug registers
- error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index);
-
- if (error.Fail()) {
- m_hwp_regs[wp_index].control = tempControl;
- m_hwp_regs[wp_index].address = tempAddr;
-
- return false;
- }
-
- return true;
-}
-
-Status NativeRegisterContextLinux_arm::ClearAllHardwareWatchpoints() {
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return error;
-
- lldb::addr_t tempAddr = 0;
- uint32_t tempControl = 0;
-
- for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
- if (m_hwp_regs[i].control & 0x01) {
- // Create a backup we can revert to in case of failure.
- tempAddr = m_hwp_regs[i].address;
- tempControl = m_hwp_regs[i].control;
-
- // Clear watchpoints in local cache
- m_hwp_regs[i].control &= ~1;
- m_hwp_regs[i].address = 0;
-
- // Ptrace call to update hardware debug registers
- error = WriteHardwareDebugRegs(eDREGTypeWATCH, i);
-
- if (error.Fail()) {
- m_hwp_regs[i].control = tempControl;
- m_hwp_regs[i].address = tempAddr;
-
- return error;
- }
- }
- }
-
- return Status();
-}
-
-uint32_t NativeRegisterContextLinux_arm::GetWatchpointSize(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- switch ((m_hwp_regs[wp_index].control >> 5) & 0x0f) {
- case 0x01:
- return 1;
- case 0x03:
- return 2;
- case 0x07:
- return 3;
- case 0x0f:
- return 4;
- default:
- return 0;
- }
-}
-bool NativeRegisterContextLinux_arm::WatchpointIsEnabled(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- if ((m_hwp_regs[wp_index].control & 0x1) == 0x1)
- return true;
- else
- return false;
-}
-
-Status
-NativeRegisterContextLinux_arm::GetWatchpointHitIndex(uint32_t &wp_index,
- lldb::addr_t trap_addr) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}, trap_addr: {1:x}", wp_index, trap_addr);
-
- uint32_t watch_size;
- lldb::addr_t watch_addr;
-
- for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index) {
- watch_size = GetWatchpointSize(wp_index);
- watch_addr = m_hwp_regs[wp_index].address;
-
- if (WatchpointIsEnabled(wp_index) && trap_addr >= watch_addr &&
- trap_addr < watch_addr + watch_size) {
- m_hwp_regs[wp_index].hit_addr = trap_addr;
- return Status();
- }
- }
-
- wp_index = LLDB_INVALID_INDEX32;
- return Status();
-}
-
-lldb::addr_t
-NativeRegisterContextLinux_arm::GetWatchpointAddress(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- if (wp_index >= m_max_hwp_supported)
- return LLDB_INVALID_ADDRESS;
-
- if (WatchpointIsEnabled(wp_index))
- return m_hwp_regs[wp_index].real_addr;
- else
- return LLDB_INVALID_ADDRESS;
-}
-
-lldb::addr_t
-NativeRegisterContextLinux_arm::GetWatchpointHitAddress(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- if (wp_index >= m_max_hwp_supported)
- return LLDB_INVALID_ADDRESS;
-
- if (WatchpointIsEnabled(wp_index))
- return m_hwp_regs[wp_index].hit_addr;
- else
- return LLDB_INVALID_ADDRESS;
-}
-
-Status NativeRegisterContextLinux_arm::ReadHardwareDebugInfo() {
- Status error;
-
- if (!m_refresh_hwdebug_info) {
- return Status();
- }
-
- unsigned int cap_val;
-
- error = NativeProcessLinux::PtraceWrapper(PTRACE_GETHBPREGS, m_thread.GetID(),
- nullptr, &cap_val,
- sizeof(unsigned int));
-
- if (error.Fail())
- return error;
-
- m_max_hwp_supported = (cap_val >> 8) & 0xff;
- m_max_hbp_supported = cap_val & 0xff;
- m_refresh_hwdebug_info = false;
-
- return error;
-}
-
-Status NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(int hwbType,
- int hwb_index) {
- Status error;
-
- lldb::addr_t *addr_buf;
- uint32_t *ctrl_buf;
-
- if (hwbType == eDREGTypeWATCH) {
- addr_buf = &m_hwp_regs[hwb_index].address;
- ctrl_buf = &m_hwp_regs[hwb_index].control;
-
- error = NativeProcessLinux::PtraceWrapper(
- PTRACE_SETHBPREGS, m_thread.GetID(),
- (PTRACE_TYPE_ARG3)(intptr_t) - ((hwb_index << 1) + 1), addr_buf,
- sizeof(unsigned int));
-
- if (error.Fail())
- return error;
-
- error = NativeProcessLinux::PtraceWrapper(
- PTRACE_SETHBPREGS, m_thread.GetID(),
- (PTRACE_TYPE_ARG3)(intptr_t) - ((hwb_index << 1) + 2), ctrl_buf,
- sizeof(unsigned int));
- } else {
- addr_buf = &m_hbr_regs[hwb_index].address;
- ctrl_buf = &m_hbr_regs[hwb_index].control;
-
- error = NativeProcessLinux::PtraceWrapper(
- PTRACE_SETHBPREGS, m_thread.GetID(),
- (PTRACE_TYPE_ARG3)(intptr_t)((hwb_index << 1) + 1), addr_buf,
- sizeof(unsigned int));
-
- if (error.Fail())
- return error;
-
- error = NativeProcessLinux::PtraceWrapper(
- PTRACE_SETHBPREGS, m_thread.GetID(),
- (PTRACE_TYPE_ARG3)(intptr_t)((hwb_index << 1) + 2), ctrl_buf,
- sizeof(unsigned int));
- }
-
- return error;
-}
-
-uint32_t NativeRegisterContextLinux_arm::CalculateFprOffset(
- const RegisterInfo *reg_info) const {
- return reg_info->byte_offset -
- GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset;
-}
-
-Status NativeRegisterContextLinux_arm::DoReadRegisterValue(
- uint32_t offset, const char *reg_name, uint32_t size,
- RegisterValue &value) {
- // PTRACE_PEEKUSER don't work in the aarch64 linux kernel used on android
- // devices (always return "Bad address"). To avoid using PTRACE_PEEKUSER we
- // read out the full GPR register set instead. This approach is about 4 times
- // slower but the performance overhead is negligible in comparision to
- // processing time in lldb-server.
- assert(offset % 4 == 0 && "Try to write a register with unaligned offset");
- if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm))
- return Status("Register isn't fit into the size of the GPR area");
-
- Status error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm));
- if (error.Fail())
- return error;
-
- value.SetUInt32(m_gpr_arm[offset / sizeof(uint32_t)]);
- return Status();
-}
-
-Status NativeRegisterContextLinux_arm::DoWriteRegisterValue(
- uint32_t offset, const char *reg_name, const RegisterValue &value) {
- // PTRACE_POKEUSER don't work in the aarch64 linux kernel used on android
- // devices (always return "Bad address"). To avoid using PTRACE_POKEUSER we
- // read out the full GPR register set, modify the requested register and
- // write it back. This approach is about 4 times slower but the performance
- // overhead is negligible in comparision to processing time in lldb-server.
- assert(offset % 4 == 0 && "Try to write a register with unaligned offset");
- if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm))
- return Status("Register isn't fit into the size of the GPR area");
-
- Status error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm));
- if (error.Fail())
- return error;
-
- uint32_t reg_value = value.GetAsUInt32();
- // As precaution for an undefined behavior encountered while setting PC we
- // will clear thumb bit of new PC if we are already in thumb mode; that is
- // CPSR thumb mode bit is set.
- if (offset / sizeof(uint32_t) == gpr_pc_arm) {
- // Check if we are already in thumb mode and thumb bit of current PC is
- // read out to be zero and thumb bit of next PC is read out to be one.
- if ((m_gpr_arm[gpr_cpsr_arm] & 0x20) && !(m_gpr_arm[gpr_pc_arm] & 0x01) &&
- (value.GetAsUInt32() & 0x01)) {
- reg_value &= (~1ull);
- }
- }
-
- m_gpr_arm[offset / sizeof(uint32_t)] = reg_value;
- return DoWriteGPR(m_gpr_arm, sizeof(m_gpr_arm));
-}
-
-Status NativeRegisterContextLinux_arm::DoReadGPR(void *buf, size_t buf_size) {
-#ifdef __arm__
- return NativeRegisterContextLinux::DoReadGPR(buf, buf_size);
-#else // __aarch64__
- struct iovec ioVec;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
-
- return ReadRegisterSet(&ioVec, buf_size, NT_PRSTATUS);
-#endif // __arm__
-}
-
-Status NativeRegisterContextLinux_arm::DoWriteGPR(void *buf, size_t buf_size) {
-#ifdef __arm__
- return NativeRegisterContextLinux::DoWriteGPR(buf, buf_size);
-#else // __aarch64__
- struct iovec ioVec;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
-
- return WriteRegisterSet(&ioVec, buf_size, NT_PRSTATUS);
-#endif // __arm__
-}
-
-Status NativeRegisterContextLinux_arm::DoReadFPR(void *buf, size_t buf_size) {
-#ifdef __arm__
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETVFPREGS, m_thread.GetID(),
- nullptr, buf, buf_size);
-#else // __aarch64__
- struct iovec ioVec;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
-
- return ReadRegisterSet(&ioVec, buf_size, NT_ARM_VFP);
-#endif // __arm__
-}
-
-Status NativeRegisterContextLinux_arm::DoWriteFPR(void *buf, size_t buf_size) {
-#ifdef __arm__
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETVFPREGS, m_thread.GetID(),
- nullptr, buf, buf_size);
-#else // __aarch64__
- struct iovec ioVec;
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
-
- return WriteRegisterSet(&ioVec, buf_size, NT_ARM_VFP);
-#endif // __arm__
-}
-
-#endif // defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
deleted file mode 100644
index d0b068550a9ee..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
+++ /dev/null
@@ -1,169 +0,0 @@
-//===-- NativeRegisterContextLinux_arm.h ---------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
-
-#ifndef lldb_NativeRegisterContextLinux_arm_h
-#define lldb_NativeRegisterContextLinux_arm_h
-
-#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
-#include "Plugins/Process/Utility/lldb-arm-register-enums.h"
-
-namespace lldb_private {
-namespace process_linux {
-
-class NativeProcessLinux;
-
-class NativeRegisterContextLinux_arm : public NativeRegisterContextLinux {
-public:
- NativeRegisterContextLinux_arm(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread);
-
- uint32_t GetRegisterSetCount() const override;
-
- const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
-
- uint32_t GetUserRegisterCount() const override;
-
- Status ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) override;
-
- Status WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &reg_value) override;
-
- Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- //------------------------------------------------------------------
- // Hardware breakpoints/watchpoint management functions
- //------------------------------------------------------------------
-
- uint32_t NumSupportedHardwareBreakpoints() override;
-
- uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
-
- bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
-
- Status ClearAllHardwareBreakpoints() override;
-
- Status GetHardwareBreakHitIndex(uint32_t &bp_index,
- lldb::addr_t trap_addr) override;
-
- uint32_t NumSupportedHardwareWatchpoints() override;
-
- uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
- uint32_t watch_flags) override;
-
- bool ClearHardwareWatchpoint(uint32_t hw_index) override;
-
- Status ClearAllHardwareWatchpoints() override;
-
- Status GetWatchpointHitIndex(uint32_t &wp_index,
- lldb::addr_t trap_addr) override;
-
- lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
-
- lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
-
- uint32_t GetWatchpointSize(uint32_t wp_index);
-
- bool WatchpointIsEnabled(uint32_t wp_index);
-
- // Debug register type select
- enum DREGType { eDREGTypeWATCH = 0, eDREGTypeBREAK };
-
-protected:
- Status DoReadRegisterValue(uint32_t offset, const char *reg_name,
- uint32_t size, RegisterValue &value) override;
-
- Status DoWriteRegisterValue(uint32_t offset, const char *reg_name,
- const RegisterValue &value) override;
-
- Status DoReadGPR(void *buf, size_t buf_size) override;
-
- Status DoWriteGPR(void *buf, size_t buf_size) override;
-
- Status DoReadFPR(void *buf, size_t buf_size) override;
-
- Status DoWriteFPR(void *buf, size_t buf_size) override;
-
- void *GetGPRBuffer() override { return &m_gpr_arm; }
-
- void *GetFPRBuffer() override { return &m_fpr; }
-
- size_t GetFPRSize() override { return sizeof(m_fpr); }
-
-private:
- struct RegInfo {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
-
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
-
- uint32_t first_fpr_v;
- uint32_t last_fpr_v;
-
- uint32_t gpr_flags;
- };
-
- struct QReg {
- uint8_t bytes[16];
- };
-
- struct FPU {
- union {
- uint32_t s[32];
- uint64_t d[32];
- QReg q[16]; // the 128-bit NEON registers
- } floats;
- uint32_t fpscr;
- };
-
- uint32_t m_gpr_arm[k_num_gpr_registers_arm];
- RegInfo m_reg_info;
- FPU m_fpr;
-
- // Debug register info for hardware breakpoints and watchpoints management.
- struct DREG {
- lldb::addr_t address; // Breakpoint/watchpoint address value.
- lldb::addr_t hit_addr; // Address at which last watchpoint trigger exception
- // occurred.
- lldb::addr_t real_addr; // Address value that should cause target to stop.
- uint32_t control; // Breakpoint/watchpoint control value.
- uint32_t refcount; // Serves as enable/disable and reference counter.
- };
-
- struct DREG m_hbr_regs[16]; // Arm native linux hardware breakpoints
- struct DREG m_hwp_regs[16]; // Arm native linux hardware watchpoints
-
- uint32_t m_max_hwp_supported;
- uint32_t m_max_hbp_supported;
- bool m_refresh_hwdebug_info;
-
- bool IsGPR(unsigned reg) const;
-
- bool IsFPR(unsigned reg) const;
-
- Status ReadHardwareDebugInfo();
-
- Status WriteHardwareDebugRegs(int hwbType, int hwb_index);
-
- uint32_t CalculateFprOffset(const RegisterInfo *reg_info) const;
-};
-
-} // namespace process_linux
-} // namespace lldb_private
-
-#endif // #ifndef lldb_NativeRegisterContextLinux_arm_h
-
-#endif // defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
deleted file mode 100644
index 9a392edbe9ef3..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ /dev/null
@@ -1,985 +0,0 @@
-//===-- NativeRegisterContextLinux_arm64.cpp --------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__arm64__) || defined(__aarch64__)
-
-#include "NativeRegisterContextLinux_arm.h"
-#include "NativeRegisterContextLinux_arm64.h"
-
-
-#include "lldb/Host/common/NativeProcessProtocol.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Status.h"
-
-#include "Plugins/Process/Linux/NativeProcessLinux.h"
-#include "Plugins/Process/Linux/Procfs.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
-
-// System includes - They have to be included after framework includes because
-// they define some macros which collide with variable names in other modules
-#include <sys/socket.h>
-// NT_PRSTATUS and NT_FPREGSET definition
-#include <elf.h>
-// user_hwdebug_state definition
-#include <asm/ptrace.h>
-
-#define REG_CONTEXT_SIZE (GetGPRSize() + GetFPRSize())
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::process_linux;
-
-// ARM64 general purpose registers.
-static const uint32_t g_gpr_regnums_arm64[] = {
- gpr_x0_arm64, gpr_x1_arm64, gpr_x2_arm64, gpr_x3_arm64,
- gpr_x4_arm64, gpr_x5_arm64, gpr_x6_arm64, gpr_x7_arm64,
- gpr_x8_arm64, gpr_x9_arm64, gpr_x10_arm64, gpr_x11_arm64,
- gpr_x12_arm64, gpr_x13_arm64, gpr_x14_arm64, gpr_x15_arm64,
- gpr_x16_arm64, gpr_x17_arm64, gpr_x18_arm64, gpr_x19_arm64,
- gpr_x20_arm64, gpr_x21_arm64, gpr_x22_arm64, gpr_x23_arm64,
- gpr_x24_arm64, gpr_x25_arm64, gpr_x26_arm64, gpr_x27_arm64,
- gpr_x28_arm64, gpr_fp_arm64, gpr_lr_arm64, gpr_sp_arm64,
- gpr_pc_arm64, gpr_cpsr_arm64, gpr_w0_arm64, gpr_w1_arm64,
- gpr_w2_arm64, gpr_w3_arm64, gpr_w4_arm64, gpr_w5_arm64,
- gpr_w6_arm64, gpr_w7_arm64, gpr_w8_arm64, gpr_w9_arm64,
- gpr_w10_arm64, gpr_w11_arm64, gpr_w12_arm64, gpr_w13_arm64,
- gpr_w14_arm64, gpr_w15_arm64, gpr_w16_arm64, gpr_w17_arm64,
- gpr_w18_arm64, gpr_w19_arm64, gpr_w20_arm64, gpr_w21_arm64,
- gpr_w22_arm64, gpr_w23_arm64, gpr_w24_arm64, gpr_w25_arm64,
- gpr_w26_arm64, gpr_w27_arm64, gpr_w28_arm64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) -
- 1) == k_num_gpr_registers_arm64,
- "g_gpr_regnums_arm64 has wrong number of register infos");
-
-// ARM64 floating point registers.
-static const uint32_t g_fpu_regnums_arm64[] = {
- fpu_v0_arm64, fpu_v1_arm64, fpu_v2_arm64, fpu_v3_arm64,
- fpu_v4_arm64, fpu_v5_arm64, fpu_v6_arm64, fpu_v7_arm64,
- fpu_v8_arm64, fpu_v9_arm64, fpu_v10_arm64, fpu_v11_arm64,
- fpu_v12_arm64, fpu_v13_arm64, fpu_v14_arm64, fpu_v15_arm64,
- fpu_v16_arm64, fpu_v17_arm64, fpu_v18_arm64, fpu_v19_arm64,
- fpu_v20_arm64, fpu_v21_arm64, fpu_v22_arm64, fpu_v23_arm64,
- fpu_v24_arm64, fpu_v25_arm64, fpu_v26_arm64, fpu_v27_arm64,
- fpu_v28_arm64, fpu_v29_arm64, fpu_v30_arm64, fpu_v31_arm64,
- fpu_s0_arm64, fpu_s1_arm64, fpu_s2_arm64, fpu_s3_arm64,
- fpu_s4_arm64, fpu_s5_arm64, fpu_s6_arm64, fpu_s7_arm64,
- fpu_s8_arm64, fpu_s9_arm64, fpu_s10_arm64, fpu_s11_arm64,
- fpu_s12_arm64, fpu_s13_arm64, fpu_s14_arm64, fpu_s15_arm64,
- fpu_s16_arm64, fpu_s17_arm64, fpu_s18_arm64, fpu_s19_arm64,
- fpu_s20_arm64, fpu_s21_arm64, fpu_s22_arm64, fpu_s23_arm64,
- fpu_s24_arm64, fpu_s25_arm64, fpu_s26_arm64, fpu_s27_arm64,
- fpu_s28_arm64, fpu_s29_arm64, fpu_s30_arm64, fpu_s31_arm64,
-
- fpu_d0_arm64, fpu_d1_arm64, fpu_d2_arm64, fpu_d3_arm64,
- fpu_d4_arm64, fpu_d5_arm64, fpu_d6_arm64, fpu_d7_arm64,
- fpu_d8_arm64, fpu_d9_arm64, fpu_d10_arm64, fpu_d11_arm64,
- fpu_d12_arm64, fpu_d13_arm64, fpu_d14_arm64, fpu_d15_arm64,
- fpu_d16_arm64, fpu_d17_arm64, fpu_d18_arm64, fpu_d19_arm64,
- fpu_d20_arm64, fpu_d21_arm64, fpu_d22_arm64, fpu_d23_arm64,
- fpu_d24_arm64, fpu_d25_arm64, fpu_d26_arm64, fpu_d27_arm64,
- fpu_d28_arm64, fpu_d29_arm64, fpu_d30_arm64, fpu_d31_arm64,
- fpu_fpsr_arm64, fpu_fpcr_arm64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) -
- 1) == k_num_fpr_registers_arm64,
- "g_fpu_regnums_arm64 has wrong number of register infos");
-
-namespace {
-// Number of register sets provided by this context.
-enum { k_num_register_sets = 2 };
-}
-
-// Register sets for ARM64.
-static const RegisterSet g_reg_sets_arm64[k_num_register_sets] = {
- {"General Purpose Registers", "gpr", k_num_gpr_registers_arm64,
- g_gpr_regnums_arm64},
- {"Floating Point Registers", "fpu", k_num_fpr_registers_arm64,
- g_fpu_regnums_arm64}};
-
-std::unique_ptr<NativeRegisterContextLinux>
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
- switch (target_arch.GetMachine()) {
- case llvm::Triple::arm:
- return llvm::make_unique<NativeRegisterContextLinux_arm>(target_arch,
- native_thread);
- case llvm::Triple::aarch64:
- return llvm::make_unique<NativeRegisterContextLinux_arm64>(target_arch,
- native_thread);
- default:
- llvm_unreachable("have no register context for architecture");
- }
-}
-
-NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
- : NativeRegisterContextLinux(native_thread,
- new RegisterInfoPOSIX_arm64(target_arch)) {
- switch (target_arch.GetMachine()) {
- case llvm::Triple::aarch64:
- m_reg_info.num_registers = k_num_registers_arm64;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64;
- m_reg_info.last_gpr = k_last_gpr_arm64;
- m_reg_info.first_fpr = k_first_fpr_arm64;
- m_reg_info.last_fpr = k_last_fpr_arm64;
- m_reg_info.first_fpr_v = fpu_v0_arm64;
- m_reg_info.last_fpr_v = fpu_v31_arm64;
- m_reg_info.gpr_flags = gpr_cpsr_arm64;
- break;
- default:
- llvm_unreachable("Unhandled target architecture.");
- break;
- }
-
- ::memset(&m_fpr, 0, sizeof(m_fpr));
- ::memset(&m_gpr_arm64, 0, sizeof(m_gpr_arm64));
- ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
- ::memset(&m_hbr_regs, 0, sizeof(m_hbr_regs));
-
- // 16 is just a maximum value, query hardware for actual watchpoint count
- m_max_hwp_supported = 16;
- m_max_hbp_supported = 16;
- m_refresh_hwdebug_info = true;
-}
-
-uint32_t NativeRegisterContextLinux_arm64::GetRegisterSetCount() const {
- return k_num_register_sets;
-}
-
-const RegisterSet *
-NativeRegisterContextLinux_arm64::GetRegisterSet(uint32_t set_index) const {
- if (set_index < k_num_register_sets)
- return &g_reg_sets_arm64[set_index];
-
- return nullptr;
-}
-
-uint32_t NativeRegisterContextLinux_arm64::GetUserRegisterCount() const {
- uint32_t count = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
- count += g_reg_sets_arm64[set_index].num_registers;
- return count;
-}
-
-Status
-NativeRegisterContextLinux_arm64::ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) {
- Status error;
-
- if (!reg_info) {
- error.SetErrorString("reg_info NULL");
- return error;
- }
-
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
-
- if (IsFPR(reg)) {
- error = ReadFPR();
- if (error.Fail())
- return error;
- } else {
- uint32_t full_reg = reg;
- bool is_subreg = reg_info->invalidate_regs &&
- (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
-
- if (is_subreg) {
- // Read the full aligned 64-bit register.
- full_reg = reg_info->invalidate_regs[0];
- }
-
- error = ReadRegisterRaw(full_reg, reg_value);
-
- if (error.Success()) {
- // If our read was not aligned (for ah,bh,ch,dh), shift our returned
- // value one byte to the right.
- if (is_subreg && (reg_info->byte_offset & 0x1))
- reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
-
- // If our return byte size was greater than the return value reg size,
- // then use the type specified by reg_info rather than the uint64_t
- // default
- if (reg_value.GetByteSize() > reg_info->byte_size)
- reg_value.SetType(reg_info);
- }
- return error;
- }
-
- // Get pointer to m_fpr variable and set the data from it.
- uint32_t fpr_offset = CalculateFprOffset(reg_info);
- assert(fpr_offset < sizeof m_fpr);
- uint8_t *src = (uint8_t *)&m_fpr + fpr_offset;
- reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
- eByteOrderLittle, error);
-
- return error;
-}
-
-Status NativeRegisterContextLinux_arm64::WriteRegister(
- const RegisterInfo *reg_info, const RegisterValue &reg_value) {
- if (!reg_info)
- return Status("reg_info NULL");
-
- const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg_index == LLDB_INVALID_REGNUM)
- return Status("no lldb regnum for %s", reg_info && reg_info->name
- ? reg_info->name
- : "<unknown register>");
-
- if (IsGPR(reg_index))
- return WriteRegisterRaw(reg_index, reg_value);
-
- if (IsFPR(reg_index)) {
- // Get pointer to m_fpr variable and set the data to it.
- uint32_t fpr_offset = CalculateFprOffset(reg_info);
- assert(fpr_offset < sizeof m_fpr);
- uint8_t *dst = (uint8_t *)&m_fpr + fpr_offset;
- switch (reg_info->byte_size) {
- case 2:
- *(uint16_t *)dst = reg_value.GetAsUInt16();
- break;
- case 4:
- *(uint32_t *)dst = reg_value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = reg_value.GetAsUInt64();
- break;
- default:
- assert(false && "Unhandled data size.");
- return Status("unhandled register data size %" PRIu32,
- reg_info->byte_size);
- }
-
- Status error = WriteFPR();
- if (error.Fail())
- return error;
-
- return Status();
- }
-
- return Status("failed - register wasn't recognized to be a GPR or an FPR, "
- "write strategy unknown");
-}
-
-Status NativeRegisterContextLinux_arm64::ReadAllRegisterValues(
- lldb::DataBufferSP &data_sp) {
- Status error;
-
- data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
- if (!data_sp)
- return Status("failed to allocate DataBufferHeap instance of size %" PRIu64,
- REG_CONTEXT_SIZE);
-
- error = ReadGPR();
- if (error.Fail())
- return error;
-
- error = ReadFPR();
- if (error.Fail())
- return error;
-
- uint8_t *dst = data_sp->GetBytes();
- if (dst == nullptr) {
- error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
- " returned a null pointer",
- REG_CONTEXT_SIZE);
- return error;
- }
-
- ::memcpy(dst, &m_gpr_arm64, GetGPRSize());
- dst += GetGPRSize();
- ::memcpy(dst, &m_fpr, sizeof(m_fpr));
-
- return error;
-}
-
-Status NativeRegisterContextLinux_arm64::WriteAllRegisterValues(
- const lldb::DataBufferSP &data_sp) {
- Status error;
-
- if (!data_sp) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided",
- __FUNCTION__);
- return error;
- }
-
- if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched "
- "data size, expected %" PRIu64 ", actual %" PRIu64,
- __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
- return error;
- }
-
- uint8_t *src = data_sp->GetBytes();
- if (src == nullptr) {
- error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s "
- "DataBuffer::GetBytes() returned a null "
- "pointer",
- __FUNCTION__);
- return error;
- }
- ::memcpy(&m_gpr_arm64, src, GetRegisterInfoInterface().GetGPRSize());
-
- error = WriteGPR();
- if (error.Fail())
- return error;
-
- src += GetRegisterInfoInterface().GetGPRSize();
- ::memcpy(&m_fpr, src, sizeof(m_fpr));
-
- error = WriteFPR();
- if (error.Fail())
- return error;
-
- return error;
-}
-
-bool NativeRegisterContextLinux_arm64::IsGPR(unsigned reg) const {
- return reg <= m_reg_info.last_gpr; // GPR's come first.
-}
-
-bool NativeRegisterContextLinux_arm64::IsFPR(unsigned reg) const {
- return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
-}
-
-uint32_t NativeRegisterContextLinux_arm64::NumSupportedHardwareBreakpoints() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
-
- if (log)
- log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-
- Status error;
-
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return 0;
-
- return m_max_hbp_supported;
-}
-
-uint32_t
-NativeRegisterContextLinux_arm64::SetHardwareBreakpoint(lldb::addr_t addr,
- size_t size) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
- LLDB_LOG(log, "addr: {0:x}, size: {1:x}", addr, size);
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
-
- uint32_t control_value = 0, bp_index = 0;
-
- // Check if size has a valid hardware breakpoint length.
- if (size != 4)
- return LLDB_INVALID_INDEX32; // Invalid size for a AArch64 hardware
- // breakpoint
-
- // Check 4-byte alignment for hardware breakpoint target address.
- if (addr & 0x03)
- return LLDB_INVALID_INDEX32; // Invalid address, should be 4-byte aligned.
-
- // Setup control value
- control_value = 0;
- control_value |= ((1 << size) - 1) << 5;
- control_value |= (2 << 1) | 1;
-
- // Iterate over stored breakpoints and find a free bp_index
- bp_index = LLDB_INVALID_INDEX32;
- for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
- if ((m_hbr_regs[i].control & 1) == 0) {
- bp_index = i; // Mark last free slot
- } else if (m_hbr_regs[i].address == addr) {
- return LLDB_INVALID_INDEX32; // We do not support duplicate breakpoints.
- }
- }
-
- if (bp_index == LLDB_INVALID_INDEX32)
- return LLDB_INVALID_INDEX32;
-
- // Update breakpoint in local cache
- m_hbr_regs[bp_index].real_addr = addr;
- m_hbr_regs[bp_index].address = addr;
- m_hbr_regs[bp_index].control = control_value;
-
- // PTRACE call to set corresponding hardware breakpoint register.
- error = WriteHardwareDebugRegs(eDREGTypeBREAK);
-
- if (error.Fail()) {
- m_hbr_regs[bp_index].address = 0;
- m_hbr_regs[bp_index].control &= ~1;
-
- return LLDB_INVALID_INDEX32;
- }
-
- return bp_index;
-}
-
-bool NativeRegisterContextLinux_arm64::ClearHardwareBreakpoint(
- uint32_t hw_idx) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
- LLDB_LOG(log, "hw_idx: {0}", hw_idx);
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return false;
-
- if (hw_idx >= m_max_hbp_supported)
- return false;
-
- // Create a backup we can revert to in case of failure.
- lldb::addr_t tempAddr = m_hbr_regs[hw_idx].address;
- uint32_t tempControl = m_hbr_regs[hw_idx].control;
-
- m_hbr_regs[hw_idx].control &= ~1;
- m_hbr_regs[hw_idx].address = 0;
-
- // PTRACE call to clear corresponding hardware breakpoint register.
- error = WriteHardwareDebugRegs(eDREGTypeBREAK);
-
- if (error.Fail()) {
- m_hbr_regs[hw_idx].control = tempControl;
- m_hbr_regs[hw_idx].address = tempAddr;
-
- return false;
- }
-
- return true;
-}
-
-Status NativeRegisterContextLinux_arm64::GetHardwareBreakHitIndex(
- uint32_t &bp_index, lldb::addr_t trap_addr) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
-
- if (log)
- log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-
- lldb::addr_t break_addr;
-
- for (bp_index = 0; bp_index < m_max_hbp_supported; ++bp_index) {
- break_addr = m_hbr_regs[bp_index].address;
-
- if ((m_hbr_regs[bp_index].control & 0x1) && (trap_addr == break_addr)) {
- m_hbr_regs[bp_index].hit_addr = trap_addr;
- return Status();
- }
- }
-
- bp_index = LLDB_INVALID_INDEX32;
- return Status();
-}
-
-Status NativeRegisterContextLinux_arm64::ClearAllHardwareBreakpoints() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
-
- if (log)
- log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__);
-
- Status error;
-
- // Read hardware breakpoint and watchpoint information.
- error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return error;
-
- lldb::addr_t tempAddr = 0;
- uint32_t tempControl = 0;
-
- for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
- if (m_hbr_regs[i].control & 0x01) {
- // Create a backup we can revert to in case of failure.
- tempAddr = m_hbr_regs[i].address;
- tempControl = m_hbr_regs[i].control;
-
- // Clear watchpoints in local cache
- m_hbr_regs[i].control &= ~1;
- m_hbr_regs[i].address = 0;
-
- // Ptrace call to update hardware debug registers
- error = WriteHardwareDebugRegs(eDREGTypeBREAK);
-
- if (error.Fail()) {
- m_hbr_regs[i].control = tempControl;
- m_hbr_regs[i].address = tempAddr;
-
- return error;
- }
- }
- }
-
- return Status();
-}
-
-uint32_t NativeRegisterContextLinux_arm64::NumSupportedHardwareWatchpoints() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return 0;
-
- LLDB_LOG(log, "{0}", m_max_hwp_supported);
- return m_max_hwp_supported;
-}
-
-uint32_t NativeRegisterContextLinux_arm64::SetHardwareWatchpoint(
- lldb::addr_t addr, size_t size, uint32_t watch_flags) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "addr: {0:x}, size: {1:x} watch_flags: {2:x}", addr, size,
- watch_flags);
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
-
- uint32_t control_value = 0, wp_index = 0;
- lldb::addr_t real_addr = addr;
-
- // Check if we are setting watchpoint other than read/write/access Also
- // update watchpoint flag to match AArch64 write-read bit configuration.
- switch (watch_flags) {
- case 1:
- watch_flags = 2;
- break;
- case 2:
- watch_flags = 1;
- break;
- case 3:
- break;
- default:
- return LLDB_INVALID_INDEX32;
- }
-
- // Check if size has a valid hardware watchpoint length.
- if (size != 1 && size != 2 && size != 4 && size != 8)
- return LLDB_INVALID_INDEX32;
-
- // Check 8-byte alignment for hardware watchpoint target address. Below is a
- // hack to recalculate address and size in order to make sure we can watch
- // non 8-byte alligned addresses as well.
- if (addr & 0x07) {
- uint8_t watch_mask = (addr & 0x07) + size;
-
- if (watch_mask > 0x08)
- return LLDB_INVALID_INDEX32;
- else if (watch_mask <= 0x02)
- size = 2;
- else if (watch_mask <= 0x04)
- size = 4;
- else
- size = 8;
-
- addr = addr & (~0x07);
- }
-
- // Setup control value
- control_value = watch_flags << 3;
- control_value |= ((1 << size) - 1) << 5;
- control_value |= (2 << 1) | 1;
-
- // Iterate over stored watchpoints and find a free wp_index
- wp_index = LLDB_INVALID_INDEX32;
- for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
- if ((m_hwp_regs[i].control & 1) == 0) {
- wp_index = i; // Mark last free slot
- } else if (m_hwp_regs[i].address == addr) {
- return LLDB_INVALID_INDEX32; // We do not support duplicate watchpoints.
- }
- }
-
- if (wp_index == LLDB_INVALID_INDEX32)
- return LLDB_INVALID_INDEX32;
-
- // Update watchpoint in local cache
- m_hwp_regs[wp_index].real_addr = real_addr;
- m_hwp_regs[wp_index].address = addr;
- m_hwp_regs[wp_index].control = control_value;
-
- // PTRACE call to set corresponding watchpoint register.
- error = WriteHardwareDebugRegs(eDREGTypeWATCH);
-
- if (error.Fail()) {
- m_hwp_regs[wp_index].address = 0;
- m_hwp_regs[wp_index].control &= ~1;
-
- return LLDB_INVALID_INDEX32;
- }
-
- return wp_index;
-}
-
-bool NativeRegisterContextLinux_arm64::ClearHardwareWatchpoint(
- uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return false;
-
- if (wp_index >= m_max_hwp_supported)
- return false;
-
- // Create a backup we can revert to in case of failure.
- lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
- uint32_t tempControl = m_hwp_regs[wp_index].control;
-
- // Update watchpoint in local cache
- m_hwp_regs[wp_index].control &= ~1;
- m_hwp_regs[wp_index].address = 0;
-
- // Ptrace call to update hardware debug registers
- error = WriteHardwareDebugRegs(eDREGTypeWATCH);
-
- if (error.Fail()) {
- m_hwp_regs[wp_index].control = tempControl;
- m_hwp_regs[wp_index].address = tempAddr;
-
- return false;
- }
-
- return true;
-}
-
-Status NativeRegisterContextLinux_arm64::ClearAllHardwareWatchpoints() {
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return error;
-
- lldb::addr_t tempAddr = 0;
- uint32_t tempControl = 0;
-
- for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
- if (m_hwp_regs[i].control & 0x01) {
- // Create a backup we can revert to in case of failure.
- tempAddr = m_hwp_regs[i].address;
- tempControl = m_hwp_regs[i].control;
-
- // Clear watchpoints in local cache
- m_hwp_regs[i].control &= ~1;
- m_hwp_regs[i].address = 0;
-
- // Ptrace call to update hardware debug registers
- error = WriteHardwareDebugRegs(eDREGTypeWATCH);
-
- if (error.Fail()) {
- m_hwp_regs[i].control = tempControl;
- m_hwp_regs[i].address = tempAddr;
-
- return error;
- }
- }
- }
-
- return Status();
-}
-
-uint32_t
-NativeRegisterContextLinux_arm64::GetWatchpointSize(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- switch ((m_hwp_regs[wp_index].control >> 5) & 0xff) {
- case 0x01:
- return 1;
- case 0x03:
- return 2;
- case 0x0f:
- return 4;
- case 0xff:
- return 8;
- default:
- return 0;
- }
-}
-bool NativeRegisterContextLinux_arm64::WatchpointIsEnabled(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- if ((m_hwp_regs[wp_index].control & 0x1) == 0x1)
- return true;
- else
- return false;
-}
-
-Status NativeRegisterContextLinux_arm64::GetWatchpointHitIndex(
- uint32_t &wp_index, lldb::addr_t trap_addr) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}, trap_addr: {1:x}", wp_index, trap_addr);
-
- uint32_t watch_size;
- lldb::addr_t watch_addr;
-
- for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index) {
- watch_size = GetWatchpointSize(wp_index);
- watch_addr = m_hwp_regs[wp_index].address;
-
- if (WatchpointIsEnabled(wp_index) && trap_addr >= watch_addr &&
- trap_addr < watch_addr + watch_size) {
- m_hwp_regs[wp_index].hit_addr = trap_addr;
- return Status();
- }
- }
-
- wp_index = LLDB_INVALID_INDEX32;
- return Status();
-}
-
-lldb::addr_t
-NativeRegisterContextLinux_arm64::GetWatchpointAddress(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- if (wp_index >= m_max_hwp_supported)
- return LLDB_INVALID_ADDRESS;
-
- if (WatchpointIsEnabled(wp_index))
- return m_hwp_regs[wp_index].real_addr;
- else
- return LLDB_INVALID_ADDRESS;
-}
-
-lldb::addr_t
-NativeRegisterContextLinux_arm64::GetWatchpointHitAddress(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- if (wp_index >= m_max_hwp_supported)
- return LLDB_INVALID_ADDRESS;
-
- if (WatchpointIsEnabled(wp_index))
- return m_hwp_regs[wp_index].hit_addr;
- else
- return LLDB_INVALID_ADDRESS;
-}
-
-Status NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() {
- if (!m_refresh_hwdebug_info) {
- return Status();
- }
-
- ::pid_t tid = m_thread.GetID();
-
- int regset = NT_ARM_HW_WATCH;
- struct iovec ioVec;
- struct user_hwdebug_state dreg_state;
- Status error;
-
- ioVec.iov_base = &dreg_state;
- ioVec.iov_len = sizeof(dreg_state);
- error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset,
- &ioVec, ioVec.iov_len);
-
- if (error.Fail())
- return error;
-
- m_max_hwp_supported = dreg_state.dbg_info & 0xff;
-
- regset = NT_ARM_HW_BREAK;
- error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset,
- &ioVec, ioVec.iov_len);
-
- if (error.Fail())
- return error;
-
- m_max_hbp_supported = dreg_state.dbg_info & 0xff;
- m_refresh_hwdebug_info = false;
-
- return error;
-}
-
-Status NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(int hwbType) {
- struct iovec ioVec;
- struct user_hwdebug_state dreg_state;
- Status error;
-
- memset(&dreg_state, 0, sizeof(dreg_state));
- ioVec.iov_base = &dreg_state;
-
- if (hwbType == eDREGTypeWATCH) {
- hwbType = NT_ARM_HW_WATCH;
- ioVec.iov_len = sizeof(dreg_state.dbg_info) + sizeof(dreg_state.pad) +
- (sizeof(dreg_state.dbg_regs[0]) * m_max_hwp_supported);
-
- for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
- dreg_state.dbg_regs[i].addr = m_hwp_regs[i].address;
- dreg_state.dbg_regs[i].ctrl = m_hwp_regs[i].control;
- }
- } else {
- hwbType = NT_ARM_HW_BREAK;
- ioVec.iov_len = sizeof(dreg_state.dbg_info) + sizeof(dreg_state.pad) +
- (sizeof(dreg_state.dbg_regs[0]) * m_max_hbp_supported);
-
- for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
- dreg_state.dbg_regs[i].addr = m_hbr_regs[i].address;
- dreg_state.dbg_regs[i].ctrl = m_hbr_regs[i].control;
- }
- }
-
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
- &hwbType, &ioVec, ioVec.iov_len);
-}
-
-Status NativeRegisterContextLinux_arm64::DoReadRegisterValue(
- uint32_t offset, const char *reg_name, uint32_t size,
- RegisterValue &value) {
- Status error;
- if (offset > sizeof(struct user_pt_regs)) {
- offset -= sizeof(struct user_pt_regs);
- if (offset > sizeof(struct user_fpsimd_state)) {
- error.SetErrorString("invalid offset value");
- return error;
- }
- elf_fpregset_t regs;
- int regset = NT_FPREGSET;
- struct iovec ioVec;
-
- ioVec.iov_base = &regs;
- ioVec.iov_len = sizeof regs;
- error = NativeProcessLinux::PtraceWrapper(
- PTRACE_GETREGSET, m_thread.GetID(), &regset, &ioVec, sizeof regs);
- if (error.Success()) {
- value.SetBytes((void *)(((unsigned char *)(&regs)) + offset), 16,
- m_thread.GetProcess().GetByteOrder());
- }
- } else {
- elf_gregset_t regs;
- int regset = NT_PRSTATUS;
- struct iovec ioVec;
-
- ioVec.iov_base = &regs;
- ioVec.iov_len = sizeof regs;
- error = NativeProcessLinux::PtraceWrapper(
- PTRACE_GETREGSET, m_thread.GetID(), &regset, &ioVec, sizeof regs);
- if (error.Success()) {
- value.SetBytes((void *)(((unsigned char *)(regs)) + offset), 8,
- m_thread.GetProcess().GetByteOrder());
- }
- }
- return error;
-}
-
-Status NativeRegisterContextLinux_arm64::DoWriteRegisterValue(
- uint32_t offset, const char *reg_name, const RegisterValue &value) {
- Status error;
- ::pid_t tid = m_thread.GetID();
- if (offset > sizeof(struct user_pt_regs)) {
- offset -= sizeof(struct user_pt_regs);
- if (offset > sizeof(struct user_fpsimd_state)) {
- error.SetErrorString("invalid offset value");
- return error;
- }
- elf_fpregset_t regs;
- int regset = NT_FPREGSET;
- struct iovec ioVec;
-
- ioVec.iov_base = &regs;
- ioVec.iov_len = sizeof regs;
- error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset,
- &ioVec, sizeof regs);
-
- if (error.Success()) {
- ::memcpy((void *)(((unsigned char *)(&regs)) + offset), value.GetBytes(),
- 16);
- error = NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, tid, &regset,
- &ioVec, sizeof regs);
- }
- } else {
- elf_gregset_t regs;
- int regset = NT_PRSTATUS;
- struct iovec ioVec;
-
- ioVec.iov_base = &regs;
- ioVec.iov_len = sizeof regs;
- error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset,
- &ioVec, sizeof regs);
- if (error.Success()) {
- ::memcpy((void *)(((unsigned char *)(&regs)) + offset), value.GetBytes(),
- 8);
- error = NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, tid, &regset,
- &ioVec, sizeof regs);
- }
- }
- return error;
-}
-
-Status NativeRegisterContextLinux_arm64::DoReadGPR(void *buf, size_t buf_size) {
- int regset = NT_PRSTATUS;
- struct iovec ioVec;
- Status error;
-
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(),
- &regset, &ioVec, buf_size);
-}
-
-Status NativeRegisterContextLinux_arm64::DoWriteGPR(void *buf,
- size_t buf_size) {
- int regset = NT_PRSTATUS;
- struct iovec ioVec;
- Status error;
-
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
- &regset, &ioVec, buf_size);
-}
-
-Status NativeRegisterContextLinux_arm64::DoReadFPR(void *buf, size_t buf_size) {
- int regset = NT_FPREGSET;
- struct iovec ioVec;
- Status error;
-
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(),
- &regset, &ioVec, buf_size);
-}
-
-Status NativeRegisterContextLinux_arm64::DoWriteFPR(void *buf,
- size_t buf_size) {
- int regset = NT_FPREGSET;
- struct iovec ioVec;
- Status error;
-
- ioVec.iov_base = buf;
- ioVec.iov_len = buf_size;
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
- &regset, &ioVec, buf_size);
-}
-
-uint32_t NativeRegisterContextLinux_arm64::CalculateFprOffset(
- const RegisterInfo *reg_info) const {
- return reg_info->byte_offset -
- GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset;
-}
-
-#endif // defined (__arm64__) || defined (__aarch64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
deleted file mode 100644
index c859d4249d053..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
+++ /dev/null
@@ -1,169 +0,0 @@
-//===-- NativeRegisterContextLinux_arm64.h ---------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__arm64__) || defined(__aarch64__)
-
-#ifndef lldb_NativeRegisterContextLinux_arm64_h
-#define lldb_NativeRegisterContextLinux_arm64_h
-
-#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
-#include "Plugins/Process/Utility/lldb-arm64-register-enums.h"
-
-namespace lldb_private {
-namespace process_linux {
-
-class NativeProcessLinux;
-
-class NativeRegisterContextLinux_arm64 : public NativeRegisterContextLinux {
-public:
- NativeRegisterContextLinux_arm64(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread);
-
- uint32_t GetRegisterSetCount() const override;
-
- uint32_t GetUserRegisterCount() const override;
-
- const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
-
- Status ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) override;
-
- Status WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &reg_value) override;
-
- Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- //------------------------------------------------------------------
- // Hardware breakpoints/watchpoint management functions
- //------------------------------------------------------------------
-
- uint32_t NumSupportedHardwareBreakpoints() override;
-
- uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
-
- bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
-
- Status ClearAllHardwareBreakpoints() override;
-
- Status GetHardwareBreakHitIndex(uint32_t &bp_index,
- lldb::addr_t trap_addr) override;
-
- uint32_t NumSupportedHardwareWatchpoints() override;
-
- uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
- uint32_t watch_flags) override;
-
- bool ClearHardwareWatchpoint(uint32_t hw_index) override;
-
- Status ClearAllHardwareWatchpoints() override;
-
- Status GetWatchpointHitIndex(uint32_t &wp_index,
- lldb::addr_t trap_addr) override;
-
- lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
-
- lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
-
- uint32_t GetWatchpointSize(uint32_t wp_index);
-
- bool WatchpointIsEnabled(uint32_t wp_index);
-
- // Debug register type select
- enum DREGType { eDREGTypeWATCH = 0, eDREGTypeBREAK };
-
-protected:
- Status DoReadRegisterValue(uint32_t offset, const char *reg_name,
- uint32_t size, RegisterValue &value) override;
-
- Status DoWriteRegisterValue(uint32_t offset, const char *reg_name,
- const RegisterValue &value) override;
-
- Status DoReadGPR(void *buf, size_t buf_size) override;
-
- Status DoWriteGPR(void *buf, size_t buf_size) override;
-
- Status DoReadFPR(void *buf, size_t buf_size) override;
-
- Status DoWriteFPR(void *buf, size_t buf_size) override;
-
- void *GetGPRBuffer() override { return &m_gpr_arm64; }
-
- void *GetFPRBuffer() override { return &m_fpr; }
-
- size_t GetFPRSize() override { return sizeof(m_fpr); }
-
-private:
- struct RegInfo {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
-
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
-
- uint32_t first_fpr_v;
- uint32_t last_fpr_v;
-
- uint32_t gpr_flags;
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct VReg {
- uint8_t bytes[16];
- };
-
- // based on RegisterContextDarwin_arm64.h
- struct FPU {
- VReg v[32];
- uint32_t fpsr;
- uint32_t fpcr;
- };
-
- uint64_t m_gpr_arm64[k_num_gpr_registers_arm64]; // 64-bit general purpose
- // registers.
- RegInfo m_reg_info;
- FPU m_fpr; // floating-point registers including extended register sets.
-
- // Debug register info for hardware breakpoints and watchpoints management.
- struct DREG {
- lldb::addr_t address; // Breakpoint/watchpoint address value.
- lldb::addr_t hit_addr; // Address at which last watchpoint trigger exception
- // occurred.
- lldb::addr_t real_addr; // Address value that should cause target to stop.
- uint32_t control; // Breakpoint/watchpoint control value.
- uint32_t refcount; // Serves as enable/disable and reference counter.
- };
-
- struct DREG m_hbr_regs[16]; // Arm native linux hardware breakpoints
- struct DREG m_hwp_regs[16]; // Arm native linux hardware watchpoints
-
- uint32_t m_max_hwp_supported;
- uint32_t m_max_hbp_supported;
- bool m_refresh_hwdebug_info;
-
- bool IsGPR(unsigned reg) const;
-
- bool IsFPR(unsigned reg) const;
-
- Status ReadHardwareDebugInfo();
-
- Status WriteHardwareDebugRegs(int hwbType);
-
- uint32_t CalculateFprOffset(const RegisterInfo *reg_info) const;
-};
-
-} // namespace process_linux
-} // namespace lldb_private
-
-#endif // #ifndef lldb_NativeRegisterContextLinux_arm64_h
-
-#endif // defined (__arm64__) || defined (__aarch64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
deleted file mode 100644
index d641056a04401..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
+++ /dev/null
@@ -1,1053 +0,0 @@
-//===-- NativeRegisterContextLinux_mips64.cpp ---------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__mips__)
-
-#include "NativeRegisterContextLinux_mips64.h"
-
-
-#include "Plugins/Process/Linux/NativeProcessLinux.h"
-#include "Plugins/Process/Linux/Procfs.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_mips.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_mips64.h"
-#include "lldb/Core/EmulateInstruction.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/LLDBAssert.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/lldb-enumerations.h"
-#include "lldb/lldb-private-enumerations.h"
-#define NT_MIPS_MSA 0x600
-#define CONFIG5_FRE (1 << 8)
-#define SR_FR (1 << 26)
-#define NUM_REGISTERS 32
-
-#include <asm/ptrace.h>
-#include <sys/ptrace.h>
-
-#ifndef PTRACE_GET_WATCH_REGS
-enum pt_watch_style { pt_watch_style_mips32, pt_watch_style_mips64 };
-struct mips32_watch_regs {
- uint32_t watchlo[8];
- uint16_t watchhi[8];
- uint16_t watch_masks[8];
- uint32_t num_valid;
-} __attribute__((aligned(8)));
-
-struct mips64_watch_regs {
- uint64_t watchlo[8];
- uint16_t watchhi[8];
- uint16_t watch_masks[8];
- uint32_t num_valid;
-} __attribute__((aligned(8)));
-
-struct pt_watch_regs {
- enum pt_watch_style style;
- union {
- struct mips32_watch_regs mips32;
- struct mips64_watch_regs mips64;
- };
-};
-
-#define PTRACE_GET_WATCH_REGS 0xd0
-#define PTRACE_SET_WATCH_REGS 0xd1
-#endif
-
-#define W (1 << 0)
-#define R (1 << 1)
-#define I (1 << 2)
-
-#define IRW (I | R | W)
-
-#ifndef PTRACE_GETREGSET
-#define PTRACE_GETREGSET 0x4204
-#endif
-struct pt_watch_regs default_watch_regs;
-
-using namespace lldb_private;
-using namespace lldb_private::process_linux;
-
-std::unique_ptr<NativeRegisterContextLinux>
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
- return llvm::make_unique<NativeRegisterContextLinux_mips64>(target_arch,
- native_thread);
-}
-
-#define REG_CONTEXT_SIZE \
- (GetRegisterInfoInterface().GetGPRSize() + sizeof(FPR_linux_mips) + \
- sizeof(MSA_linux_mips))
-
-// ----------------------------------------------------------------------------
-// NativeRegisterContextLinux_mips64 members.
-// ----------------------------------------------------------------------------
-
-static RegisterInfoInterface *
-CreateRegisterInfoInterface(const ArchSpec &target_arch) {
- if ((target_arch.GetMachine() == llvm::Triple::mips) ||
- (target_arch.GetMachine() == llvm::Triple::mipsel)) {
- // 32-bit hosts run with a RegisterContextLinux_mips context.
- return new RegisterContextLinux_mips(
- target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable());
- } else {
- return new RegisterContextLinux_mips64(
- target_arch, NativeRegisterContextLinux_mips64::IsMSAAvailable());
- }
-}
-
-NativeRegisterContextLinux_mips64::NativeRegisterContextLinux_mips64(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
- : NativeRegisterContextLinux(native_thread,
- CreateRegisterInfoInterface(target_arch)) {
- switch (target_arch.GetMachine()) {
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- m_reg_info.num_registers = k_num_registers_mips;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_mips;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_mips;
- m_reg_info.last_gpr = k_last_gpr_mips;
- m_reg_info.first_fpr = k_first_fpr_mips;
- m_reg_info.last_fpr = k_last_fpr_mips;
- m_reg_info.first_msa = k_first_msa_mips;
- m_reg_info.last_msa = k_last_msa_mips;
- break;
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- m_reg_info.num_registers = k_num_registers_mips64;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_mips64;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_mips64;
- m_reg_info.last_gpr = k_last_gpr_mips64;
- m_reg_info.first_fpr = k_first_fpr_mips64;
- m_reg_info.last_fpr = k_last_fpr_mips64;
- m_reg_info.first_msa = k_first_msa_mips64;
- m_reg_info.last_msa = k_last_msa_mips64;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
-
- // Initialize m_iovec to point to the buffer and buffer size using the
- // conventions of Berkeley style UIO structures, as required by PTRACE
- // extensions.
- m_iovec.iov_base = &m_msa;
- m_iovec.iov_len = sizeof(MSA_linux_mips);
-
- // init h/w watchpoint addr map
- for (int index = 0; index <= MAX_NUM_WP; index++)
- hw_addr_map[index] = LLDB_INVALID_ADDRESS;
-
- ::memset(&m_gpr, 0, sizeof(GPR_linux_mips));
- ::memset(&m_fpr, 0, sizeof(FPR_linux_mips));
- ::memset(&m_msa, 0, sizeof(MSA_linux_mips));
-}
-
-uint32_t NativeRegisterContextLinux_mips64::GetRegisterSetCount() const {
- switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el: {
- const auto context = static_cast<const RegisterContextLinux_mips64 &>
- (GetRegisterInfoInterface());
- return context.GetRegisterSetCount();
- }
- case llvm::Triple::mips:
- case llvm::Triple::mipsel: {
- const auto context = static_cast<const RegisterContextLinux_mips &>
- (GetRegisterInfoInterface());
- return context.GetRegisterSetCount();
- }
- default:
- llvm_unreachable("Unhandled target architecture.");
- }
-}
-
-lldb::addr_t NativeRegisterContextLinux_mips64::GetPCfromBreakpointLocation(
- lldb::addr_t fail_value) {
- Status error;
- RegisterValue pc_value;
- lldb::addr_t pc = fail_value;
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS));
- LLDB_LOG(log, "Reading PC from breakpoint location");
-
- // PC register is at index 34 of the register array
- const RegisterInfo *const pc_info_p = GetRegisterInfoAtIndex(gpr_pc_mips64);
-
- error = ReadRegister(pc_info_p, pc_value);
- if (error.Success()) {
- pc = pc_value.GetAsUInt64();
-
- // CAUSE register is at index 37 of the register array
- const RegisterInfo *const cause_info_p =
- GetRegisterInfoAtIndex(gpr_cause_mips64);
- RegisterValue cause_value;
-
- ReadRegister(cause_info_p, cause_value);
-
- uint64_t cause = cause_value.GetAsUInt64();
- LLDB_LOG(log, "PC {0:x} cause {1:x}", pc, cause);
-
- /*
- * The breakpoint might be in a delay slot. In this case PC points
- * to the delayed branch instruction rather then the instruction
- * in the delay slot. If the CAUSE.BD flag is set then adjust the
- * PC based on the size of the branch instruction.
- */
- if ((cause & (1 << 31)) != 0) {
- lldb::addr_t branch_delay = 0;
- branch_delay =
- 4; // FIXME - Adjust according to size of branch instruction at PC
- pc = pc + branch_delay;
- pc_value.SetUInt64(pc);
- WriteRegister(pc_info_p, pc_value);
- LLDB_LOG(log, "New PC {0:x}", pc);
- }
- }
-
- return pc;
-}
-
-const RegisterSet *
-NativeRegisterContextLinux_mips64::GetRegisterSet(uint32_t set_index) const {
- if (set_index >= GetRegisterSetCount())
- return nullptr;
-
- switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el: {
- const auto context = static_cast<const RegisterContextLinux_mips64 &>
- (GetRegisterInfoInterface());
- return context.GetRegisterSet(set_index);
- }
- case llvm::Triple::mips:
- case llvm::Triple::mipsel: {
- const auto context = static_cast<const RegisterContextLinux_mips &>
- (GetRegisterInfoInterface());
- return context.GetRegisterSet(set_index);
- }
- default:
- llvm_unreachable("Unhandled target architecture.");
- }
-}
-
-lldb_private::Status
-NativeRegisterContextLinux_mips64::ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) {
- Status error;
-
- if (!reg_info) {
- error.SetErrorString("reg_info NULL");
- return error;
- }
-
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- uint8_t byte_size = reg_info->byte_size;
- if (reg == LLDB_INVALID_REGNUM) {
- // This is likely an internal register for lldb use only and should not be
- // directly queried.
- error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
- "register, cannot read directly",
- reg_info->name);
- return error;
- }
-
- if (IsMSA(reg) && !IsMSAAvailable()) {
- error.SetErrorString("MSA not available on this processor");
- return error;
- }
-
- if (IsMSA(reg) || IsFPR(reg)) {
- uint8_t *src = nullptr;
- lldbassert(reg_info->byte_offset < sizeof(UserArea));
-
- error = ReadCP1();
-
- if (!error.Success()) {
- error.SetErrorString("failed to read co-processor 1 register");
- return error;
- }
-
- if (IsFPR(reg)) {
- if (IsFR0() && (byte_size != 4)) {
- byte_size = 4;
- uint8_t ptrace_index;
- ptrace_index = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
- src = ReturnFPOffset(ptrace_index, reg_info->byte_offset);
- } else
- src = (uint8_t *)&m_fpr + reg_info->byte_offset - sizeof(m_gpr);
- } else
- src = (uint8_t *)&m_msa + reg_info->byte_offset -
- (sizeof(m_gpr) + sizeof(m_fpr));
- switch (byte_size) {
- case 4:
- reg_value.SetUInt32(*(uint32_t *)src);
- break;
- case 8:
- reg_value.SetUInt64(*(uint64_t *)src);
- break;
- case 16:
- reg_value.SetBytes((const void *)src, 16, GetByteOrder());
- break;
- default:
- assert(false && "Unhandled data size.");
- error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
- reg_info->byte_size);
- break;
- }
- } else {
- error = ReadRegisterRaw(reg, reg_value);
- }
-
- return error;
-}
-
-lldb_private::Status NativeRegisterContextLinux_mips64::WriteRegister(
- const RegisterInfo *reg_info, const RegisterValue &reg_value) {
- Status error;
-
- assert(reg_info && "reg_info is null");
-
- const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
-
- if (reg_index == LLDB_INVALID_REGNUM)
- return Status("no lldb regnum for %s", reg_info && reg_info->name
- ? reg_info->name
- : "<unknown register>");
-
- if (IsMSA(reg_index) && !IsMSAAvailable()) {
- error.SetErrorString("MSA not available on this processor");
- return error;
- }
-
- if (IsFPR(reg_index) || IsMSA(reg_index)) {
- uint8_t *dst = nullptr;
- uint64_t *src = nullptr;
- uint8_t byte_size = reg_info->byte_size;
- lldbassert(reg_info->byte_offset < sizeof(UserArea));
-
- // Initialise the FP and MSA buffers by reading all co-processor 1
- // registers
- ReadCP1();
-
- if (IsFPR(reg_index)) {
- if (IsFR0() && (byte_size != 4)) {
- byte_size = 4;
- uint8_t ptrace_index;
- ptrace_index = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
- dst = ReturnFPOffset(ptrace_index, reg_info->byte_offset);
- } else
- dst = (uint8_t *)&m_fpr + reg_info->byte_offset - sizeof(m_gpr);
- } else
- dst = (uint8_t *)&m_msa + reg_info->byte_offset -
- (sizeof(m_gpr) + sizeof(m_fpr));
- switch (byte_size) {
- case 4:
- *(uint32_t *)dst = reg_value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = reg_value.GetAsUInt64();
- break;
- case 16:
- src = (uint64_t *)reg_value.GetBytes();
- *(uint64_t *)dst = *src;
- *(uint64_t *)(dst + 8) = *(src + 1);
- break;
- default:
- assert(false && "Unhandled data size.");
- error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
- reg_info->byte_size);
- break;
- }
- error = WriteCP1();
- if (!error.Success()) {
- error.SetErrorString("failed to write co-processor 1 register");
- return error;
- }
- } else {
- error = WriteRegisterRaw(reg_index, reg_value);
- }
-
- return error;
-}
-
-Status NativeRegisterContextLinux_mips64::ReadAllRegisterValues(
- lldb::DataBufferSP &data_sp) {
- Status error;
-
- data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
- if (!data_sp) {
- error.SetErrorStringWithFormat(
- "failed to allocate DataBufferHeap instance of size %" PRIu64,
- REG_CONTEXT_SIZE);
- return error;
- }
-
- error = ReadGPR();
- if (!error.Success()) {
- error.SetErrorString("ReadGPR() failed");
- return error;
- }
-
- error = ReadCP1();
- if (!error.Success()) {
- error.SetErrorString("ReadCP1() failed");
- return error;
- }
-
- uint8_t *dst = data_sp->GetBytes();
- if (dst == nullptr) {
- error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
- " returned a null pointer",
- REG_CONTEXT_SIZE);
- return error;
- }
-
- ::memcpy(dst, &m_gpr, GetRegisterInfoInterface().GetGPRSize());
- dst += GetRegisterInfoInterface().GetGPRSize();
-
- ::memcpy(dst, &m_fpr, GetFPRSize());
- dst += GetFPRSize();
-
- ::memcpy(dst, &m_msa, sizeof(MSA_linux_mips));
-
- return error;
-}
-
-Status NativeRegisterContextLinux_mips64::WriteAllRegisterValues(
- const lldb::DataBufferSP &data_sp) {
- Status error;
-
- if (!data_sp) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_mips64::%s invalid data_sp provided",
- __FUNCTION__);
- return error;
- }
-
- if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_mips64::%s data_sp contained mismatched "
- "data size, expected %" PRIu64 ", actual %" PRIu64,
- __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
- return error;
- }
-
- uint8_t *src = data_sp->GetBytes();
- if (src == nullptr) {
- error.SetErrorStringWithFormat("NativeRegisterContextLinux_mips64::%s "
- "DataBuffer::GetBytes() returned a null "
- "pointer",
- __FUNCTION__);
- return error;
- }
-
- ::memcpy(&m_gpr, src, GetRegisterInfoInterface().GetGPRSize());
- src += GetRegisterInfoInterface().GetGPRSize();
-
- ::memcpy(&m_fpr, src, GetFPRSize());
- src += GetFPRSize();
-
- ::memcpy(&m_msa, src, sizeof(MSA_linux_mips));
-
- error = WriteGPR();
- if (!error.Success()) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_mips64::%s WriteGPR() failed",
- __FUNCTION__);
- return error;
- }
-
- error = WriteCP1();
- if (!error.Success()) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_mips64::%s WriteCP1() failed",
- __FUNCTION__);
- return error;
- }
-
- return error;
-}
-
-Status NativeRegisterContextLinux_mips64::ReadCP1() {
- Status error;
-
- uint8_t *src = nullptr;
- uint8_t *dst = nullptr;
-
- lldb::ByteOrder byte_order = GetByteOrder();
-
- bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
-
- if (IsMSAAvailable()) {
- error = NativeRegisterContextLinux::ReadRegisterSet(
- &m_iovec, sizeof(MSA_linux_mips), NT_MIPS_MSA);
- src = (uint8_t *)&m_msa + (IsBigEndian * 8);
- dst = (uint8_t *)&m_fpr;
- for (int i = 0; i < NUM_REGISTERS; i++) {
- // Copy fp values from msa buffer fetched via ptrace
- *(uint64_t *)dst = *(uint64_t *)src;
- src = src + 16;
- dst = dst + 8;
- }
- m_fpr.fir = m_msa.fir;
- m_fpr.fcsr = m_msa.fcsr;
- m_fpr.config5 = m_msa.config5;
- } else {
- error = NativeRegisterContextLinux::ReadFPR();
- }
- return error;
-}
-
-uint8_t *
-NativeRegisterContextLinux_mips64::ReturnFPOffset(uint8_t reg_index,
- uint32_t byte_offset) {
-
- uint8_t *fp_buffer_ptr = nullptr;
- lldb::ByteOrder byte_order = GetByteOrder();
- bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
- if (reg_index % 2) {
- uint8_t offset_diff = (IsBigEndian) ? 8 : 4;
- fp_buffer_ptr =
- (uint8_t *)&m_fpr + byte_offset - offset_diff - sizeof(m_gpr);
- } else {
- fp_buffer_ptr =
- (uint8_t *)&m_fpr + byte_offset + 4 * (IsBigEndian) - sizeof(m_gpr);
- }
- return fp_buffer_ptr;
-}
-
-Status NativeRegisterContextLinux_mips64::WriteCP1() {
- Status error;
-
- uint8_t *src = nullptr;
- uint8_t *dst = nullptr;
-
- lldb::ByteOrder byte_order = GetByteOrder();
-
- bool IsBigEndian = (byte_order == lldb::eByteOrderBig);
-
- if (IsMSAAvailable()) {
- dst = (uint8_t *)&m_msa + (IsBigEndian * 8);
- src = (uint8_t *)&m_fpr;
- for (int i = 0; i < NUM_REGISTERS; i++) {
- // Copy fp values to msa buffer for ptrace
- *(uint64_t *)dst = *(uint64_t *)src;
- dst = dst + 16;
- src = src + 8;
- }
- m_msa.fir = m_fpr.fir;
- m_msa.fcsr = m_fpr.fcsr;
- m_msa.config5 = m_fpr.config5;
- error = NativeRegisterContextLinux::WriteRegisterSet(
- &m_iovec, sizeof(MSA_linux_mips), NT_MIPS_MSA);
- } else {
- error = NativeRegisterContextLinux::WriteFPR();
- }
-
- return error;
-}
-
-bool NativeRegisterContextLinux_mips64::IsFR0() {
- const RegisterInfo *const reg_info_p = GetRegisterInfoAtIndex(gpr_sr_mips64);
-
- RegisterValue reg_value;
- ReadRegister(reg_info_p, reg_value);
-
- uint64_t value = reg_value.GetAsUInt64();
-
- return (!(value & SR_FR));
-}
-
-bool NativeRegisterContextLinux_mips64::IsFRE() {
- const RegisterInfo *const reg_info_p =
- GetRegisterInfoAtIndex(gpr_config5_mips64);
-
- RegisterValue reg_value;
- ReadRegister(reg_info_p, reg_value);
-
- uint64_t config5 = reg_value.GetAsUInt64();
-
- return (config5 & CONFIG5_FRE);
-}
-
-bool NativeRegisterContextLinux_mips64::IsFPR(uint32_t reg_index) const {
- return (m_reg_info.first_fpr <= reg_index &&
- reg_index <= m_reg_info.last_fpr);
-}
-
-static uint32_t GetWatchHi(struct pt_watch_regs *regs, uint32_t index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- if (regs->style == pt_watch_style_mips32)
- return regs->mips32.watchhi[index];
- else if (regs->style == pt_watch_style_mips64)
- return regs->mips64.watchhi[index];
- LLDB_LOG(log, "Invalid watch register style");
- return 0;
-}
-
-static void SetWatchHi(struct pt_watch_regs *regs, uint32_t index,
- uint16_t value) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- if (regs->style == pt_watch_style_mips32)
- regs->mips32.watchhi[index] = value;
- else if (regs->style == pt_watch_style_mips64)
- regs->mips64.watchhi[index] = value;
- LLDB_LOG(log, "Invalid watch register style");
- return;
-}
-
-static lldb::addr_t GetWatchLo(struct pt_watch_regs *regs, uint32_t index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- if (regs->style == pt_watch_style_mips32)
- return regs->mips32.watchlo[index];
- else if (regs->style == pt_watch_style_mips64)
- return regs->mips64.watchlo[index];
- LLDB_LOG(log, "Invalid watch register style");
- return LLDB_INVALID_ADDRESS;
-}
-
-static void SetWatchLo(struct pt_watch_regs *regs, uint32_t index,
- uint64_t value) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- if (regs->style == pt_watch_style_mips32)
- regs->mips32.watchlo[index] = (uint32_t)value;
- else if (regs->style == pt_watch_style_mips64)
- regs->mips64.watchlo[index] = value;
- else
- LLDB_LOG(log, "Invalid watch register style");
-}
-
-static uint32_t GetIRWMask(struct pt_watch_regs *regs, uint32_t index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- if (regs->style == pt_watch_style_mips32)
- return regs->mips32.watch_masks[index] & IRW;
- else if (regs->style == pt_watch_style_mips64)
- return regs->mips64.watch_masks[index] & IRW;
- LLDB_LOG(log, "Invalid watch register style");
- return 0;
-}
-
-static uint32_t GetRegMask(struct pt_watch_regs *regs, uint32_t index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- if (regs->style == pt_watch_style_mips32)
- return regs->mips32.watch_masks[index] & ~IRW;
- else if (regs->style == pt_watch_style_mips64)
- return regs->mips64.watch_masks[index] & ~IRW;
- LLDB_LOG(log, "Invalid watch register style");
- return 0;
-}
-
-static lldb::addr_t GetRangeMask(lldb::addr_t mask) {
- lldb::addr_t mask_bit = 1;
- while (mask_bit < mask) {
- mask = mask | mask_bit;
- mask_bit <<= 1;
- }
- return mask;
-}
-
-static int GetVacantWatchIndex(struct pt_watch_regs *regs, lldb::addr_t addr,
- uint32_t size, uint32_t irw,
- uint32_t num_valid) {
- lldb::addr_t last_byte = addr + size - 1;
- lldb::addr_t mask = GetRangeMask(addr ^ last_byte) | IRW;
- lldb::addr_t base_addr = addr & ~mask;
-
- // Check if this address is already watched by previous watch points.
- lldb::addr_t lo;
- uint16_t hi;
- uint32_t vacant_watches = 0;
- for (uint32_t index = 0; index < num_valid; index++) {
- lo = GetWatchLo(regs, index);
- if (lo != 0 && irw == ((uint32_t)lo & irw)) {
- hi = GetWatchHi(regs, index) | IRW;
- lo &= ~(lldb::addr_t)hi;
- if (addr >= lo && last_byte <= (lo + hi))
- return index;
- } else
- vacant_watches++;
- }
-
- // Now try to find a vacant index
- if (vacant_watches > 0) {
- vacant_watches = 0;
- for (uint32_t index = 0; index < num_valid; index++) {
- lo = GetWatchLo(regs, index);
- if (lo == 0 && irw == (GetIRWMask(regs, index) & irw)) {
- if (mask <= (GetRegMask(regs, index) | IRW)) {
- // It fits, we can use it.
- SetWatchLo(regs, index, base_addr | irw);
- SetWatchHi(regs, index, mask & ~IRW);
- return index;
- } else {
- // It doesn't fit, but has the proper IRW capabilities
- vacant_watches++;
- }
- }
- }
-
- if (vacant_watches > 1) {
- // Split this watchpoint accross several registers
- struct pt_watch_regs regs_copy;
- regs_copy = *regs;
- lldb::addr_t break_addr;
- uint32_t segment_size;
- for (uint32_t index = 0; index < num_valid; index++) {
- lo = GetWatchLo(&regs_copy, index);
- hi = GetRegMask(&regs_copy, index) | IRW;
- if (lo == 0 && irw == (hi & irw)) {
- lo = addr & ~(lldb::addr_t)hi;
- break_addr = lo + hi + 1;
- if (break_addr >= addr + size)
- segment_size = size;
- else
- segment_size = break_addr - addr;
- mask = GetRangeMask(addr ^ (addr + segment_size - 1));
- SetWatchLo(&regs_copy, index, (addr & ~mask) | irw);
- SetWatchHi(&regs_copy, index, mask & ~IRW);
- if (break_addr >= addr + size) {
- *regs = regs_copy;
- return index;
- }
- size = addr + size - break_addr;
- addr = break_addr;
- }
- }
- }
- }
- return LLDB_INVALID_INDEX32;
-}
-
-bool NativeRegisterContextLinux_mips64::IsMSA(uint32_t reg_index) const {
- return (m_reg_info.first_msa <= reg_index &&
- reg_index <= m_reg_info.last_msa);
-}
-
-bool NativeRegisterContextLinux_mips64::IsMSAAvailable() {
- MSA_linux_mips msa_buf;
- unsigned int regset = NT_MIPS_MSA;
-
- Status error = NativeProcessLinux::PtraceWrapper(
- PTRACE_GETREGSET, Host::GetCurrentProcessID(),
- static_cast<void *>(&regset), &msa_buf, sizeof(MSA_linux_mips));
-
- if (error.Success() && msa_buf.mir) {
- return true;
- }
-
- return false;
-}
-
-Status NativeRegisterContextLinux_mips64::IsWatchpointHit(uint32_t wp_index,
- bool &is_hit) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Status("Watchpoint index out of range");
-
- // reading the current state of watch regs
- struct pt_watch_regs watch_readback;
- Status error = DoReadWatchPointRegisterValue(
- m_thread.GetID(), static_cast<void *>(&watch_readback));
-
- if (GetWatchHi(&watch_readback, wp_index) & (IRW)) {
- // clear hit flag in watchhi
- SetWatchHi(&watch_readback, wp_index,
- (GetWatchHi(&watch_readback, wp_index) & ~(IRW)));
- DoWriteWatchPointRegisterValue(m_thread.GetID(),
- static_cast<void *>(&watch_readback));
-
- is_hit = true;
- return error;
- }
- is_hit = false;
- return error;
-}
-
-Status NativeRegisterContextLinux_mips64::GetWatchpointHitIndex(
- uint32_t &wp_index, lldb::addr_t trap_addr) {
- uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
- for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
- bool is_hit;
- Status error = IsWatchpointHit(wp_index, is_hit);
- if (error.Fail()) {
- wp_index = LLDB_INVALID_INDEX32;
- } else if (is_hit) {
- return error;
- }
- }
- wp_index = LLDB_INVALID_INDEX32;
- return Status();
-}
-
-Status NativeRegisterContextLinux_mips64::IsWatchpointVacant(uint32_t wp_index,
- bool &is_vacant) {
- is_vacant = false;
- return Status("MIPS TODO: "
- "NativeRegisterContextLinux_mips64::IsWatchpointVacant not "
- "implemented");
-}
-
-bool NativeRegisterContextLinux_mips64::ClearHardwareWatchpoint(
- uint32_t wp_index) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return false;
-
- struct pt_watch_regs regs;
- // First reading the current state of watch regs
- DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
-
- if (regs.style == pt_watch_style_mips32) {
- regs.mips32.watchlo[wp_index] = default_watch_regs.mips32.watchlo[wp_index];
- regs.mips32.watchhi[wp_index] = default_watch_regs.mips32.watchhi[wp_index];
- regs.mips32.watch_masks[wp_index] =
- default_watch_regs.mips32.watch_masks[wp_index];
- } else // pt_watch_style_mips64
- {
- regs.mips64.watchlo[wp_index] = default_watch_regs.mips64.watchlo[wp_index];
- regs.mips64.watchhi[wp_index] = default_watch_regs.mips64.watchhi[wp_index];
- regs.mips64.watch_masks[wp_index] =
- default_watch_regs.mips64.watch_masks[wp_index];
- }
-
- Status error = DoWriteWatchPointRegisterValue(m_thread.GetID(),
- static_cast<void *>(&regs));
- if (!error.Fail()) {
- hw_addr_map[wp_index] = LLDB_INVALID_ADDRESS;
- return true;
- }
- return false;
-}
-
-Status NativeRegisterContextLinux_mips64::ClearAllHardwareWatchpoints() {
- return DoWriteWatchPointRegisterValue(
- m_thread.GetID(), static_cast<void *>(&default_watch_regs));
-}
-
-Status NativeRegisterContextLinux_mips64::SetHardwareWatchpointWithIndex(
- lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
- Status error;
- error.SetErrorString("MIPS TODO: "
- "NativeRegisterContextLinux_mips64::"
- "SetHardwareWatchpointWithIndex not implemented");
- return error;
-}
-
-uint32_t NativeRegisterContextLinux_mips64::SetHardwareWatchpoint(
- lldb::addr_t addr, size_t size, uint32_t watch_flags) {
- struct pt_watch_regs regs;
-
- // First reading the current state of watch regs
- DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
-
- // Try if a new watch point fits in this state
- int index = GetVacantWatchIndex(&regs, addr, size, watch_flags,
- NumSupportedHardwareWatchpoints());
-
- // New watchpoint doesn't fit
- if (index == LLDB_INVALID_INDEX32)
- return LLDB_INVALID_INDEX32;
-
- // It fits, so we go ahead with updating the state of watch regs
- DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
-
- // Storing exact address
- hw_addr_map[index] = addr;
- return index;
-}
-
-lldb::addr_t
-NativeRegisterContextLinux_mips64::GetWatchpointAddress(uint32_t wp_index) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return LLDB_INVALID_ADDRESS;
-
- return hw_addr_map[wp_index];
-}
-
-struct EmulatorBaton {
- lldb::addr_t m_watch_hit_addr;
- NativeProcessLinux *m_process;
- NativeRegisterContext *m_reg_context;
-
- EmulatorBaton(NativeProcessLinux *process, NativeRegisterContext *reg_context)
- : m_watch_hit_addr(LLDB_INVALID_ADDRESS), m_process(process),
- m_reg_context(reg_context) {}
-};
-
-static size_t ReadMemoryCallback(EmulateInstruction *instruction, void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr, void *dst, size_t length) {
- size_t bytes_read;
- EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
- emulator_baton->m_process->ReadMemory(addr, dst, length, bytes_read);
- return bytes_read;
-}
-
-static size_t WriteMemoryCallback(EmulateInstruction *instruction, void *baton,
- const EmulateInstruction::Context &context,
- lldb::addr_t addr, const void *dst,
- size_t length) {
- return length;
-}
-
-static bool ReadRegisterCallback(EmulateInstruction *instruction, void *baton,
- const RegisterInfo *reg_info,
- RegisterValue &reg_value) {
- EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
-
- const RegisterInfo *full_reg_info =
- emulator_baton->m_reg_context->GetRegisterInfo(
- lldb::eRegisterKindDWARF, reg_info->kinds[lldb::eRegisterKindDWARF]);
-
- Status error =
- emulator_baton->m_reg_context->ReadRegister(full_reg_info, reg_value);
- if (error.Success())
- return true;
-
- return false;
-}
-
-static bool WriteRegisterCallback(EmulateInstruction *instruction, void *baton,
- const EmulateInstruction::Context &context,
- const RegisterInfo *reg_info,
- const RegisterValue &reg_value) {
- if (reg_info->kinds[lldb::eRegisterKindDWARF] == dwarf_bad_mips64) {
- EmulatorBaton *emulator_baton = static_cast<EmulatorBaton *>(baton);
- emulator_baton->m_watch_hit_addr = reg_value.GetAsUInt64();
- }
-
- return true;
-}
-
-/*
- * MIPS Linux kernel returns a masked address (last 3bits are masked)
- * when a HW watchpoint is hit. However user may not have set a watchpoint
- * on this address. Emulate instruction at PC and find the base address of
- * the load/store instruction. This will give the exact address used to
- * read/write the variable. Send this exact address to client so that
- * it can decide to stop or continue the thread.
-*/
-lldb::addr_t
-NativeRegisterContextLinux_mips64::GetWatchpointHitAddress(uint32_t wp_index) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return LLDB_INVALID_ADDRESS;
-
- lldb_private::ArchSpec arch;
- arch = GetRegisterInfoInterface().GetTargetArchitecture();
- std::unique_ptr<EmulateInstruction> emulator_ap(
- EmulateInstruction::FindPlugin(arch, lldb_private::eInstructionTypeAny,
- nullptr));
-
- if (emulator_ap == nullptr)
- return LLDB_INVALID_ADDRESS;
-
- EmulatorBaton baton(
- static_cast<NativeProcessLinux *>(&m_thread.GetProcess()), this);
- emulator_ap->SetBaton(&baton);
- emulator_ap->SetReadMemCallback(&ReadMemoryCallback);
- emulator_ap->SetReadRegCallback(&ReadRegisterCallback);
- emulator_ap->SetWriteMemCallback(&WriteMemoryCallback);
- emulator_ap->SetWriteRegCallback(&WriteRegisterCallback);
-
- if (!emulator_ap->ReadInstruction())
- return LLDB_INVALID_ADDRESS;
-
- if (emulator_ap->EvaluateInstruction(lldb::eEmulateInstructionOptionNone))
- return baton.m_watch_hit_addr;
-
- return LLDB_INVALID_ADDRESS;
-}
-
-uint32_t NativeRegisterContextLinux_mips64::NumSupportedHardwareWatchpoints() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- struct pt_watch_regs regs;
- static int num_valid = 0;
- if (!num_valid) {
- DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
- default_watch_regs =
- regs; // Keeping default watch regs values for future use
- switch (regs.style) {
- case pt_watch_style_mips32:
- num_valid = regs.mips32.num_valid; // Using num_valid as cache
- return num_valid;
- case pt_watch_style_mips64:
- num_valid = regs.mips64.num_valid;
- return num_valid;
- }
- LLDB_LOG(log, "Invalid watch register style");
- return 0;
- }
- return num_valid;
-}
-
-Status
-NativeRegisterContextLinux_mips64::ReadRegisterRaw(uint32_t reg_index,
- RegisterValue &value) {
- const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
-
- if (!reg_info)
- return Status("register %" PRIu32 " not found", reg_index);
-
- uint32_t offset = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
-
- if ((offset == ptrace_sr_mips) || (offset == ptrace_config5_mips))
- return Read_SR_Config(reg_info->byte_offset, reg_info->name,
- reg_info->byte_size, value);
-
- return DoReadRegisterValue(offset, reg_info->name, reg_info->byte_size,
- value);
-}
-
-Status NativeRegisterContextLinux_mips64::WriteRegisterRaw(
- uint32_t reg_index, const RegisterValue &value) {
- const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
-
- if (!reg_info)
- return Status("register %" PRIu32 " not found", reg_index);
-
- if (reg_info->invalidate_regs)
- lldbassert(false && "reg_info->invalidate_regs is unhandled");
-
- uint32_t offset = reg_info->kinds[lldb::eRegisterKindProcessPlugin];
- return DoWriteRegisterValue(offset, reg_info->name, value);
-}
-
-Status NativeRegisterContextLinux_mips64::Read_SR_Config(uint32_t offset,
- const char *reg_name,
- uint32_t size,
- RegisterValue &value) {
- GPR_linux_mips regs;
- ::memset(&regs, 0, sizeof(GPR_linux_mips));
-
- Status error = NativeProcessLinux::PtraceWrapper(
- PTRACE_GETREGS, m_thread.GetID(), NULL, &regs, sizeof regs);
- if (error.Success()) {
- const lldb_private::ArchSpec &arch =
- m_thread.GetProcess().GetArchitecture();
- void *target_address = ((uint8_t *)&regs) + offset +
- 4 * (arch.GetMachine() == llvm::Triple::mips);
- value.SetUInt(*(uint32_t *)target_address, size);
- }
- return error;
-}
-
-Status NativeRegisterContextLinux_mips64::DoReadWatchPointRegisterValue(
- lldb::tid_t tid, void *watch_readback) {
- return NativeProcessLinux::PtraceWrapper(PTRACE_GET_WATCH_REGS,
- m_thread.GetID(), watch_readback);
-}
-
-Status NativeRegisterContextLinux_mips64::DoWriteWatchPointRegisterValue(
- lldb::tid_t tid, void *watch_reg_value) {
- return NativeProcessLinux::PtraceWrapper(PTRACE_SET_WATCH_REGS,
- m_thread.GetID(), watch_reg_value);
-}
-
-#endif // defined (__mips__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
deleted file mode 100644
index c4e984a545bc6..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
+++ /dev/null
@@ -1,140 +0,0 @@
-//===-- NativeRegisterContextLinux_mips64.h ---------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__mips__)
-
-#ifndef lldb_NativeRegisterContextLinux_mips64_h
-#define lldb_NativeRegisterContextLinux_mips64_h
-
-#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
-#include "Plugins/Process/Utility/RegisterContext_mips.h"
-#include "Plugins/Process/Utility/lldb-mips-linux-register-enums.h"
-#include <sys/uio.h>
-
-#define MAX_NUM_WP 8
-
-namespace lldb_private {
-namespace process_linux {
-
-class NativeProcessLinux;
-
-class NativeRegisterContextLinux_mips64 : public NativeRegisterContextLinux {
-public:
- NativeRegisterContextLinux_mips64(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread);
-
- uint32_t GetRegisterSetCount() const override;
-
- lldb::addr_t GetPCfromBreakpointLocation(
- lldb::addr_t fail_value = LLDB_INVALID_ADDRESS) override;
-
- lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
-
- const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
-
- Status ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) override;
-
- Status WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &reg_value) override;
-
- Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- Status ReadCP1();
-
- Status WriteCP1();
-
- uint8_t *ReturnFPOffset(uint8_t reg_index, uint32_t byte_offset);
-
- Status IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
-
- Status GetWatchpointHitIndex(uint32_t &wp_index,
- lldb::addr_t trap_addr) override;
-
- Status IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
-
- bool ClearHardwareWatchpoint(uint32_t wp_index) override;
-
- Status ClearAllHardwareWatchpoints() override;
-
- Status SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
- uint32_t watch_flags,
- uint32_t wp_index);
-
- uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
- uint32_t watch_flags) override;
-
- lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
-
- uint32_t NumSupportedHardwareWatchpoints() override;
-
- static bool IsMSAAvailable();
-
-protected:
- Status Read_SR_Config(uint32_t offset, const char *reg_name, uint32_t size,
- RegisterValue &value);
-
- Status ReadRegisterRaw(uint32_t reg_index, RegisterValue &value) override;
-
- Status WriteRegisterRaw(uint32_t reg_index,
- const RegisterValue &value) override;
-
- Status DoReadWatchPointRegisterValue(lldb::tid_t tid, void *watch_readback);
-
- Status DoWriteWatchPointRegisterValue(lldb::tid_t tid, void *watch_readback);
-
- bool IsFR0();
-
- bool IsFRE();
-
- bool IsFPR(uint32_t reg_index) const;
-
- bool IsMSA(uint32_t reg_index) const;
-
- void *GetGPRBuffer() override { return &m_gpr; }
-
- void *GetFPRBuffer() override { return &m_fpr; }
-
- size_t GetFPRSize() override { return sizeof(FPR_linux_mips); }
-
-private:
- // Info about register ranges.
- struct RegInfo {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
-
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
- uint32_t first_msa;
- uint32_t last_msa;
- };
-
- RegInfo m_reg_info;
-
- GPR_linux_mips m_gpr;
-
- FPR_linux_mips m_fpr;
-
- MSA_linux_mips m_msa;
-
- lldb::addr_t hw_addr_map[MAX_NUM_WP];
-
- struct iovec m_iovec;
-};
-
-} // namespace process_linux
-} // namespace lldb_private
-
-#endif // #ifndef lldb_NativeRegisterContextLinux_mips64_h
-
-#endif // defined (__mips__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp
deleted file mode 100644
index da51fda1c80b3..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.cpp
+++ /dev/null
@@ -1,804 +0,0 @@
-//===-- NativeRegisterContextLinux_ppc64le.cpp ------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// This implementation is related to the OpenPOWER ABI for Power Architecture
-// 64-bit ELF V2 ABI
-
-#if defined(__powerpc64__)
-
-#include "NativeRegisterContextLinux_ppc64le.h"
-
-#include "lldb/Host/common/NativeProcessProtocol.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Status.h"
-
-#include "Plugins/Process/Linux/NativeProcessLinux.h"
-#include "Plugins/Process/Linux/Procfs.h"
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h"
-
-// System includes - They have to be included after framework includes because
-// they define some macros which collide with variable names in other modules
-#include <sys/socket.h>
-#include <elf.h>
-#include <asm/ptrace.h>
-
-#define REG_CONTEXT_SIZE \
- (GetGPRSize() + GetFPRSize() + sizeof(m_vmx_ppc64le) + sizeof(m_vsx_ppc64le))
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::process_linux;
-
-static const uint32_t g_gpr_regnums_ppc64le[] = {
- gpr_r0_ppc64le, gpr_r1_ppc64le, gpr_r2_ppc64le, gpr_r3_ppc64le,
- gpr_r4_ppc64le, gpr_r5_ppc64le, gpr_r6_ppc64le, gpr_r7_ppc64le,
- gpr_r8_ppc64le, gpr_r9_ppc64le, gpr_r10_ppc64le, gpr_r11_ppc64le,
- gpr_r12_ppc64le, gpr_r13_ppc64le, gpr_r14_ppc64le, gpr_r15_ppc64le,
- gpr_r16_ppc64le, gpr_r17_ppc64le, gpr_r18_ppc64le, gpr_r19_ppc64le,
- gpr_r20_ppc64le, gpr_r21_ppc64le, gpr_r22_ppc64le, gpr_r23_ppc64le,
- gpr_r24_ppc64le, gpr_r25_ppc64le, gpr_r26_ppc64le, gpr_r27_ppc64le,
- gpr_r28_ppc64le, gpr_r29_ppc64le, gpr_r30_ppc64le, gpr_r31_ppc64le,
- gpr_pc_ppc64le, gpr_msr_ppc64le, gpr_origr3_ppc64le, gpr_ctr_ppc64le,
- gpr_lr_ppc64le, gpr_xer_ppc64le, gpr_cr_ppc64le, gpr_softe_ppc64le,
- gpr_trap_ppc64le,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-static const uint32_t g_fpr_regnums_ppc64le[] = {
- fpr_f0_ppc64le, fpr_f1_ppc64le, fpr_f2_ppc64le, fpr_f3_ppc64le,
- fpr_f4_ppc64le, fpr_f5_ppc64le, fpr_f6_ppc64le, fpr_f7_ppc64le,
- fpr_f8_ppc64le, fpr_f9_ppc64le, fpr_f10_ppc64le, fpr_f11_ppc64le,
- fpr_f12_ppc64le, fpr_f13_ppc64le, fpr_f14_ppc64le, fpr_f15_ppc64le,
- fpr_f16_ppc64le, fpr_f17_ppc64le, fpr_f18_ppc64le, fpr_f19_ppc64le,
- fpr_f20_ppc64le, fpr_f21_ppc64le, fpr_f22_ppc64le, fpr_f23_ppc64le,
- fpr_f24_ppc64le, fpr_f25_ppc64le, fpr_f26_ppc64le, fpr_f27_ppc64le,
- fpr_f28_ppc64le, fpr_f29_ppc64le, fpr_f30_ppc64le, fpr_f31_ppc64le,
- fpr_fpscr_ppc64le,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-static const uint32_t g_vmx_regnums_ppc64le[] = {
- vmx_vr0_ppc64le, vmx_vr1_ppc64le, vmx_vr2_ppc64le, vmx_vr3_ppc64le,
- vmx_vr4_ppc64le, vmx_vr5_ppc64le, vmx_vr6_ppc64le, vmx_vr7_ppc64le,
- vmx_vr8_ppc64le, vmx_vr9_ppc64le, vmx_vr10_ppc64le, vmx_vr11_ppc64le,
- vmx_vr12_ppc64le, vmx_vr13_ppc64le, vmx_vr14_ppc64le, vmx_vr15_ppc64le,
- vmx_vr16_ppc64le, vmx_vr17_ppc64le, vmx_vr18_ppc64le, vmx_vr19_ppc64le,
- vmx_vr20_ppc64le, vmx_vr21_ppc64le, vmx_vr22_ppc64le, vmx_vr23_ppc64le,
- vmx_vr24_ppc64le, vmx_vr25_ppc64le, vmx_vr26_ppc64le, vmx_vr27_ppc64le,
- vmx_vr28_ppc64le, vmx_vr29_ppc64le, vmx_vr30_ppc64le, vmx_vr31_ppc64le,
- vmx_vscr_ppc64le, vmx_vrsave_ppc64le,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-static const uint32_t g_vsx_regnums_ppc64le[] = {
- vsx_vs0_ppc64le, vsx_vs1_ppc64le, vsx_vs2_ppc64le, vsx_vs3_ppc64le,
- vsx_vs4_ppc64le, vsx_vs5_ppc64le, vsx_vs6_ppc64le, vsx_vs7_ppc64le,
- vsx_vs8_ppc64le, vsx_vs9_ppc64le, vsx_vs10_ppc64le, vsx_vs11_ppc64le,
- vsx_vs12_ppc64le, vsx_vs13_ppc64le, vsx_vs14_ppc64le, vsx_vs15_ppc64le,
- vsx_vs16_ppc64le, vsx_vs17_ppc64le, vsx_vs18_ppc64le, vsx_vs19_ppc64le,
- vsx_vs20_ppc64le, vsx_vs21_ppc64le, vsx_vs22_ppc64le, vsx_vs23_ppc64le,
- vsx_vs24_ppc64le, vsx_vs25_ppc64le, vsx_vs26_ppc64le, vsx_vs27_ppc64le,
- vsx_vs28_ppc64le, vsx_vs29_ppc64le, vsx_vs30_ppc64le, vsx_vs31_ppc64le,
- vsx_vs32_ppc64le, vsx_vs33_ppc64le, vsx_vs34_ppc64le, vsx_vs35_ppc64le,
- vsx_vs36_ppc64le, vsx_vs37_ppc64le, vsx_vs38_ppc64le, vsx_vs39_ppc64le,
- vsx_vs40_ppc64le, vsx_vs41_ppc64le, vsx_vs42_ppc64le, vsx_vs43_ppc64le,
- vsx_vs44_ppc64le, vsx_vs45_ppc64le, vsx_vs46_ppc64le, vsx_vs47_ppc64le,
- vsx_vs48_ppc64le, vsx_vs49_ppc64le, vsx_vs50_ppc64le, vsx_vs51_ppc64le,
- vsx_vs52_ppc64le, vsx_vs53_ppc64le, vsx_vs54_ppc64le, vsx_vs55_ppc64le,
- vsx_vs56_ppc64le, vsx_vs57_ppc64le, vsx_vs58_ppc64le, vsx_vs59_ppc64le,
- vsx_vs60_ppc64le, vsx_vs61_ppc64le, vsx_vs62_ppc64le, vsx_vs63_ppc64le,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-
-namespace {
-// Number of register sets provided by this context.
-enum { k_num_register_sets = 4 };
-}
-
-static const RegisterSet g_reg_sets_ppc64le[k_num_register_sets] = {
- {"General Purpose Registers", "gpr", k_num_gpr_registers_ppc64le,
- g_gpr_regnums_ppc64le},
- {"Floating Point Registers", "fpr", k_num_fpr_registers_ppc64le,
- g_fpr_regnums_ppc64le},
- {"AltiVec/VMX Registers", "vmx", k_num_vmx_registers_ppc64le,
- g_vmx_regnums_ppc64le},
- {"VSX Registers", "vsx", k_num_vsx_registers_ppc64le,
- g_vsx_regnums_ppc64le},
-};
-
-std::unique_ptr<NativeRegisterContextLinux>
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
- switch (target_arch.GetMachine()) {
- case llvm::Triple::ppc64le:
- return llvm::make_unique<NativeRegisterContextLinux_ppc64le>(target_arch,
- native_thread);
- default:
- llvm_unreachable("have no register context for architecture");
- }
-}
-
-NativeRegisterContextLinux_ppc64le::NativeRegisterContextLinux_ppc64le(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
- : NativeRegisterContextLinux(native_thread,
- new RegisterInfoPOSIX_ppc64le(target_arch)) {
- if (target_arch.GetMachine() != llvm::Triple::ppc64le) {
- llvm_unreachable("Unhandled target architecture.");
- }
-
- ::memset(&m_gpr_ppc64le, 0, sizeof(m_gpr_ppc64le));
- ::memset(&m_fpr_ppc64le, 0, sizeof(m_fpr_ppc64le));
- ::memset(&m_vmx_ppc64le, 0, sizeof(m_vmx_ppc64le));
- ::memset(&m_vsx_ppc64le, 0, sizeof(m_vsx_ppc64le));
- ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs));
-}
-
-uint32_t NativeRegisterContextLinux_ppc64le::GetRegisterSetCount() const {
- return k_num_register_sets;
-}
-
-const RegisterSet *
-NativeRegisterContextLinux_ppc64le::GetRegisterSet(uint32_t set_index) const {
- if (set_index < k_num_register_sets)
- return &g_reg_sets_ppc64le[set_index];
-
- return nullptr;
-}
-
-uint32_t NativeRegisterContextLinux_ppc64le::GetUserRegisterCount() const {
- uint32_t count = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
- count += g_reg_sets_ppc64le[set_index].num_registers;
- return count;
-}
-
-Status NativeRegisterContextLinux_ppc64le::ReadRegister(
- const RegisterInfo *reg_info, RegisterValue &reg_value) {
- Status error;
-
- if (!reg_info) {
- error.SetErrorString("reg_info NULL");
- return error;
- }
-
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
-
- if (IsFPR(reg)) {
- error = ReadFPR();
- if (error.Fail())
- return error;
-
- // Get pointer to m_fpr_ppc64le variable and set the data from it.
- uint32_t fpr_offset = CalculateFprOffset(reg_info);
- assert(fpr_offset < sizeof m_fpr_ppc64le);
- uint8_t *src = (uint8_t *)&m_fpr_ppc64le + fpr_offset;
- reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
- eByteOrderLittle, error);
- } else if (IsVSX(reg)) {
- uint32_t vsx_offset = CalculateVsxOffset(reg_info);
- assert(vsx_offset < sizeof(m_vsx_ppc64le));
-
- if (vsx_offset < sizeof(m_vsx_ppc64le) / 2) {
- error = ReadVSX();
- if (error.Fail())
- return error;
-
- error = ReadFPR();
- if (error.Fail())
- return error;
-
- uint64_t value[2];
- uint8_t *dst, *src;
- dst = (uint8_t *)&value;
- src = (uint8_t *)&m_vsx_ppc64le + vsx_offset / 2;
- ::memcpy(dst, src, 8);
- dst += 8;
- src = (uint8_t *)&m_fpr_ppc64le + vsx_offset / 2;
- ::memcpy(dst, src, 8);
- reg_value.SetFromMemoryData(reg_info, &value, reg_info->byte_size,
- eByteOrderLittle, error);
- } else {
- error = ReadVMX();
- if (error.Fail())
- return error;
-
- // Get pointer to m_vmx_ppc64le variable and set the data from it.
- uint32_t vmx_offset = vsx_offset - sizeof(m_vsx_ppc64le) / 2;
- uint8_t *src = (uint8_t *)&m_vmx_ppc64le + vmx_offset;
- reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
- eByteOrderLittle, error);
- }
- } else if (IsVMX(reg)) {
- error = ReadVMX();
- if (error.Fail())
- return error;
-
- // Get pointer to m_vmx_ppc64le variable and set the data from it.
- uint32_t vmx_offset = CalculateVmxOffset(reg_info);
- assert(vmx_offset < sizeof m_vmx_ppc64le);
- uint8_t *src = (uint8_t *)&m_vmx_ppc64le + vmx_offset;
- reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
- eByteOrderLittle, error);
- } else if (IsGPR(reg)) {
- error = ReadGPR();
- if (error.Fail())
- return error;
-
- uint8_t *src = (uint8_t *) &m_gpr_ppc64le + reg_info->byte_offset;
- reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size,
- eByteOrderLittle, error);
- } else {
- return Status("failed - register wasn't recognized to be a GPR, FPR, VSX "
- "or VMX, read strategy unknown");
- }
-
- return error;
-}
-
-Status NativeRegisterContextLinux_ppc64le::WriteRegister(
- const RegisterInfo *reg_info, const RegisterValue &reg_value) {
- Status error;
- if (!reg_info)
- return Status("reg_info NULL");
-
- const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg_index == LLDB_INVALID_REGNUM)
- return Status("no lldb regnum for %s", reg_info && reg_info->name
- ? reg_info->name
- : "<unknown register>");
-
- if (IsGPR(reg_index)) {
- error = ReadGPR();
- if (error.Fail())
- return error;
-
- uint8_t *dst = (uint8_t *)&m_gpr_ppc64le + reg_info->byte_offset;
- ::memcpy(dst, reg_value.GetBytes(), reg_value.GetByteSize());
-
- error = WriteGPR();
- if (error.Fail())
- return error;
-
- return Status();
- }
-
- if (IsFPR(reg_index)) {
- error = ReadFPR();
- if (error.Fail())
- return error;
-
- // Get pointer to m_fpr_ppc64le variable and set the data to it.
- uint32_t fpr_offset = CalculateFprOffset(reg_info);
- assert(fpr_offset < GetFPRSize());
- uint8_t *dst = (uint8_t *)&m_fpr_ppc64le + fpr_offset;
- ::memcpy(dst, reg_value.GetBytes(), reg_value.GetByteSize());
-
- error = WriteFPR();
- if (error.Fail())
- return error;
-
- return Status();
- }
-
- if (IsVMX(reg_index)) {
- error = ReadVMX();
- if (error.Fail())
- return error;
-
- // Get pointer to m_vmx_ppc64le variable and set the data to it.
- uint32_t vmx_offset = CalculateVmxOffset(reg_info);
- assert(vmx_offset < sizeof(m_vmx_ppc64le));
- uint8_t *dst = (uint8_t *)&m_vmx_ppc64le + vmx_offset;
- ::memcpy(dst, reg_value.GetBytes(), reg_value.GetByteSize());
-
- error = WriteVMX();
- if (error.Fail())
- return error;
-
- return Status();
- }
-
- if (IsVSX(reg_index)) {
- uint32_t vsx_offset = CalculateVsxOffset(reg_info);
- assert(vsx_offset < sizeof(m_vsx_ppc64le));
-
- if (vsx_offset < sizeof(m_vsx_ppc64le) / 2) {
- error = ReadVSX();
- if (error.Fail())
- return error;
-
- error = ReadFPR();
- if (error.Fail())
- return error;
-
- uint64_t value[2];
- ::memcpy(value, reg_value.GetBytes(), 16);
- uint8_t *dst, *src;
- src = (uint8_t *)value;
- dst = (uint8_t *)&m_vsx_ppc64le + vsx_offset / 2;
- ::memcpy(dst, src, 8);
- src += 8;
- dst = (uint8_t *)&m_fpr_ppc64le + vsx_offset / 2;
- ::memcpy(dst, src, 8);
-
- WriteVSX();
- WriteFPR();
- } else {
- error = ReadVMX();
- if (error.Fail())
- return error;
-
- // Get pointer to m_vmx_ppc64le variable and set the data from it.
- uint32_t vmx_offset = vsx_offset - sizeof(m_vsx_ppc64le) / 2;
- uint8_t *dst = (uint8_t *)&m_vmx_ppc64le + vmx_offset;
- ::memcpy(dst, reg_value.GetBytes(), reg_value.GetByteSize());
- WriteVMX();
- }
-
- return Status();
- }
-
- return Status("failed - register wasn't recognized to be a GPR, FPR, VSX "
- "or VMX, write strategy unknown");
-}
-
-Status NativeRegisterContextLinux_ppc64le::ReadAllRegisterValues(
- lldb::DataBufferSP &data_sp) {
- Status error;
-
- data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
- if (!data_sp)
- return Status("failed to allocate DataBufferHeap instance of size %" PRIu64,
- REG_CONTEXT_SIZE);
-
- error = ReadGPR();
- if (error.Fail())
- return error;
-
- error = ReadFPR();
- if (error.Fail())
- return error;
-
- error = ReadVMX();
- if (error.Fail())
- return error;
-
- error = ReadVSX();
- if (error.Fail())
- return error;
-
- uint8_t *dst = data_sp->GetBytes();
- if (dst == nullptr) {
- error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
- " returned a null pointer",
- REG_CONTEXT_SIZE);
- return error;
- }
-
- ::memcpy(dst, &m_gpr_ppc64le, GetGPRSize());
- dst += GetGPRSize();
- ::memcpy(dst, &m_fpr_ppc64le, GetFPRSize());
- dst += GetFPRSize();
- ::memcpy(dst, &m_vmx_ppc64le, sizeof(m_vmx_ppc64le));
- dst += sizeof(m_vmx_ppc64le);
- ::memcpy(dst, &m_vsx_ppc64le, sizeof(m_vsx_ppc64le));
-
- return error;
-}
-
-Status NativeRegisterContextLinux_ppc64le::WriteAllRegisterValues(
- const lldb::DataBufferSP &data_sp) {
- Status error;
-
- if (!data_sp) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_ppc64le::%s invalid data_sp provided",
- __FUNCTION__);
- return error;
- }
-
- if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_ppc64le::%s data_sp contained mismatched "
- "data size, expected %" PRIu64 ", actual %" PRIu64,
- __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
- return error;
- }
-
- uint8_t *src = data_sp->GetBytes();
- if (src == nullptr) {
- error.SetErrorStringWithFormat("NativeRegisterContextLinux_ppc64le::%s "
- "DataBuffer::GetBytes() returned a null "
- "pointer",
- __FUNCTION__);
- return error;
- }
-
- ::memcpy(&m_gpr_ppc64le, src, GetGPRSize());
- error = WriteGPR();
-
- if (error.Fail())
- return error;
-
- src += GetGPRSize();
- ::memcpy(&m_fpr_ppc64le, src, GetFPRSize());
-
- error = WriteFPR();
- if (error.Fail())
- return error;
-
- src += GetFPRSize();
- ::memcpy(&m_vmx_ppc64le, src, sizeof(m_vmx_ppc64le));
-
- error = WriteVMX();
- if (error.Fail())
- return error;
-
- src += sizeof(m_vmx_ppc64le);
- ::memcpy(&m_vsx_ppc64le, src, sizeof(m_vsx_ppc64le));
- error = WriteVSX();
-
- return error;
-}
-
-bool NativeRegisterContextLinux_ppc64le::IsGPR(unsigned reg) const {
- return reg <= k_last_gpr_ppc64le; // GPR's come first.
-}
-
-bool NativeRegisterContextLinux_ppc64le::IsFPR(unsigned reg) const {
- return (k_first_fpr_ppc64le <= reg && reg <= k_last_fpr_ppc64le);
-}
-
-Status NativeRegisterContextLinux_ppc64le::DoReadGPR(
- void *buf, size_t buf_size) {
- int regset = NT_PRSTATUS;
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGS, m_thread.GetID(),
- &regset, buf, buf_size);
-}
-
-Status NativeRegisterContextLinux_ppc64le::DoWriteGPR(
- void *buf, size_t buf_size) {
- int regset = NT_PRSTATUS;
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGS, m_thread.GetID(),
- &regset, buf, buf_size);
-}
-
-Status NativeRegisterContextLinux_ppc64le::DoReadFPR(void *buf,
- size_t buf_size) {
- int regset = NT_FPREGSET;
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETFPREGS, m_thread.GetID(),
- &regset, buf, buf_size);
-}
-
-Status NativeRegisterContextLinux_ppc64le::DoWriteFPR(void *buf,
- size_t buf_size) {
- int regset = NT_FPREGSET;
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETFPREGS, m_thread.GetID(),
- &regset, buf, buf_size);
-}
-
-uint32_t NativeRegisterContextLinux_ppc64le::CalculateFprOffset(
- const RegisterInfo *reg_info) const {
- return reg_info->byte_offset -
- GetRegisterInfoAtIndex(k_first_fpr_ppc64le)->byte_offset;
-}
-
-uint32_t NativeRegisterContextLinux_ppc64le::CalculateVmxOffset(
- const RegisterInfo *reg_info) const {
- return reg_info->byte_offset -
- GetRegisterInfoAtIndex(k_first_vmx_ppc64le)->byte_offset;
-}
-
-uint32_t NativeRegisterContextLinux_ppc64le::CalculateVsxOffset(
- const RegisterInfo *reg_info) const {
- return reg_info->byte_offset -
- GetRegisterInfoAtIndex(k_first_vsx_ppc64le)->byte_offset;
-}
-
-Status NativeRegisterContextLinux_ppc64le::ReadVMX() {
- int regset = NT_PPC_VMX;
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETVRREGS, m_thread.GetID(),
- &regset, &m_vmx_ppc64le,
- sizeof(m_vmx_ppc64le));
-}
-
-Status NativeRegisterContextLinux_ppc64le::WriteVMX() {
- int regset = NT_PPC_VMX;
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETVRREGS, m_thread.GetID(),
- &regset, &m_vmx_ppc64le,
- sizeof(m_vmx_ppc64le));
-}
-
-Status NativeRegisterContextLinux_ppc64le::ReadVSX() {
- int regset = NT_PPC_VSX;
- return NativeProcessLinux::PtraceWrapper(PTRACE_GETVSRREGS, m_thread.GetID(),
- &regset, &m_vsx_ppc64le,
- sizeof(m_vsx_ppc64le));
-}
-
-Status NativeRegisterContextLinux_ppc64le::WriteVSX() {
- int regset = NT_PPC_VSX;
- return NativeProcessLinux::PtraceWrapper(PTRACE_SETVSRREGS, m_thread.GetID(),
- &regset, &m_vsx_ppc64le,
- sizeof(m_vsx_ppc64le));
-}
-
-bool NativeRegisterContextLinux_ppc64le::IsVMX(unsigned reg) {
- return (reg >= k_first_vmx_ppc64le) && (reg <= k_last_vmx_ppc64le);
-}
-
-bool NativeRegisterContextLinux_ppc64le::IsVSX(unsigned reg) {
- return (reg >= k_first_vsx_ppc64le) && (reg <= k_last_vsx_ppc64le);
-}
-
-uint32_t NativeRegisterContextLinux_ppc64le::NumSupportedHardwareWatchpoints() {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return 0;
-
- LLDB_LOG(log, "{0}", m_max_hwp_supported);
- return m_max_hwp_supported;
-}
-
-uint32_t NativeRegisterContextLinux_ppc64le::SetHardwareWatchpoint(
- lldb::addr_t addr, size_t size, uint32_t watch_flags) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "addr: {0:x}, size: {1:x} watch_flags: {2:x}", addr, size,
- watch_flags);
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
-
- uint32_t control_value = 0, wp_index = 0;
- lldb::addr_t real_addr = addr;
- uint32_t rw_mode = 0;
-
- // Check if we are setting watchpoint other than read/write/access Update
- // watchpoint flag to match ppc64le write-read bit configuration.
- switch (watch_flags) {
- case eWatchpointKindWrite:
- rw_mode = PPC_BREAKPOINT_TRIGGER_WRITE;
- watch_flags = 2;
- break;
- case eWatchpointKindRead:
- rw_mode = PPC_BREAKPOINT_TRIGGER_READ;
- watch_flags = 1;
- break;
- case (eWatchpointKindRead | eWatchpointKindWrite):
- rw_mode = PPC_BREAKPOINT_TRIGGER_RW;
- break;
- default:
- return LLDB_INVALID_INDEX32;
- }
-
- // Check if size has a valid hardware watchpoint length.
- if (size != 1 && size != 2 && size != 4 && size != 8)
- return LLDB_INVALID_INDEX32;
-
- // Check 8-byte alignment for hardware watchpoint target address. Below is a
- // hack to recalculate address and size in order to make sure we can watch
- // non 8-byte alligned addresses as well.
- if (addr & 0x07) {
-
- addr_t begin = llvm::alignDown(addr, 8);
- addr_t end = llvm::alignTo(addr + size, 8);
- size = llvm::PowerOf2Ceil(end - begin);
-
- addr = addr & (~0x07);
- }
-
- // Setup control value
- control_value = watch_flags << 3;
- control_value |= ((1 << size) - 1) << 5;
- control_value |= (2 << 1) | 1;
-
- // Iterate over stored watchpoints and find a free wp_index
- wp_index = LLDB_INVALID_INDEX32;
- for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
- if ((m_hwp_regs[i].control & 1) == 0) {
- wp_index = i; // Mark last free slot
- } else if (m_hwp_regs[i].address == addr) {
- return LLDB_INVALID_INDEX32; // We do not support duplicate watchpoints.
- }
- }
-
- if (wp_index == LLDB_INVALID_INDEX32)
- return LLDB_INVALID_INDEX32;
-
- // Update watchpoint in local cache
- m_hwp_regs[wp_index].real_addr = real_addr;
- m_hwp_regs[wp_index].address = addr;
- m_hwp_regs[wp_index].control = control_value;
- m_hwp_regs[wp_index].mode = rw_mode;
-
- // PTRACE call to set corresponding watchpoint register.
- error = WriteHardwareDebugRegs();
-
- if (error.Fail()) {
- m_hwp_regs[wp_index].address = 0;
- m_hwp_regs[wp_index].control &= llvm::maskTrailingZeros<uint32_t>(1);
-
- return LLDB_INVALID_INDEX32;
- }
-
- return wp_index;
-}
-
-bool NativeRegisterContextLinux_ppc64le::ClearHardwareWatchpoint(
- uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- // Read hardware breakpoint and watchpoint information.
- Status error = ReadHardwareDebugInfo();
-
- if (error.Fail())
- return false;
-
- if (wp_index >= m_max_hwp_supported)
- return false;
-
- // Create a backup we can revert to in case of failure.
- lldb::addr_t tempAddr = m_hwp_regs[wp_index].address;
- uint32_t tempControl = m_hwp_regs[wp_index].control;
- long *tempSlot = reinterpret_cast<long *>(m_hwp_regs[wp_index].slot);
-
- // Update watchpoint in local cache
- m_hwp_regs[wp_index].control &= llvm::maskTrailingZeros<uint32_t>(1);
- m_hwp_regs[wp_index].address = 0;
- m_hwp_regs[wp_index].slot = 0;
- m_hwp_regs[wp_index].mode = 0;
-
- // Ptrace call to update hardware debug registers
- error = NativeProcessLinux::PtraceWrapper(PPC_PTRACE_DELHWDEBUG,
- m_thread.GetID(), 0, tempSlot);
-
- if (error.Fail()) {
- m_hwp_regs[wp_index].control = tempControl;
- m_hwp_regs[wp_index].address = tempAddr;
- m_hwp_regs[wp_index].slot = reinterpret_cast<long>(tempSlot);
-
- return false;
- }
-
- return true;
-}
-
-uint32_t
-NativeRegisterContextLinux_ppc64le::GetWatchpointSize(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- unsigned control = (m_hwp_regs[wp_index].control >> 5) & 0xff;
- if (llvm::isPowerOf2_32(control + 1)) {
- return llvm::countPopulation(control);
- }
-
- return 0;
-}
-
-bool NativeRegisterContextLinux_ppc64le::WatchpointIsEnabled(
- uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- return !!((m_hwp_regs[wp_index].control & 0x1) == 0x1);
-}
-
-Status NativeRegisterContextLinux_ppc64le::GetWatchpointHitIndex(
- uint32_t &wp_index, lldb::addr_t trap_addr) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}, trap_addr: {1:x}", wp_index, trap_addr);
-
- uint32_t watch_size;
- lldb::addr_t watch_addr;
-
- for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index) {
- watch_size = GetWatchpointSize(wp_index);
- watch_addr = m_hwp_regs[wp_index].address;
-
- if (WatchpointIsEnabled(wp_index) && trap_addr >= watch_addr &&
- trap_addr <= watch_addr + watch_size) {
- m_hwp_regs[wp_index].hit_addr = trap_addr;
- return Status();
- }
- }
-
- wp_index = LLDB_INVALID_INDEX32;
- return Status();
-}
-
-lldb::addr_t
-NativeRegisterContextLinux_ppc64le::GetWatchpointAddress(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- if (wp_index >= m_max_hwp_supported)
- return LLDB_INVALID_ADDRESS;
-
- if (WatchpointIsEnabled(wp_index))
- return m_hwp_regs[wp_index].real_addr;
- else
- return LLDB_INVALID_ADDRESS;
-}
-
-lldb::addr_t
-NativeRegisterContextLinux_ppc64le::GetWatchpointHitAddress(uint32_t wp_index) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS));
- LLDB_LOG(log, "wp_index: {0}", wp_index);
-
- if (wp_index >= m_max_hwp_supported)
- return LLDB_INVALID_ADDRESS;
-
- if (WatchpointIsEnabled(wp_index))
- return m_hwp_regs[wp_index].hit_addr;
-
- return LLDB_INVALID_ADDRESS;
-}
-
-Status NativeRegisterContextLinux_ppc64le::ReadHardwareDebugInfo() {
- if (!m_refresh_hwdebug_info) {
- return Status();
- }
-
- ::pid_t tid = m_thread.GetID();
-
- struct ppc_debug_info hwdebug_info;
- Status error;
-
- error = NativeProcessLinux::PtraceWrapper(
- PPC_PTRACE_GETHWDBGINFO, tid, 0, &hwdebug_info, sizeof(hwdebug_info));
-
- if (error.Fail())
- return error;
-
- m_max_hwp_supported = hwdebug_info.num_data_bps;
- m_max_hbp_supported = hwdebug_info.num_instruction_bps;
- m_refresh_hwdebug_info = false;
-
- return error;
-}
-
-Status NativeRegisterContextLinux_ppc64le::WriteHardwareDebugRegs() {
- struct ppc_hw_breakpoint reg_state;
- Status error;
- long ret;
-
- for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
- reg_state.addr = m_hwp_regs[i].address;
- reg_state.trigger_type = m_hwp_regs[i].mode;
- reg_state.version = 1;
- reg_state.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
- reg_state.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
- reg_state.addr2 = 0;
- reg_state.condition_value = 0;
-
- error = NativeProcessLinux::PtraceWrapper(PPC_PTRACE_SETHWDEBUG,
- m_thread.GetID(), 0, &reg_state,
- sizeof(reg_state), &ret);
-
- if (error.Fail())
- return error;
-
- m_hwp_regs[i].slot = ret;
- }
-
- return error;
-}
-
-#endif // defined(__powerpc64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h
deleted file mode 100644
index 2c4471962ad0d..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_ppc64le.h
+++ /dev/null
@@ -1,149 +0,0 @@
-//===-- NativeRegisterContextLinux_ppc64le.h --------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// This implementation is related to the OpenPOWER ABI for Power Architecture
-// 64-bit ELF V2 ABI
-
-#if defined(__powerpc64__)
-
-#ifndef lldb_NativeRegisterContextLinux_ppc64le_h
-#define lldb_NativeRegisterContextLinux_ppc64le_h
-
-#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
-#include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h"
-
-#define DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
-#include "Plugins/Process/Utility/RegisterInfos_ppc64le.h"
-#undef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
-
-namespace lldb_private {
-namespace process_linux {
-
-class NativeProcessLinux;
-
-class NativeRegisterContextLinux_ppc64le : public NativeRegisterContextLinux {
-public:
- NativeRegisterContextLinux_ppc64le(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread);
-
- uint32_t GetRegisterSetCount() const override;
-
- uint32_t GetUserRegisterCount() const override;
-
- const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
-
- Status ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) override;
-
- Status WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &reg_value) override;
-
- Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- //------------------------------------------------------------------
- // Hardware watchpoint management functions
- //------------------------------------------------------------------
-
- uint32_t NumSupportedHardwareWatchpoints() override;
-
- uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
- uint32_t watch_flags) override;
-
- bool ClearHardwareWatchpoint(uint32_t hw_index) override;
-
- Status GetWatchpointHitIndex(uint32_t &wp_index,
- lldb::addr_t trap_addr) override;
-
- lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index) override;
-
- lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
-
- uint32_t GetWatchpointSize(uint32_t wp_index);
-
- bool WatchpointIsEnabled(uint32_t wp_index);
-
-protected:
- Status DoReadGPR(void *buf, size_t buf_size) override;
-
- Status DoWriteGPR(void *buf, size_t buf_size) override;
-
- Status DoReadFPR(void *buf, size_t buf_size) override;
-
- Status DoWriteFPR(void *buf, size_t buf_size) override;
-
- bool IsVMX(unsigned reg);
-
- bool IsVSX(unsigned reg);
-
- Status ReadVMX();
-
- Status WriteVMX();
-
- Status ReadVSX();
-
- Status WriteVSX();
-
- void *GetGPRBuffer() override { return &m_gpr_ppc64le; }
-
- void *GetFPRBuffer() override { return &m_fpr_ppc64le; }
-
- size_t GetFPRSize() override { return sizeof(m_fpr_ppc64le); }
-
-private:
- GPR m_gpr_ppc64le; // 64-bit general purpose registers.
- FPR m_fpr_ppc64le; // floating-point registers including extended register.
- VMX m_vmx_ppc64le; // VMX registers.
- VSX m_vsx_ppc64le; // Last lower bytes from first VSX registers.
-
- bool IsGPR(unsigned reg) const;
-
- bool IsFPR(unsigned reg) const;
-
- bool IsVMX(unsigned reg) const;
-
- bool IsVSX(unsigned reg) const;
-
- uint32_t CalculateFprOffset(const RegisterInfo *reg_info) const;
-
- uint32_t CalculateVmxOffset(const RegisterInfo *reg_info) const;
-
- uint32_t CalculateVsxOffset(const RegisterInfo *reg_info) const;
-
- Status ReadHardwareDebugInfo();
-
- Status WriteHardwareDebugRegs();
-
- // Debug register info for hardware watchpoints management.
- struct DREG {
- lldb::addr_t address; // Breakpoint/watchpoint address value.
- lldb::addr_t hit_addr; // Address at which last watchpoint trigger
- // exception occurred.
- lldb::addr_t real_addr; // Address value that should cause target to stop.
- uint32_t control; // Breakpoint/watchpoint control value.
- uint32_t refcount; // Serves as enable/disable and reference counter.
- long slot; // Saves the value returned from PTRACE_SETHWDEBUG.
- int mode; // Defines if watchpoint is read/write/access.
- };
-
- std::array<DREG, 4> m_hwp_regs;
-
- // 16 is just a maximum value, query hardware for actual watchpoint count
- uint32_t m_max_hwp_supported = 16;
- uint32_t m_max_hbp_supported = 16;
- bool m_refresh_hwdebug_info = true;
-};
-
-} // namespace process_linux
-} // namespace lldb_private
-
-#endif // #ifndef lldb_NativeRegisterContextLinux_ppc64le_h
-
-#endif // defined(__powerpc64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
deleted file mode 100644
index 1bc916b69bcd1..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.cpp
+++ /dev/null
@@ -1,638 +0,0 @@
-//===-- NativeRegisterContextLinux_s390x.cpp --------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__s390x__) && defined(__linux__)
-
-#include "NativeRegisterContextLinux_s390x.h"
-#include "Plugins/Process/Linux/NativeProcessLinux.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Status.h"
-
-#include "Plugins/Process/Utility/RegisterContextLinux_s390x.h"
-
-#include <asm/ptrace.h>
-#include <linux/uio.h>
-#include <sys/ptrace.h>
-
-using namespace lldb_private;
-using namespace lldb_private::process_linux;
-
-// ----------------------------------------------------------------------------
-// Private namespace.
-// ----------------------------------------------------------------------------
-
-namespace {
-// s390x 64-bit general purpose registers.
-static const uint32_t g_gpr_regnums_s390x[] = {
- lldb_r0_s390x, lldb_r1_s390x, lldb_r2_s390x, lldb_r3_s390x,
- lldb_r4_s390x, lldb_r5_s390x, lldb_r6_s390x, lldb_r7_s390x,
- lldb_r8_s390x, lldb_r9_s390x, lldb_r10_s390x, lldb_r11_s390x,
- lldb_r12_s390x, lldb_r13_s390x, lldb_r14_s390x, lldb_r15_s390x,
- lldb_acr0_s390x, lldb_acr1_s390x, lldb_acr2_s390x, lldb_acr3_s390x,
- lldb_acr4_s390x, lldb_acr5_s390x, lldb_acr6_s390x, lldb_acr7_s390x,
- lldb_acr8_s390x, lldb_acr9_s390x, lldb_acr10_s390x, lldb_acr11_s390x,
- lldb_acr12_s390x, lldb_acr13_s390x, lldb_acr14_s390x, lldb_acr15_s390x,
- lldb_pswm_s390x, lldb_pswa_s390x,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-static_assert((sizeof(g_gpr_regnums_s390x) / sizeof(g_gpr_regnums_s390x[0])) -
- 1 ==
- k_num_gpr_registers_s390x,
- "g_gpr_regnums_s390x has wrong number of register infos");
-
-// s390x 64-bit floating point registers.
-static const uint32_t g_fpu_regnums_s390x[] = {
- lldb_f0_s390x, lldb_f1_s390x, lldb_f2_s390x, lldb_f3_s390x,
- lldb_f4_s390x, lldb_f5_s390x, lldb_f6_s390x, lldb_f7_s390x,
- lldb_f8_s390x, lldb_f9_s390x, lldb_f10_s390x, lldb_f11_s390x,
- lldb_f12_s390x, lldb_f13_s390x, lldb_f14_s390x, lldb_f15_s390x,
- lldb_fpc_s390x,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-static_assert((sizeof(g_fpu_regnums_s390x) / sizeof(g_fpu_regnums_s390x[0])) -
- 1 ==
- k_num_fpr_registers_s390x,
- "g_fpu_regnums_s390x has wrong number of register infos");
-
-// s390x Linux operating-system information.
-static const uint32_t g_linux_regnums_s390x[] = {
- lldb_orig_r2_s390x, lldb_last_break_s390x, lldb_system_call_s390x,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-static_assert((sizeof(g_linux_regnums_s390x) /
- sizeof(g_linux_regnums_s390x[0])) -
- 1 ==
- k_num_linux_registers_s390x,
- "g_linux_regnums_s390x has wrong number of register infos");
-
-// Number of register sets provided by this context.
-enum { k_num_register_sets = 3 };
-
-// Register sets for s390x 64-bit.
-static const RegisterSet g_reg_sets_s390x[k_num_register_sets] = {
- {"General Purpose Registers", "gpr", k_num_gpr_registers_s390x,
- g_gpr_regnums_s390x},
- {"Floating Point Registers", "fpr", k_num_fpr_registers_s390x,
- g_fpu_regnums_s390x},
- {"Linux Operating System Data", "linux", k_num_linux_registers_s390x,
- g_linux_regnums_s390x},
-};
-}
-
-#define REG_CONTEXT_SIZE (sizeof(s390_regs) + sizeof(s390_fp_regs) + 4)
-
-// ----------------------------------------------------------------------------
-// Required ptrace defines.
-// ----------------------------------------------------------------------------
-
-#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
-#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */
-
-std::unique_ptr<NativeRegisterContextLinux>
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
- return llvm::make_unique<NativeRegisterContextLinux_s390x>(target_arch,
- native_thread);
-}
-
-// ----------------------------------------------------------------------------
-// NativeRegisterContextLinux_s390x members.
-// ----------------------------------------------------------------------------
-
-static RegisterInfoInterface *
-CreateRegisterInfoInterface(const ArchSpec &target_arch) {
- assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
- "Register setting path assumes this is a 64-bit host");
- return new RegisterContextLinux_s390x(target_arch);
-}
-
-NativeRegisterContextLinux_s390x::NativeRegisterContextLinux_s390x(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
- : NativeRegisterContextLinux(native_thread,
- CreateRegisterInfoInterface(target_arch)) {
- // Set up data about ranges of valid registers.
- switch (target_arch.GetMachine()) {
- case llvm::Triple::systemz:
- m_reg_info.num_registers = k_num_registers_s390x;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_s390x;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_s390x;
- m_reg_info.last_gpr = k_last_gpr_s390x;
- m_reg_info.first_fpr = k_first_fpr_s390x;
- m_reg_info.last_fpr = k_last_fpr_s390x;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
-
- // Clear out the watchpoint state.
- m_watchpoint_addr = LLDB_INVALID_ADDRESS;
-}
-
-uint32_t NativeRegisterContextLinux_s390x::GetRegisterSetCount() const {
- uint32_t sets = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
- if (IsRegisterSetAvailable(set_index))
- ++sets;
- }
-
- return sets;
-}
-
-uint32_t NativeRegisterContextLinux_s390x::GetUserRegisterCount() const {
- uint32_t count = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
- const RegisterSet *set = GetRegisterSet(set_index);
- if (set)
- count += set->num_registers;
- }
- return count;
-}
-
-const RegisterSet *
-NativeRegisterContextLinux_s390x::GetRegisterSet(uint32_t set_index) const {
- if (!IsRegisterSetAvailable(set_index))
- return nullptr;
-
- switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
- case llvm::Triple::systemz:
- return &g_reg_sets_s390x[set_index];
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
-
- return nullptr;
-}
-
-bool NativeRegisterContextLinux_s390x::IsRegisterSetAvailable(
- uint32_t set_index) const {
- return set_index < k_num_register_sets;
-}
-
-bool NativeRegisterContextLinux_s390x::IsGPR(uint32_t reg_index) const {
- // GPRs come first. "orig_r2" counts as GPR since it is part of the GPR
- // register area.
- return reg_index <= m_reg_info.last_gpr || reg_index == lldb_orig_r2_s390x;
-}
-
-bool NativeRegisterContextLinux_s390x::IsFPR(uint32_t reg_index) const {
- return (m_reg_info.first_fpr <= reg_index &&
- reg_index <= m_reg_info.last_fpr);
-}
-
-Status
-NativeRegisterContextLinux_s390x::ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) {
- if (!reg_info)
- return Status("reg_info NULL");
-
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg == LLDB_INVALID_REGNUM)
- return Status("register \"%s\" is an internal-only lldb register, cannot "
- "read directly",
- reg_info->name);
-
- if (IsGPR(reg)) {
- s390_regs regs;
- Status error = DoReadGPR(&regs, sizeof(regs));
- if (error.Fail())
- return error;
-
- uint8_t *src = (uint8_t *)&regs + reg_info->byte_offset;
- assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(regs));
- switch (reg_info->byte_size) {
- case 4:
- reg_value.SetUInt32(*(uint32_t *)src);
- break;
- case 8:
- reg_value.SetUInt64(*(uint64_t *)src);
- break;
- default:
- assert(false && "Unhandled data size.");
- return Status("unhandled byte size: %" PRIu32, reg_info->byte_size);
- }
- return Status();
- }
-
- if (IsFPR(reg)) {
- s390_fp_regs fp_regs;
- Status error = DoReadFPR(&fp_regs, sizeof(fp_regs));
- if (error.Fail())
- return error;
-
- // byte_offset is just the offset within FPR, not the whole user area.
- uint8_t *src = (uint8_t *)&fp_regs + reg_info->byte_offset;
- assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(fp_regs));
- switch (reg_info->byte_size) {
- case 4:
- reg_value.SetUInt32(*(uint32_t *)src);
- break;
- case 8:
- reg_value.SetUInt64(*(uint64_t *)src);
- break;
- default:
- assert(false && "Unhandled data size.");
- return Status("unhandled byte size: %" PRIu32, reg_info->byte_size);
- }
- return Status();
- }
-
- if (reg == lldb_last_break_s390x) {
- uint64_t last_break;
- Status error = DoReadRegisterSet(NT_S390_LAST_BREAK, &last_break, 8);
- if (error.Fail())
- return error;
-
- reg_value.SetUInt64(last_break);
- return Status();
- }
-
- if (reg == lldb_system_call_s390x) {
- uint32_t system_call;
- Status error = DoReadRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
- if (error.Fail())
- return error;
-
- reg_value.SetUInt32(system_call);
- return Status();
- }
-
- return Status("failed - register wasn't recognized");
-}
-
-Status NativeRegisterContextLinux_s390x::WriteRegister(
- const RegisterInfo *reg_info, const RegisterValue &reg_value) {
- if (!reg_info)
- return Status("reg_info NULL");
-
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg == LLDB_INVALID_REGNUM)
- return Status("register \"%s\" is an internal-only lldb register, cannot "
- "write directly",
- reg_info->name);
-
- if (IsGPR(reg)) {
- s390_regs regs;
- Status error = DoReadGPR(&regs, sizeof(regs));
- if (error.Fail())
- return error;
-
- uint8_t *dst = (uint8_t *)&regs + reg_info->byte_offset;
- assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(regs));
- switch (reg_info->byte_size) {
- case 4:
- *(uint32_t *)dst = reg_value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = reg_value.GetAsUInt64();
- break;
- default:
- assert(false && "Unhandled data size.");
- return Status("unhandled byte size: %" PRIu32, reg_info->byte_size);
- }
- return DoWriteGPR(&regs, sizeof(regs));
- }
-
- if (IsFPR(reg)) {
- s390_fp_regs fp_regs;
- Status error = DoReadFPR(&fp_regs, sizeof(fp_regs));
- if (error.Fail())
- return error;
-
- // byte_offset is just the offset within fp_regs, not the whole user area.
- uint8_t *dst = (uint8_t *)&fp_regs + reg_info->byte_offset;
- assert(reg_info->byte_offset + reg_info->byte_size <= sizeof(fp_regs));
- switch (reg_info->byte_size) {
- case 4:
- *(uint32_t *)dst = reg_value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = reg_value.GetAsUInt64();
- break;
- default:
- assert(false && "Unhandled data size.");
- return Status("unhandled byte size: %" PRIu32, reg_info->byte_size);
- }
- return DoWriteFPR(&fp_regs, sizeof(fp_regs));
- }
-
- if (reg == lldb_last_break_s390x) {
- return Status("The last break address is read-only");
- }
-
- if (reg == lldb_system_call_s390x) {
- uint32_t system_call = reg_value.GetAsUInt32();
- return DoWriteRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
- }
-
- return Status("failed - register wasn't recognized");
-}
-
-Status NativeRegisterContextLinux_s390x::ReadAllRegisterValues(
- lldb::DataBufferSP &data_sp) {
- Status error;
-
- data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
- if (!data_sp) {
- error.SetErrorStringWithFormat(
- "failed to allocate DataBufferHeap instance of size %" PRIu64,
- REG_CONTEXT_SIZE);
- return error;
- }
-
- uint8_t *dst = data_sp->GetBytes();
- if (dst == nullptr) {
- error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
- " returned a null pointer",
- REG_CONTEXT_SIZE);
- return error;
- }
-
- error = DoReadGPR(dst, sizeof(s390_regs));
- dst += sizeof(s390_regs);
- if (error.Fail())
- return error;
-
- error = DoReadFPR(dst, sizeof(s390_fp_regs));
- dst += sizeof(s390_fp_regs);
- if (error.Fail())
- return error;
-
- // Ignore errors if the regset is unsupported (happens on older kernels).
- DoReadRegisterSet(NT_S390_SYSTEM_CALL, dst, 4);
- dst += 4;
-
- // To enable inferior function calls while the process is stopped in an
- // interrupted system call, we need to clear the system call flag. It will be
- // restored to its original value by WriteAllRegisterValues. Again we ignore
- // error if the regset is unsupported.
- uint32_t system_call = 0;
- DoWriteRegisterSet(NT_S390_SYSTEM_CALL, &system_call, 4);
-
- return error;
-}
-
-Status NativeRegisterContextLinux_s390x::WriteAllRegisterValues(
- const lldb::DataBufferSP &data_sp) {
- Status error;
-
- if (!data_sp) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_s390x::%s invalid data_sp provided",
- __FUNCTION__);
- return error;
- }
-
- if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_s390x::%s data_sp contained mismatched "
- "data size, expected %" PRIu64 ", actual %" PRIu64,
- __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
- return error;
- }
-
- uint8_t *src = data_sp->GetBytes();
- if (src == nullptr) {
- error.SetErrorStringWithFormat("NativeRegisterContextLinux_s390x::%s "
- "DataBuffer::GetBytes() returned a null "
- "pointer",
- __FUNCTION__);
- return error;
- }
-
- error = DoWriteGPR(src, sizeof(s390_regs));
- src += sizeof(s390_regs);
- if (error.Fail())
- return error;
-
- error = DoWriteFPR(src, sizeof(s390_fp_regs));
- src += sizeof(s390_fp_regs);
- if (error.Fail())
- return error;
-
- // Ignore errors if the regset is unsupported (happens on older kernels).
- DoWriteRegisterSet(NT_S390_SYSTEM_CALL, src, 4);
- src += 4;
-
- return error;
-}
-
-Status NativeRegisterContextLinux_s390x::DoReadRegisterValue(
- uint32_t offset, const char *reg_name, uint32_t size,
- RegisterValue &value) {
- return Status("DoReadRegisterValue unsupported");
-}
-
-Status NativeRegisterContextLinux_s390x::DoWriteRegisterValue(
- uint32_t offset, const char *reg_name, const RegisterValue &value) {
- return Status("DoWriteRegisterValue unsupported");
-}
-
-Status NativeRegisterContextLinux_s390x::PeekUserArea(uint32_t offset,
- void *buf,
- size_t buf_size) {
- ptrace_area parea;
- parea.len = buf_size;
- parea.process_addr = (addr_t)buf;
- parea.kernel_addr = offset;
-
- return NativeProcessLinux::PtraceWrapper(PTRACE_PEEKUSR_AREA,
- m_thread.GetID(), &parea);
-}
-
-Status NativeRegisterContextLinux_s390x::PokeUserArea(uint32_t offset,
- const void *buf,
- size_t buf_size) {
- ptrace_area parea;
- parea.len = buf_size;
- parea.process_addr = (addr_t)buf;
- parea.kernel_addr = offset;
-
- return NativeProcessLinux::PtraceWrapper(PTRACE_POKEUSR_AREA,
- m_thread.GetID(), &parea);
-}
-
-Status NativeRegisterContextLinux_s390x::DoReadGPR(void *buf, size_t buf_size) {
- assert(buf_size == sizeof(s390_regs));
- return PeekUserArea(offsetof(user_regs_struct, psw), buf, buf_size);
-}
-
-Status NativeRegisterContextLinux_s390x::DoWriteGPR(void *buf,
- size_t buf_size) {
- assert(buf_size == sizeof(s390_regs));
- return PokeUserArea(offsetof(user_regs_struct, psw), buf, buf_size);
-}
-
-Status NativeRegisterContextLinux_s390x::DoReadFPR(void *buf, size_t buf_size) {
- assert(buf_size == sizeof(s390_fp_regs));
- return PeekUserArea(offsetof(user_regs_struct, fp_regs), buf, buf_size);
-}
-
-Status NativeRegisterContextLinux_s390x::DoWriteFPR(void *buf,
- size_t buf_size) {
- assert(buf_size == sizeof(s390_fp_regs));
- return PokeUserArea(offsetof(user_regs_struct, fp_regs), buf, buf_size);
-}
-
-Status NativeRegisterContextLinux_s390x::DoReadRegisterSet(uint32_t regset,
- void *buf,
- size_t buf_size) {
- struct iovec iov;
- iov.iov_base = buf;
- iov.iov_len = buf_size;
-
- return ReadRegisterSet(&iov, buf_size, regset);
-}
-
-Status NativeRegisterContextLinux_s390x::DoWriteRegisterSet(uint32_t regset,
- const void *buf,
- size_t buf_size) {
- struct iovec iov;
- iov.iov_base = const_cast<void *>(buf);
- iov.iov_len = buf_size;
-
- return WriteRegisterSet(&iov, buf_size, regset);
-}
-
-Status NativeRegisterContextLinux_s390x::IsWatchpointHit(uint32_t wp_index,
- bool &is_hit) {
- per_lowcore_bits per_lowcore;
-
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Status("Watchpoint index out of range");
-
- if (m_watchpoint_addr == LLDB_INVALID_ADDRESS) {
- is_hit = false;
- return Status();
- }
-
- Status error = PeekUserArea(offsetof(user_regs_struct, per_info.lowcore),
- &per_lowcore, sizeof(per_lowcore));
- if (error.Fail()) {
- is_hit = false;
- return error;
- }
-
- is_hit = (per_lowcore.perc_storage_alteration == 1 &&
- per_lowcore.perc_store_real_address == 0);
-
- if (is_hit) {
- // Do not report this watchpoint again.
- memset(&per_lowcore, 0, sizeof(per_lowcore));
- PokeUserArea(offsetof(user_regs_struct, per_info.lowcore), &per_lowcore,
- sizeof(per_lowcore));
- }
-
- return Status();
-}
-
-Status NativeRegisterContextLinux_s390x::GetWatchpointHitIndex(
- uint32_t &wp_index, lldb::addr_t trap_addr) {
- uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
- for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
- bool is_hit;
- Status error = IsWatchpointHit(wp_index, is_hit);
- if (error.Fail()) {
- wp_index = LLDB_INVALID_INDEX32;
- return error;
- } else if (is_hit) {
- return error;
- }
- }
- wp_index = LLDB_INVALID_INDEX32;
- return Status();
-}
-
-Status NativeRegisterContextLinux_s390x::IsWatchpointVacant(uint32_t wp_index,
- bool &is_vacant) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Status("Watchpoint index out of range");
-
- is_vacant = m_watchpoint_addr == LLDB_INVALID_ADDRESS;
-
- return Status();
-}
-
-bool NativeRegisterContextLinux_s390x::ClearHardwareWatchpoint(
- uint32_t wp_index) {
- per_struct per_info;
-
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return false;
-
- Status error = PeekUserArea(offsetof(user_regs_struct, per_info), &per_info,
- sizeof(per_info));
- if (error.Fail())
- return false;
-
- per_info.control_regs.bits.em_storage_alteration = 0;
- per_info.control_regs.bits.storage_alt_space_ctl = 0;
- per_info.starting_addr = 0;
- per_info.ending_addr = 0;
-
- error = PokeUserArea(offsetof(user_regs_struct, per_info), &per_info,
- sizeof(per_info));
- if (error.Fail())
- return false;
-
- m_watchpoint_addr = LLDB_INVALID_ADDRESS;
- return true;
-}
-
-Status NativeRegisterContextLinux_s390x::ClearAllHardwareWatchpoints() {
- if (ClearHardwareWatchpoint(0))
- return Status();
- return Status("Clearing all hardware watchpoints failed.");
-}
-
-uint32_t NativeRegisterContextLinux_s390x::SetHardwareWatchpoint(
- lldb::addr_t addr, size_t size, uint32_t watch_flags) {
- per_struct per_info;
-
- if (watch_flags != 0x1)
- return LLDB_INVALID_INDEX32;
-
- if (m_watchpoint_addr != LLDB_INVALID_ADDRESS)
- return LLDB_INVALID_INDEX32;
-
- Status error = PeekUserArea(offsetof(user_regs_struct, per_info), &per_info,
- sizeof(per_info));
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
-
- per_info.control_regs.bits.em_storage_alteration = 1;
- per_info.control_regs.bits.storage_alt_space_ctl = 1;
- per_info.starting_addr = addr;
- per_info.ending_addr = addr + size - 1;
-
- error = PokeUserArea(offsetof(user_regs_struct, per_info), &per_info,
- sizeof(per_info));
- if (error.Fail())
- return LLDB_INVALID_INDEX32;
-
- m_watchpoint_addr = addr;
- return 0;
-}
-
-lldb::addr_t
-NativeRegisterContextLinux_s390x::GetWatchpointAddress(uint32_t wp_index) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return LLDB_INVALID_ADDRESS;
- return m_watchpoint_addr;
-}
-
-uint32_t NativeRegisterContextLinux_s390x::NumSupportedHardwareWatchpoints() {
- return 1;
-}
-
-#endif // defined(__s390x__) && defined(__linux__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h
deleted file mode 100644
index 57b1a0481512f..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_s390x.h
+++ /dev/null
@@ -1,115 +0,0 @@
-//===-- NativeRegisterContextLinux_s390x.h ----------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__s390x__) && defined(__linux__)
-
-#ifndef lldb_NativeRegisterContextLinux_s390x_h
-#define lldb_NativeRegisterContextLinux_s390x_h
-
-#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
-#include "Plugins/Process/Utility/RegisterContext_s390x.h"
-#include "Plugins/Process/Utility/lldb-s390x-register-enums.h"
-
-namespace lldb_private {
-namespace process_linux {
-
-class NativeProcessLinux;
-
-class NativeRegisterContextLinux_s390x : public NativeRegisterContextLinux {
-public:
- NativeRegisterContextLinux_s390x(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread);
-
- uint32_t GetRegisterSetCount() const override;
-
- const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
-
- uint32_t GetUserRegisterCount() const override;
-
- Status ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) override;
-
- Status WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &reg_value) override;
-
- Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- Status IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
-
- Status GetWatchpointHitIndex(uint32_t &wp_index,
- lldb::addr_t trap_addr) override;
-
- Status IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
-
- bool ClearHardwareWatchpoint(uint32_t wp_index) override;
-
- Status ClearAllHardwareWatchpoints() override;
-
- uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
- uint32_t watch_flags) override;
-
- lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
-
- uint32_t NumSupportedHardwareWatchpoints() override;
-
-protected:
- Status DoReadRegisterValue(uint32_t offset, const char *reg_name,
- uint32_t size, RegisterValue &value) override;
-
- Status DoWriteRegisterValue(uint32_t offset, const char *reg_name,
- const RegisterValue &value) override;
-
- Status DoReadGPR(void *buf, size_t buf_size) override;
-
- Status DoWriteGPR(void *buf, size_t buf_size) override;
-
- Status DoReadFPR(void *buf, size_t buf_size) override;
-
- Status DoWriteFPR(void *buf, size_t buf_size) override;
-
-private:
- // Info about register ranges.
- struct RegInfo {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
-
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
- };
-
- // Private member variables.
- RegInfo m_reg_info;
- lldb::addr_t m_watchpoint_addr;
-
- // Private member methods.
- bool IsRegisterSetAvailable(uint32_t set_index) const;
-
- bool IsGPR(uint32_t reg_index) const;
-
- bool IsFPR(uint32_t reg_index) const;
-
- Status PeekUserArea(uint32_t offset, void *buf, size_t buf_size);
-
- Status PokeUserArea(uint32_t offset, const void *buf, size_t buf_size);
-
- Status DoReadRegisterSet(uint32_t regset, void *buf, size_t buf_size);
-
- Status DoWriteRegisterSet(uint32_t regset, const void *buf, size_t buf_size);
-};
-
-} // namespace process_linux
-} // namespace lldb_private
-
-#endif // #ifndef lldb_NativeRegisterContextLinux_s390x_h
-
-#endif // defined(__s390x__) && defined(__linux__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
deleted file mode 100755
index 50bf29b094df0..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
+++ /dev/null
@@ -1,1213 +0,0 @@
-//===-- NativeRegisterContextLinux_x86_64.cpp ---------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__i386__) || defined(__x86_64__)
-
-#include "NativeRegisterContextLinux_x86_64.h"
-
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Status.h"
-
-#include "Plugins/Process/Utility/RegisterContextLinux_i386.h"
-#include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h"
-
-#include <linux/elf.h>
-
-using namespace lldb_private;
-using namespace lldb_private::process_linux;
-
-// ----------------------------------------------------------------------------
-// Private namespace.
-// ----------------------------------------------------------------------------
-
-namespace {
-// x86 32-bit general purpose registers.
-const uint32_t g_gpr_regnums_i386[] = {
- lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386,
- lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386,
- lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386,
- lldb_gs_i386, lldb_ss_i386, lldb_ds_i386, lldb_es_i386,
- lldb_ax_i386, lldb_bx_i386, lldb_cx_i386, lldb_dx_i386,
- lldb_di_i386, lldb_si_i386, lldb_bp_i386, lldb_sp_i386,
- lldb_ah_i386, lldb_bh_i386, lldb_ch_i386, lldb_dh_i386,
- lldb_al_i386, lldb_bl_i386, lldb_cl_i386, lldb_dl_i386,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) -
- 1 ==
- k_num_gpr_registers_i386,
- "g_gpr_regnums_i386 has wrong number of register infos");
-
-// x86 32-bit floating point registers.
-const uint32_t g_fpu_regnums_i386[] = {
- lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386,
- lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386,
- lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386,
- lldb_st2_i386, lldb_st3_i386, lldb_st4_i386, lldb_st5_i386,
- lldb_st6_i386, lldb_st7_i386, lldb_mm0_i386, lldb_mm1_i386,
- lldb_mm2_i386, lldb_mm3_i386, lldb_mm4_i386, lldb_mm5_i386,
- lldb_mm6_i386, lldb_mm7_i386, lldb_xmm0_i386, lldb_xmm1_i386,
- lldb_xmm2_i386, lldb_xmm3_i386, lldb_xmm4_i386, lldb_xmm5_i386,
- lldb_xmm6_i386, lldb_xmm7_i386,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) -
- 1 ==
- k_num_fpr_registers_i386,
- "g_fpu_regnums_i386 has wrong number of register infos");
-
-// x86 32-bit AVX registers.
-const uint32_t g_avx_regnums_i386[] = {
- lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386,
- lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) -
- 1 ==
- k_num_avx_registers_i386,
- " g_avx_regnums_i386 has wrong number of register infos");
-
-// x64 32-bit MPX registers.
-static const uint32_t g_mpx_regnums_i386[] = {
- lldb_bnd0_i386, lldb_bnd1_i386, lldb_bnd2_i386, lldb_bnd3_i386,
- lldb_bndcfgu_i386, lldb_bndstatus_i386,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-static_assert((sizeof(g_mpx_regnums_i386) / sizeof(g_mpx_regnums_i386[0])) -
- 1 ==
- k_num_mpx_registers_i386,
- "g_mpx_regnums_x86_64 has wrong number of register infos");
-
-// x86 64-bit general purpose registers.
-static const uint32_t g_gpr_regnums_x86_64[] = {
- lldb_rax_x86_64, lldb_rbx_x86_64, lldb_rcx_x86_64, lldb_rdx_x86_64,
- lldb_rdi_x86_64, lldb_rsi_x86_64, lldb_rbp_x86_64, lldb_rsp_x86_64,
- lldb_r8_x86_64, lldb_r9_x86_64, lldb_r10_x86_64, lldb_r11_x86_64,
- lldb_r12_x86_64, lldb_r13_x86_64, lldb_r14_x86_64, lldb_r15_x86_64,
- lldb_rip_x86_64, lldb_rflags_x86_64, lldb_cs_x86_64, lldb_fs_x86_64,
- lldb_gs_x86_64, lldb_ss_x86_64, lldb_ds_x86_64, lldb_es_x86_64,
- lldb_eax_x86_64, lldb_ebx_x86_64, lldb_ecx_x86_64, lldb_edx_x86_64,
- lldb_edi_x86_64, lldb_esi_x86_64, lldb_ebp_x86_64, lldb_esp_x86_64,
- lldb_r8d_x86_64, // Low 32 bits or r8
- lldb_r9d_x86_64, // Low 32 bits or r9
- lldb_r10d_x86_64, // Low 32 bits or r10
- lldb_r11d_x86_64, // Low 32 bits or r11
- lldb_r12d_x86_64, // Low 32 bits or r12
- lldb_r13d_x86_64, // Low 32 bits or r13
- lldb_r14d_x86_64, // Low 32 bits or r14
- lldb_r15d_x86_64, // Low 32 bits or r15
- lldb_ax_x86_64, lldb_bx_x86_64, lldb_cx_x86_64, lldb_dx_x86_64,
- lldb_di_x86_64, lldb_si_x86_64, lldb_bp_x86_64, lldb_sp_x86_64,
- lldb_r8w_x86_64, // Low 16 bits or r8
- lldb_r9w_x86_64, // Low 16 bits or r9
- lldb_r10w_x86_64, // Low 16 bits or r10
- lldb_r11w_x86_64, // Low 16 bits or r11
- lldb_r12w_x86_64, // Low 16 bits or r12
- lldb_r13w_x86_64, // Low 16 bits or r13
- lldb_r14w_x86_64, // Low 16 bits or r14
- lldb_r15w_x86_64, // Low 16 bits or r15
- lldb_ah_x86_64, lldb_bh_x86_64, lldb_ch_x86_64, lldb_dh_x86_64,
- lldb_al_x86_64, lldb_bl_x86_64, lldb_cl_x86_64, lldb_dl_x86_64,
- lldb_dil_x86_64, lldb_sil_x86_64, lldb_bpl_x86_64, lldb_spl_x86_64,
- lldb_r8l_x86_64, // Low 8 bits or r8
- lldb_r9l_x86_64, // Low 8 bits or r9
- lldb_r10l_x86_64, // Low 8 bits or r10
- lldb_r11l_x86_64, // Low 8 bits or r11
- lldb_r12l_x86_64, // Low 8 bits or r12
- lldb_r13l_x86_64, // Low 8 bits or r13
- lldb_r14l_x86_64, // Low 8 bits or r14
- lldb_r15l_x86_64, // Low 8 bits or r15
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) -
- 1 ==
- k_num_gpr_registers_x86_64,
- "g_gpr_regnums_x86_64 has wrong number of register infos");
-
-// x86 64-bit floating point registers.
-static const uint32_t g_fpu_regnums_x86_64[] = {
- lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64,
- lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64,
- lldb_foseg_x86_64, lldb_fooff_x86_64, lldb_mxcsr_x86_64,
- lldb_mxcsrmask_x86_64, lldb_st0_x86_64, lldb_st1_x86_64,
- lldb_st2_x86_64, lldb_st3_x86_64, lldb_st4_x86_64,
- lldb_st5_x86_64, lldb_st6_x86_64, lldb_st7_x86_64,
- lldb_mm0_x86_64, lldb_mm1_x86_64, lldb_mm2_x86_64,
- lldb_mm3_x86_64, lldb_mm4_x86_64, lldb_mm5_x86_64,
- lldb_mm6_x86_64, lldb_mm7_x86_64, lldb_xmm0_x86_64,
- lldb_xmm1_x86_64, lldb_xmm2_x86_64, lldb_xmm3_x86_64,
- lldb_xmm4_x86_64, lldb_xmm5_x86_64, lldb_xmm6_x86_64,
- lldb_xmm7_x86_64, lldb_xmm8_x86_64, lldb_xmm9_x86_64,
- lldb_xmm10_x86_64, lldb_xmm11_x86_64, lldb_xmm12_x86_64,
- lldb_xmm13_x86_64, lldb_xmm14_x86_64, lldb_xmm15_x86_64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) -
- 1 ==
- k_num_fpr_registers_x86_64,
- "g_fpu_regnums_x86_64 has wrong number of register infos");
-
-// x86 64-bit AVX registers.
-static const uint32_t g_avx_regnums_x86_64[] = {
- lldb_ymm0_x86_64, lldb_ymm1_x86_64, lldb_ymm2_x86_64, lldb_ymm3_x86_64,
- lldb_ymm4_x86_64, lldb_ymm5_x86_64, lldb_ymm6_x86_64, lldb_ymm7_x86_64,
- lldb_ymm8_x86_64, lldb_ymm9_x86_64, lldb_ymm10_x86_64, lldb_ymm11_x86_64,
- lldb_ymm12_x86_64, lldb_ymm13_x86_64, lldb_ymm14_x86_64, lldb_ymm15_x86_64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) -
- 1 ==
- k_num_avx_registers_x86_64,
- "g_avx_regnums_x86_64 has wrong number of register infos");
-
-// x86 64-bit MPX registers.
-static const uint32_t g_mpx_regnums_x86_64[] = {
- lldb_bnd0_x86_64, lldb_bnd1_x86_64, lldb_bnd2_x86_64,
- lldb_bnd3_x86_64, lldb_bndcfgu_x86_64, lldb_bndstatus_x86_64,
- LLDB_INVALID_REGNUM // register sets need to end with this flag
-};
-static_assert((sizeof(g_mpx_regnums_x86_64) / sizeof(g_mpx_regnums_x86_64[0])) -
- 1 ==
- k_num_mpx_registers_x86_64,
- "g_mpx_regnums_x86_64 has wrong number of register infos");
-
-// Number of register sets provided by this context.
-enum { k_num_extended_register_sets = 2, k_num_register_sets = 4 };
-
-// Register sets for x86 32-bit.
-static const RegisterSet g_reg_sets_i386[k_num_register_sets] = {
- {"General Purpose Registers", "gpr", k_num_gpr_registers_i386,
- g_gpr_regnums_i386},
- {"Floating Point Registers", "fpu", k_num_fpr_registers_i386,
- g_fpu_regnums_i386},
- {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386,
- g_avx_regnums_i386},
- { "Memory Protection Extensions", "mpx", k_num_mpx_registers_i386,
- g_mpx_regnums_i386}};
-
-// Register sets for x86 64-bit.
-static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = {
- {"General Purpose Registers", "gpr", k_num_gpr_registers_x86_64,
- g_gpr_regnums_x86_64},
- {"Floating Point Registers", "fpu", k_num_fpr_registers_x86_64,
- g_fpu_regnums_x86_64},
- {"Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64,
- g_avx_regnums_x86_64},
- { "Memory Protection Extensions", "mpx", k_num_mpx_registers_x86_64,
- g_mpx_regnums_x86_64}};
-}
-
-#define REG_CONTEXT_SIZE (GetRegisterInfoInterface().GetGPRSize() + sizeof(FPR))
-
-// ----------------------------------------------------------------------------
-// Required ptrace defines.
-// ----------------------------------------------------------------------------
-
-// Support ptrace extensions even when compiled without required kernel support
-#ifndef NT_X86_XSTATE
-#define NT_X86_XSTATE 0x202
-#endif
-#ifndef NT_PRXFPREG
-#define NT_PRXFPREG 0x46e62b7f
-#endif
-
-// On x86_64 NT_PRFPREG is used to access the FXSAVE area. On i386, we need to
-// use NT_PRXFPREG.
-static inline unsigned int fxsr_regset(const ArchSpec &arch) {
- return arch.GetAddressByteSize() == 8 ? NT_PRFPREG : NT_PRXFPREG;
-}
-
-// ----------------------------------------------------------------------------
-// Required MPX define.
-// ----------------------------------------------------------------------------
-
-// Support MPX extensions also if compiled with compiler without MPX support.
-#ifndef bit_MPX
-#define bit_MPX 0x4000
-#endif
-
-// ----------------------------------------------------------------------------
-// XCR0 extended register sets masks.
-// ----------------------------------------------------------------------------
-#define mask_XSTATE_AVX (1ULL << 2)
-#define mask_XSTATE_BNDREGS (1ULL << 3)
-#define mask_XSTATE_BNDCFG (1ULL << 4)
-#define mask_XSTATE_MPX (mask_XSTATE_BNDREGS | mask_XSTATE_BNDCFG)
-
-std::unique_ptr<NativeRegisterContextLinux>
-NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
- return std::unique_ptr<NativeRegisterContextLinux>(
- new NativeRegisterContextLinux_x86_64(target_arch, native_thread));
-}
-
-// ----------------------------------------------------------------------------
-// NativeRegisterContextLinux_x86_64 members.
-// ----------------------------------------------------------------------------
-
-static RegisterInfoInterface *
-CreateRegisterInfoInterface(const ArchSpec &target_arch) {
- if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
- // 32-bit hosts run with a RegisterContextLinux_i386 context.
- return new RegisterContextLinux_i386(target_arch);
- } else {
- assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
- "Register setting path assumes this is a 64-bit host");
- // X86_64 hosts know how to work with 64-bit and 32-bit EXEs using the
- // x86_64 register context.
- return new RegisterContextLinux_x86_64(target_arch);
- }
-}
-
-NativeRegisterContextLinux_x86_64::NativeRegisterContextLinux_x86_64(
- const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
- : NativeRegisterContextLinux(native_thread,
- CreateRegisterInfoInterface(target_arch)),
- m_xstate_type(XStateType::Invalid), m_fpr(), m_iovec(), m_ymm_set(),
- m_mpx_set(), m_reg_info(), m_gpr_x86_64() {
- // Set up data about ranges of valid registers.
- switch (target_arch.GetMachine()) {
- case llvm::Triple::x86:
- m_reg_info.num_registers = k_num_registers_i386;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_i386;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_i386;
- m_reg_info.num_avx_registers = k_num_avx_registers_i386;
- m_reg_info.num_mpx_registers = k_num_mpx_registers_i386;
- m_reg_info.last_gpr = k_last_gpr_i386;
- m_reg_info.first_fpr = k_first_fpr_i386;
- m_reg_info.last_fpr = k_last_fpr_i386;
- m_reg_info.first_st = lldb_st0_i386;
- m_reg_info.last_st = lldb_st7_i386;
- m_reg_info.first_mm = lldb_mm0_i386;
- m_reg_info.last_mm = lldb_mm7_i386;
- m_reg_info.first_xmm = lldb_xmm0_i386;
- m_reg_info.last_xmm = lldb_xmm7_i386;
- m_reg_info.first_ymm = lldb_ymm0_i386;
- m_reg_info.last_ymm = lldb_ymm7_i386;
- m_reg_info.first_mpxr = lldb_bnd0_i386;
- m_reg_info.last_mpxr = lldb_bnd3_i386;
- m_reg_info.first_mpxc = lldb_bndcfgu_i386;
- m_reg_info.last_mpxc = lldb_bndstatus_i386;
- m_reg_info.first_dr = lldb_dr0_i386;
- m_reg_info.gpr_flags = lldb_eflags_i386;
- break;
- case llvm::Triple::x86_64:
- m_reg_info.num_registers = k_num_registers_x86_64;
- m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64;
- m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64;
- m_reg_info.num_avx_registers = k_num_avx_registers_x86_64;
- m_reg_info.num_mpx_registers = k_num_mpx_registers_x86_64;
- m_reg_info.last_gpr = k_last_gpr_x86_64;
- m_reg_info.first_fpr = k_first_fpr_x86_64;
- m_reg_info.last_fpr = k_last_fpr_x86_64;
- m_reg_info.first_st = lldb_st0_x86_64;
- m_reg_info.last_st = lldb_st7_x86_64;
- m_reg_info.first_mm = lldb_mm0_x86_64;
- m_reg_info.last_mm = lldb_mm7_x86_64;
- m_reg_info.first_xmm = lldb_xmm0_x86_64;
- m_reg_info.last_xmm = lldb_xmm15_x86_64;
- m_reg_info.first_ymm = lldb_ymm0_x86_64;
- m_reg_info.last_ymm = lldb_ymm15_x86_64;
- m_reg_info.first_mpxr = lldb_bnd0_x86_64;
- m_reg_info.last_mpxr = lldb_bnd3_x86_64;
- m_reg_info.first_mpxc = lldb_bndcfgu_x86_64;
- m_reg_info.last_mpxc = lldb_bndstatus_x86_64;
- m_reg_info.first_dr = lldb_dr0_x86_64;
- m_reg_info.gpr_flags = lldb_rflags_x86_64;
- break;
- default:
- assert(false && "Unhandled target architecture.");
- break;
- }
-
- // Initialize m_iovec to point to the buffer and buffer size using the
- // conventions of Berkeley style UIO structures, as required by PTRACE
- // extensions.
- m_iovec.iov_base = &m_fpr;
- m_iovec.iov_len = sizeof(m_fpr);
-
- // Clear out the FPR state.
- ::memset(&m_fpr, 0, sizeof(m_fpr));
-
- // Store byte offset of fctrl (i.e. first register of FPR)
- const RegisterInfo *reg_info_fctrl = GetRegisterInfoByName("fctrl");
- m_fctrl_offset_in_userarea = reg_info_fctrl->byte_offset;
-}
-
-// CONSIDER after local and llgs debugging are merged, register set support can
-// be moved into a base x86-64 class with IsRegisterSetAvailable made virtual.
-uint32_t NativeRegisterContextLinux_x86_64::GetRegisterSetCount() const {
- uint32_t sets = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
- if (IsRegisterSetAvailable(set_index))
- ++sets;
- }
-
- return sets;
-}
-
-uint32_t NativeRegisterContextLinux_x86_64::GetUserRegisterCount() const {
- uint32_t count = 0;
- for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) {
- const RegisterSet *set = GetRegisterSet(set_index);
- if (set)
- count += set->num_registers;
- }
- return count;
-}
-
-const RegisterSet *
-NativeRegisterContextLinux_x86_64::GetRegisterSet(uint32_t set_index) const {
- if (!IsRegisterSetAvailable(set_index))
- return nullptr;
-
- switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
- case llvm::Triple::x86:
- return &g_reg_sets_i386[set_index];
- case llvm::Triple::x86_64:
- return &g_reg_sets_x86_64[set_index];
- default:
- assert(false && "Unhandled target architecture.");
- return nullptr;
- }
-
- return nullptr;
-}
-
-Status
-NativeRegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) {
- Status error;
-
- if (!reg_info) {
- error.SetErrorString("reg_info NULL");
- return error;
- }
-
- const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg == LLDB_INVALID_REGNUM) {
- // This is likely an internal register for lldb use only and should not be
- // directly queried.
- error.SetErrorStringWithFormat("register \"%s\" is an internal-only lldb "
- "register, cannot read directly",
- reg_info->name);
- return error;
- }
-
- if (IsFPR(reg) || IsAVX(reg) || IsMPX(reg)) {
- error = ReadFPR();
- if (error.Fail())
- return error;
- } else {
- uint32_t full_reg = reg;
- bool is_subreg = reg_info->invalidate_regs &&
- (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
-
- if (is_subreg) {
- // Read the full aligned 64-bit register.
- full_reg = reg_info->invalidate_regs[0];
- }
-
- error = ReadRegisterRaw(full_reg, reg_value);
-
- if (error.Success()) {
- // If our read was not aligned (for ah,bh,ch,dh), shift our returned
- // value one byte to the right.
- if (is_subreg && (reg_info->byte_offset & 0x1))
- reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8);
-
- // If our return byte size was greater than the return value reg size,
- // then use the type specified by reg_info rather than the uint64_t
- // default
- if (reg_value.GetByteSize() > reg_info->byte_size)
- reg_value.SetType(reg_info);
- }
- return error;
- }
-
- if (reg_info->encoding == lldb::eEncodingVector) {
- lldb::ByteOrder byte_order = GetByteOrder();
-
- if (byte_order != lldb::eByteOrderInvalid) {
- if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
- reg_value.SetBytes(m_fpr.fxsave.stmm[reg - m_reg_info.first_st].bytes,
- reg_info->byte_size, byte_order);
- if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
- reg_value.SetBytes(m_fpr.fxsave.stmm[reg - m_reg_info.first_mm].bytes,
- reg_info->byte_size, byte_order);
- if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
- reg_value.SetBytes(m_fpr.fxsave.xmm[reg - m_reg_info.first_xmm].bytes,
- reg_info->byte_size, byte_order);
- if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm) {
- // Concatenate ymm using the register halves in xmm.bytes and
- // ymmh.bytes
- if (CopyXSTATEtoYMM(reg, byte_order))
- reg_value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
- reg_info->byte_size, byte_order);
- else {
- error.SetErrorString("failed to copy ymm register value");
- return error;
- }
- }
- if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
- if (CopyXSTATEtoMPX(reg))
- reg_value.SetBytes(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
- reg_info->byte_size, byte_order);
- else {
- error.SetErrorString("failed to copy mpx register value");
- return error;
- }
- }
- if (reg >= m_reg_info.first_mpxc && reg <= m_reg_info.last_mpxc) {
- if (CopyXSTATEtoMPX(reg))
- reg_value.SetBytes(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
- reg_info->byte_size, byte_order);
- else {
- error.SetErrorString("failed to copy mpx register value");
- return error;
- }
- }
-
- if (reg_value.GetType() != RegisterValue::eTypeBytes)
- error.SetErrorString(
- "write failed - type was expected to be RegisterValue::eTypeBytes");
-
- return error;
- }
-
- error.SetErrorString("byte order is invalid");
- return error;
- }
-
- // Get pointer to m_fpr.fxsave variable and set the data from it.
-
- // Byte offsets of all registers are calculated wrt 'UserArea' structure.
- // However, ReadFPR() reads fpu registers {using ptrace(PTRACE_GETFPREGS,..)}
- // and stores them in 'm_fpr' (of type FPR structure). To extract values of
- // fpu registers, m_fpr should be read at byte offsets calculated wrt to FPR
- // structure.
-
- // Since, FPR structure is also one of the member of UserArea structure.
- // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
- // byte_offset(fctrl wrt UserArea)
- assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) < sizeof(m_fpr));
- uint8_t *src =
- (uint8_t *)&m_fpr + reg_info->byte_offset - m_fctrl_offset_in_userarea;
- switch (reg_info->byte_size) {
- case 1:
- reg_value.SetUInt8(*(uint8_t *)src);
- break;
- case 2:
- reg_value.SetUInt16(*(uint16_t *)src);
- break;
- case 4:
- reg_value.SetUInt32(*(uint32_t *)src);
- break;
- case 8:
- reg_value.SetUInt64(*(uint64_t *)src);
- break;
- default:
- assert(false && "Unhandled data size.");
- error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32,
- reg_info->byte_size);
- break;
- }
-
- return error;
-}
-
-void NativeRegisterContextLinux_x86_64::UpdateXSTATEforWrite(
- uint32_t reg_index) {
- XSAVE_HDR::XFeature &xstate_bv = m_fpr.xsave.header.xstate_bv;
- if (IsFPR(reg_index)) {
- // IsFPR considers both %st and %xmm registers as floating point, but these
- // map to two features. Set both flags, just in case.
- xstate_bv |= XSAVE_HDR::XFeature::FP | XSAVE_HDR::XFeature::SSE;
- } else if (IsAVX(reg_index)) {
- // Lower bytes of some %ymm registers are shared with %xmm registers.
- xstate_bv |= XSAVE_HDR::XFeature::YMM | XSAVE_HDR::XFeature::SSE;
- } else if (IsMPX(reg_index)) {
- // MPX registers map to two XSAVE features.
- xstate_bv |= XSAVE_HDR::XFeature::BNDREGS | XSAVE_HDR::XFeature::BNDCSR;
- }
-}
-
-Status NativeRegisterContextLinux_x86_64::WriteRegister(
- const RegisterInfo *reg_info, const RegisterValue &reg_value) {
- assert(reg_info && "reg_info is null");
-
- const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB];
- if (reg_index == LLDB_INVALID_REGNUM)
- return Status("no lldb regnum for %s", reg_info && reg_info->name
- ? reg_info->name
- : "<unknown register>");
-
- UpdateXSTATEforWrite(reg_index);
-
- if (IsGPR(reg_index))
- return WriteRegisterRaw(reg_index, reg_value);
-
- if (IsFPR(reg_index) || IsAVX(reg_index) || IsMPX(reg_index)) {
- if (reg_info->encoding == lldb::eEncodingVector) {
- if (reg_index >= m_reg_info.first_st && reg_index <= m_reg_info.last_st)
- ::memcpy(m_fpr.fxsave.stmm[reg_index - m_reg_info.first_st].bytes,
- reg_value.GetBytes(), reg_value.GetByteSize());
-
- if (reg_index >= m_reg_info.first_mm && reg_index <= m_reg_info.last_mm)
- ::memcpy(m_fpr.fxsave.stmm[reg_index - m_reg_info.first_mm].bytes,
- reg_value.GetBytes(), reg_value.GetByteSize());
-
- if (reg_index >= m_reg_info.first_xmm && reg_index <= m_reg_info.last_xmm)
- ::memcpy(m_fpr.fxsave.xmm[reg_index - m_reg_info.first_xmm].bytes,
- reg_value.GetBytes(), reg_value.GetByteSize());
-
- if (reg_index >= m_reg_info.first_ymm &&
- reg_index <= m_reg_info.last_ymm) {
- // Store ymm register content, and split into the register halves in
- // xmm.bytes and ymmh.bytes
- ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
- reg_value.GetBytes(), reg_value.GetByteSize());
- if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
- return Status("CopyYMMtoXSTATE() failed");
- }
-
- if (reg_index >= m_reg_info.first_mpxr &&
- reg_index <= m_reg_info.last_mpxr) {
- ::memcpy(m_mpx_set.mpxr[reg_index - m_reg_info.first_mpxr].bytes,
- reg_value.GetBytes(), reg_value.GetByteSize());
- if (!CopyMPXtoXSTATE(reg_index))
- return Status("CopyMPXtoXSTATE() failed");
- }
-
- if (reg_index >= m_reg_info.first_mpxc &&
- reg_index <= m_reg_info.last_mpxc) {
- ::memcpy(m_mpx_set.mpxc[reg_index - m_reg_info.first_mpxc].bytes,
- reg_value.GetBytes(), reg_value.GetByteSize());
- if (!CopyMPXtoXSTATE(reg_index))
- return Status("CopyMPXtoXSTATE() failed");
- }
- } else {
- // Get pointer to m_fpr.fxsave variable and set the data to it.
-
- // Byte offsets of all registers are calculated wrt 'UserArea' structure.
- // However, WriteFPR() takes m_fpr (of type FPR structure) and writes
- // only fpu registers using ptrace(PTRACE_SETFPREGS,..) API. Hence fpu
- // registers should be written in m_fpr at byte offsets calculated wrt
- // FPR structure.
-
- // Since, FPR structure is also one of the member of UserArea structure.
- // byte_offset(fpu wrt FPR) = byte_offset(fpu wrt UserArea) -
- // byte_offset(fctrl wrt UserArea)
- assert((reg_info->byte_offset - m_fctrl_offset_in_userarea) <
- sizeof(m_fpr));
- uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset -
- m_fctrl_offset_in_userarea;
- switch (reg_info->byte_size) {
- case 1:
- *(uint8_t *)dst = reg_value.GetAsUInt8();
- break;
- case 2:
- *(uint16_t *)dst = reg_value.GetAsUInt16();
- break;
- case 4:
- *(uint32_t *)dst = reg_value.GetAsUInt32();
- break;
- case 8:
- *(uint64_t *)dst = reg_value.GetAsUInt64();
- break;
- default:
- assert(false && "Unhandled data size.");
- return Status("unhandled register data size %" PRIu32,
- reg_info->byte_size);
- }
- }
-
- Status error = WriteFPR();
- if (error.Fail())
- return error;
-
- if (IsAVX(reg_index)) {
- if (!CopyYMMtoXSTATE(reg_index, GetByteOrder()))
- return Status("CopyYMMtoXSTATE() failed");
- }
-
- if (IsMPX(reg_index)) {
- if (!CopyMPXtoXSTATE(reg_index))
- return Status("CopyMPXtoXSTATE() failed");
- }
- return Status();
- }
- return Status("failed - register wasn't recognized to be a GPR or an FPR, "
- "write strategy unknown");
-}
-
-Status NativeRegisterContextLinux_x86_64::ReadAllRegisterValues(
- lldb::DataBufferSP &data_sp) {
- Status error;
-
- data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
- error = ReadGPR();
- if (error.Fail())
- return error;
-
- error = ReadFPR();
- if (error.Fail())
- return error;
-
- uint8_t *dst = data_sp->GetBytes();
- ::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
- dst += GetRegisterInfoInterface().GetGPRSize();
- if (m_xstate_type == XStateType::FXSAVE)
- ::memcpy(dst, &m_fpr.fxsave, sizeof(m_fpr.fxsave));
- else if (m_xstate_type == XStateType::XSAVE) {
- lldb::ByteOrder byte_order = GetByteOrder();
-
- if (IsCPUFeatureAvailable(RegSet::avx)) {
- // Assemble the YMM register content from the register halves.
- for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
- ++reg) {
- if (!CopyXSTATEtoYMM(reg, byte_order)) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_x86_64::%s "
- "CopyXSTATEtoYMM() failed for reg num "
- "%" PRIu32,
- __FUNCTION__, reg);
- return error;
- }
- }
- }
-
- if (IsCPUFeatureAvailable(RegSet::mpx)) {
- for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
- ++reg) {
- if (!CopyXSTATEtoMPX(reg)) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_x86_64::%s "
- "CopyXSTATEtoMPX() failed for reg num "
- "%" PRIu32,
- __FUNCTION__, reg);
- return error;
- }
- }
- }
- // Copy the extended register state including the assembled ymm registers.
- ::memcpy(dst, &m_fpr, sizeof(m_fpr));
- } else {
- assert(false && "how do we save the floating point registers?");
- error.SetErrorString("unsure how to save the floating point registers");
- }
- /** The following code is specific to Linux x86 based architectures,
- * where the register orig_eax (32 bit)/orig_rax (64 bit) is set to
- * -1 to solve the bug 23659, such a setting prevents the automatic
- * decrement of the instruction pointer which was causing the SIGILL
- * exception.
- * **/
-
- RegisterValue value((uint64_t)-1);
- const RegisterInfo *reg_info =
- GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_eax");
- if (reg_info == nullptr)
- reg_info = GetRegisterInfoInterface().GetDynamicRegisterInfo("orig_rax");
-
- if (reg_info != nullptr)
- return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, value);
-
- return error;
-}
-
-Status NativeRegisterContextLinux_x86_64::WriteAllRegisterValues(
- const lldb::DataBufferSP &data_sp) {
- Status error;
-
- if (!data_sp) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided",
- __FUNCTION__);
- return error;
- }
-
- if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
- error.SetErrorStringWithFormatv(
- "data_sp contained mismatched data size, expected {0}, actual {1}",
- REG_CONTEXT_SIZE, data_sp->GetByteSize());
- return error;
- }
-
- uint8_t *src = data_sp->GetBytes();
- if (src == nullptr) {
- error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s "
- "DataBuffer::GetBytes() returned a null "
- "pointer",
- __FUNCTION__);
- return error;
- }
- ::memcpy(&m_gpr_x86_64, src, GetRegisterInfoInterface().GetGPRSize());
-
- error = WriteGPR();
- if (error.Fail())
- return error;
-
- src += GetRegisterInfoInterface().GetGPRSize();
- if (m_xstate_type == XStateType::FXSAVE)
- ::memcpy(&m_fpr.fxsave, src, sizeof(m_fpr.fxsave));
- else if (m_xstate_type == XStateType::XSAVE)
- ::memcpy(&m_fpr.xsave, src, sizeof(m_fpr.xsave));
-
- error = WriteFPR();
- if (error.Fail())
- return error;
-
- if (m_xstate_type == XStateType::XSAVE) {
- lldb::ByteOrder byte_order = GetByteOrder();
-
- if (IsCPUFeatureAvailable(RegSet::avx)) {
- // Parse the YMM register content from the register halves.
- for (uint32_t reg = m_reg_info.first_ymm; reg <= m_reg_info.last_ymm;
- ++reg) {
- if (!CopyYMMtoXSTATE(reg, byte_order)) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_x86_64::%s "
- "CopyYMMtoXSTATE() failed for reg num "
- "%" PRIu32,
- __FUNCTION__, reg);
- return error;
- }
- }
- }
-
- if (IsCPUFeatureAvailable(RegSet::mpx)) {
- for (uint32_t reg = m_reg_info.first_mpxr; reg <= m_reg_info.last_mpxc;
- ++reg) {
- if (!CopyMPXtoXSTATE(reg)) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_x86_64::%s "
- "CopyMPXtoXSTATE() failed for reg num "
- "%" PRIu32,
- __FUNCTION__, reg);
- return error;
- }
- }
- }
- }
-
- return error;
-}
-
-bool NativeRegisterContextLinux_x86_64::IsCPUFeatureAvailable(
- RegSet feature_code) const {
- if (m_xstate_type == XStateType::Invalid) {
- if (const_cast<NativeRegisterContextLinux_x86_64 *>(this)->ReadFPR().Fail())
- return false;
- }
- switch (feature_code) {
- case RegSet::gpr:
- case RegSet::fpu:
- return true;
- case RegSet::avx: // Check if CPU has AVX and if there is kernel support, by
- // reading in the XCR0 area of XSAVE.
- if ((m_fpr.xsave.i387.xcr0 & mask_XSTATE_AVX) == mask_XSTATE_AVX)
- return true;
- break;
- case RegSet::mpx: // Check if CPU has MPX and if there is kernel support, by
- // reading in the XCR0 area of XSAVE.
- if ((m_fpr.xsave.i387.xcr0 & mask_XSTATE_MPX) == mask_XSTATE_MPX)
- return true;
- break;
- }
- return false;
-}
-
-bool NativeRegisterContextLinux_x86_64::IsRegisterSetAvailable(
- uint32_t set_index) const {
- uint32_t num_sets = k_num_register_sets - k_num_extended_register_sets;
-
- switch (static_cast<RegSet>(set_index)) {
- case RegSet::gpr:
- case RegSet::fpu:
- return (set_index < num_sets);
- case RegSet::avx:
- return IsCPUFeatureAvailable(RegSet::avx);
- case RegSet::mpx:
- return IsCPUFeatureAvailable(RegSet::mpx);
- }
- return false;
-}
-
-bool NativeRegisterContextLinux_x86_64::IsGPR(uint32_t reg_index) const {
- // GPRs come first.
- return reg_index <= m_reg_info.last_gpr;
-}
-
-bool NativeRegisterContextLinux_x86_64::IsFPR(uint32_t reg_index) const {
- return (m_reg_info.first_fpr <= reg_index &&
- reg_index <= m_reg_info.last_fpr);
-}
-
-Status NativeRegisterContextLinux_x86_64::WriteFPR() {
- switch (m_xstate_type) {
- case XStateType::FXSAVE:
- return WriteRegisterSet(
- &m_iovec, sizeof(m_fpr.fxsave),
- fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
- case XStateType::XSAVE:
- return WriteRegisterSet(&m_iovec, sizeof(m_fpr.xsave), NT_X86_XSTATE);
- default:
- return Status("Unrecognized FPR type.");
- }
-}
-
-bool NativeRegisterContextLinux_x86_64::IsAVX(uint32_t reg_index) const {
- if (!IsCPUFeatureAvailable(RegSet::avx))
- return false;
- return (m_reg_info.first_ymm <= reg_index &&
- reg_index <= m_reg_info.last_ymm);
-}
-
-bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoYMM(
- uint32_t reg_index, lldb::ByteOrder byte_order) {
- if (!IsAVX(reg_index))
- return false;
-
- if (byte_order == lldb::eByteOrderLittle) {
- ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
- m_fpr.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
- sizeof(XMMReg));
- ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes +
- sizeof(XMMReg),
- m_fpr.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
- sizeof(YMMHReg));
- return true;
- }
-
- if (byte_order == lldb::eByteOrderBig) {
- ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes +
- sizeof(XMMReg),
- m_fpr.fxsave.xmm[reg_index - m_reg_info.first_ymm].bytes,
- sizeof(XMMReg));
- ::memcpy(m_ymm_set.ymm[reg_index - m_reg_info.first_ymm].bytes,
- m_fpr.xsave.ymmh[reg_index - m_reg_info.first_ymm].bytes,
- sizeof(YMMHReg));
- return true;
- }
- return false; // unsupported or invalid byte order
-}
-
-bool NativeRegisterContextLinux_x86_64::CopyYMMtoXSTATE(
- uint32_t reg, lldb::ByteOrder byte_order) {
- if (!IsAVX(reg))
- return false;
-
- if (byte_order == lldb::eByteOrderLittle) {
- ::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(XMMReg));
- ::memcpy(m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
- sizeof(YMMHReg));
- return true;
- }
-
- if (byte_order == lldb::eByteOrderBig) {
- ::memcpy(m_fpr.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
- sizeof(XMMReg));
- ::memcpy(m_fpr.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
- m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, sizeof(YMMHReg));
- return true;
- }
- return false; // unsupported or invalid byte order
-}
-
-void *NativeRegisterContextLinux_x86_64::GetFPRBuffer() {
- switch (m_xstate_type) {
- case XStateType::FXSAVE:
- return &m_fpr.fxsave;
- case XStateType::XSAVE:
- return &m_iovec;
- default:
- return nullptr;
- }
-}
-
-size_t NativeRegisterContextLinux_x86_64::GetFPRSize() {
- switch (m_xstate_type) {
- case XStateType::FXSAVE:
- return sizeof(m_fpr.fxsave);
- case XStateType::XSAVE:
- return sizeof(m_iovec);
- default:
- return 0;
- }
-}
-
-Status NativeRegisterContextLinux_x86_64::ReadFPR() {
- Status error;
-
- // Probe XSAVE and if it is not supported fall back to FXSAVE.
- if (m_xstate_type != XStateType::FXSAVE) {
- error = ReadRegisterSet(&m_iovec, sizeof(m_fpr.xsave), NT_X86_XSTATE);
- if (!error.Fail()) {
- m_xstate_type = XStateType::XSAVE;
- return error;
- }
- }
- error = ReadRegisterSet(
- &m_iovec, sizeof(m_fpr.xsave),
- fxsr_regset(GetRegisterInfoInterface().GetTargetArchitecture()));
- if (!error.Fail()) {
- m_xstate_type = XStateType::FXSAVE;
- return error;
- }
- return Status("Unrecognized FPR type.");
-}
-
-bool NativeRegisterContextLinux_x86_64::IsMPX(uint32_t reg_index) const {
- if (!IsCPUFeatureAvailable(RegSet::mpx))
- return false;
- return (m_reg_info.first_mpxr <= reg_index &&
- reg_index <= m_reg_info.last_mpxc);
-}
-
-bool NativeRegisterContextLinux_x86_64::CopyXSTATEtoMPX(uint32_t reg) {
- if (!IsMPX(reg))
- return false;
-
- if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
- ::memcpy(m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes,
- m_fpr.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
- sizeof(MPXReg));
- } else {
- ::memcpy(m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes,
- m_fpr.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
- sizeof(MPXCsr));
- }
- return true;
-}
-
-bool NativeRegisterContextLinux_x86_64::CopyMPXtoXSTATE(uint32_t reg) {
- if (!IsMPX(reg))
- return false;
-
- if (reg >= m_reg_info.first_mpxr && reg <= m_reg_info.last_mpxr) {
- ::memcpy(m_fpr.xsave.mpxr[reg - m_reg_info.first_mpxr].bytes,
- m_mpx_set.mpxr[reg - m_reg_info.first_mpxr].bytes, sizeof(MPXReg));
- } else {
- ::memcpy(m_fpr.xsave.mpxc[reg - m_reg_info.first_mpxc].bytes,
- m_mpx_set.mpxc[reg - m_reg_info.first_mpxc].bytes, sizeof(MPXCsr));
- }
- return true;
-}
-
-Status NativeRegisterContextLinux_x86_64::IsWatchpointHit(uint32_t wp_index,
- bool &is_hit) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Status("Watchpoint index out of range");
-
- RegisterValue reg_value;
- Status error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
- if (error.Fail()) {
- is_hit = false;
- return error;
- }
-
- uint64_t status_bits = reg_value.GetAsUInt64();
-
- is_hit = status_bits & (1 << wp_index);
-
- return error;
-}
-
-Status NativeRegisterContextLinux_x86_64::GetWatchpointHitIndex(
- uint32_t &wp_index, lldb::addr_t trap_addr) {
- uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
- for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) {
- bool is_hit;
- Status error = IsWatchpointHit(wp_index, is_hit);
- if (error.Fail()) {
- wp_index = LLDB_INVALID_INDEX32;
- return error;
- } else if (is_hit) {
- return error;
- }
- }
- wp_index = LLDB_INVALID_INDEX32;
- return Status();
-}
-
-Status NativeRegisterContextLinux_x86_64::IsWatchpointVacant(uint32_t wp_index,
- bool &is_vacant) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Status("Watchpoint index out of range");
-
- RegisterValue reg_value;
- Status error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
- if (error.Fail()) {
- is_vacant = false;
- return error;
- }
-
- uint64_t control_bits = reg_value.GetAsUInt64();
-
- is_vacant = !(control_bits & (1 << (2 * wp_index)));
-
- return error;
-}
-
-Status NativeRegisterContextLinux_x86_64::SetHardwareWatchpointWithIndex(
- lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
-
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return Status("Watchpoint index out of range");
-
- // Read only watchpoints aren't supported on x86_64. Fall back to read/write
- // waitchpoints instead.
- // TODO: Add logic to detect when a write happens and ignore that watchpoint
- // hit.
- if (watch_flags == 0x2)
- watch_flags = 0x3;
-
- if (watch_flags != 0x1 && watch_flags != 0x3)
- return Status("Invalid read/write bits for watchpoint");
-
- if (size != 1 && size != 2 && size != 4 && size != 8)
- return Status("Invalid size for watchpoint");
-
- bool is_vacant;
- Status error = IsWatchpointVacant(wp_index, is_vacant);
- if (error.Fail())
- return error;
- if (!is_vacant)
- return Status("Watchpoint index not vacant");
-
- RegisterValue reg_value;
- error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
- if (error.Fail())
- return error;
-
- // for watchpoints 0, 1, 2, or 3, respectively, set bits 1, 3, 5, or 7
- uint64_t enable_bit = 1 << (2 * wp_index);
-
- // set bits 16-17, 20-21, 24-25, or 28-29
- // with 0b01 for write, and 0b11 for read/write
- uint64_t rw_bits = watch_flags << (16 + 4 * wp_index);
-
- // set bits 18-19, 22-23, 26-27, or 30-31
- // with 0b00, 0b01, 0b10, or 0b11
- // for 1, 2, 8 (if supported), or 4 bytes, respectively
- uint64_t size_bits = (size == 8 ? 0x2 : size - 1) << (18 + 4 * wp_index);
-
- uint64_t bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
-
- uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
-
- control_bits |= enable_bit | rw_bits | size_bits;
-
- error = WriteRegisterRaw(m_reg_info.first_dr + wp_index, RegisterValue(addr));
- if (error.Fail())
- return error;
-
- error =
- WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
- if (error.Fail())
- return error;
-
- error.Clear();
- return error;
-}
-
-bool NativeRegisterContextLinux_x86_64::ClearHardwareWatchpoint(
- uint32_t wp_index) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return false;
-
- RegisterValue reg_value;
-
- // for watchpoints 0, 1, 2, or 3, respectively, clear bits 0, 1, 2, or 3 of
- // the debug status register (DR6)
- Status error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
- if (error.Fail())
- return false;
- uint64_t bit_mask = 1 << wp_index;
- uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
- error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
- if (error.Fail())
- return false;
-
- // for watchpoints 0, 1, 2, or 3, respectively, clear bits {0-1,16-19},
- // {2-3,20-23}, {4-5,24-27}, or {6-7,28-31} of the debug control register
- // (DR7)
- error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
- if (error.Fail())
- return false;
- bit_mask = (0x3 << (2 * wp_index)) | (0xF << (16 + 4 * wp_index));
- uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
- return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits))
- .Success();
-}
-
-Status NativeRegisterContextLinux_x86_64::ClearAllHardwareWatchpoints() {
- RegisterValue reg_value;
-
- // clear bits {0-4} of the debug status register (DR6)
- Status error = ReadRegisterRaw(m_reg_info.first_dr + 6, reg_value);
- if (error.Fail())
- return error;
- uint64_t bit_mask = 0xF;
- uint64_t status_bits = reg_value.GetAsUInt64() & ~bit_mask;
- error = WriteRegisterRaw(m_reg_info.first_dr + 6, RegisterValue(status_bits));
- if (error.Fail())
- return error;
-
- // clear bits {0-7,16-31} of the debug control register (DR7)
- error = ReadRegisterRaw(m_reg_info.first_dr + 7, reg_value);
- if (error.Fail())
- return error;
- bit_mask = 0xFF | (0xFFFF << 16);
- uint64_t control_bits = reg_value.GetAsUInt64() & ~bit_mask;
- return WriteRegisterRaw(m_reg_info.first_dr + 7, RegisterValue(control_bits));
-}
-
-uint32_t NativeRegisterContextLinux_x86_64::SetHardwareWatchpoint(
- lldb::addr_t addr, size_t size, uint32_t watch_flags) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- for (uint32_t wp_index = 0; wp_index < num_hw_watchpoints; ++wp_index) {
- bool is_vacant;
- Status error = IsWatchpointVacant(wp_index, is_vacant);
- if (is_vacant) {
- error = SetHardwareWatchpointWithIndex(addr, size, watch_flags, wp_index);
- if (error.Success())
- return wp_index;
- }
- if (error.Fail() && log) {
- log->Printf("NativeRegisterContextLinux_x86_64::%s Error: %s",
- __FUNCTION__, error.AsCString());
- }
- }
- return LLDB_INVALID_INDEX32;
-}
-
-lldb::addr_t
-NativeRegisterContextLinux_x86_64::GetWatchpointAddress(uint32_t wp_index) {
- if (wp_index >= NumSupportedHardwareWatchpoints())
- return LLDB_INVALID_ADDRESS;
- RegisterValue reg_value;
- if (ReadRegisterRaw(m_reg_info.first_dr + wp_index, reg_value).Fail())
- return LLDB_INVALID_ADDRESS;
- return reg_value.GetAsUInt64();
-}
-
-uint32_t NativeRegisterContextLinux_x86_64::NumSupportedHardwareWatchpoints() {
- // Available debug address registers: dr0, dr1, dr2, dr3
- return 4;
-}
-
-#endif // defined(__i386__) || defined(__x86_64__)
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
deleted file mode 100644
index 9dcf82f50a458..0000000000000
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.h
+++ /dev/null
@@ -1,149 +0,0 @@
-//===-- NativeRegisterContextLinux_x86_64.h ---------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#if defined(__i386__) || defined(__x86_64__)
-
-#ifndef lldb_NativeRegisterContextLinux_x86_64_h
-#define lldb_NativeRegisterContextLinux_x86_64_h
-
-#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
-#include "Plugins/Process/Utility/RegisterContext_x86.h"
-#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
-#include <sys/uio.h>
-
-namespace lldb_private {
-namespace process_linux {
-
-class NativeProcessLinux;
-
-class NativeRegisterContextLinux_x86_64 : public NativeRegisterContextLinux {
-public:
- NativeRegisterContextLinux_x86_64(const ArchSpec &target_arch,
- NativeThreadProtocol &native_thread);
-
- uint32_t GetRegisterSetCount() const override;
-
- const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
-
- uint32_t GetUserRegisterCount() const override;
-
- Status ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) override;
-
- Status WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &reg_value) override;
-
- Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- Status IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
-
- Status GetWatchpointHitIndex(uint32_t &wp_index,
- lldb::addr_t trap_addr) override;
-
- Status IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
-
- bool ClearHardwareWatchpoint(uint32_t wp_index) override;
-
- Status ClearAllHardwareWatchpoints() override;
-
- Status SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
- uint32_t watch_flags,
- uint32_t wp_index);
-
- uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
- uint32_t watch_flags) override;
-
- lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
-
- uint32_t NumSupportedHardwareWatchpoints() override;
-
-protected:
- void *GetGPRBuffer() override { return &m_gpr_x86_64; }
-
- void *GetFPRBuffer() override;
-
- size_t GetFPRSize() override;
-
- Status ReadFPR() override;
-
- Status WriteFPR() override;
-
-private:
- // Private member types.
- enum class XStateType { Invalid, FXSAVE, XSAVE };
- enum class RegSet { gpr, fpu, avx, mpx };
-
- // Info about register ranges.
- struct RegInfo {
- uint32_t num_registers;
- uint32_t num_gpr_registers;
- uint32_t num_fpr_registers;
- uint32_t num_avx_registers;
- uint32_t num_mpx_registers;
- uint32_t last_gpr;
- uint32_t first_fpr;
- uint32_t last_fpr;
- uint32_t first_st;
- uint32_t last_st;
- uint32_t first_mm;
- uint32_t last_mm;
- uint32_t first_xmm;
- uint32_t last_xmm;
- uint32_t first_ymm;
- uint32_t last_ymm;
- uint32_t first_mpxr;
- uint32_t last_mpxr;
- uint32_t first_mpxc;
- uint32_t last_mpxc;
- uint32_t first_dr;
- uint32_t gpr_flags;
- };
-
- // Private member variables.
- mutable XStateType m_xstate_type;
- FPR m_fpr; // Extended States Area, named FPR for historical reasons.
- struct iovec m_iovec;
- YMM m_ymm_set;
- MPX m_mpx_set;
- RegInfo m_reg_info;
- uint64_t m_gpr_x86_64[k_num_gpr_registers_x86_64];
- uint32_t m_fctrl_offset_in_userarea;
-
- // Private member methods.
- bool IsCPUFeatureAvailable(RegSet feature_code) const;
-
- bool IsRegisterSetAvailable(uint32_t set_index) const;
-
- bool IsGPR(uint32_t reg_index) const;
-
- bool IsFPR(uint32_t reg_index) const;
-
- bool CopyXSTATEtoYMM(uint32_t reg_index, lldb::ByteOrder byte_order);
-
- bool CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order);
-
- bool IsAVX(uint32_t reg_index) const;
-
- bool CopyXSTATEtoMPX(uint32_t reg);
-
- bool CopyMPXtoXSTATE(uint32_t reg);
-
- bool IsMPX(uint32_t reg_index) const;
-
- void UpdateXSTATEforWrite(uint32_t reg_index);
-};
-
-} // namespace process_linux
-} // namespace lldb_private
-
-#endif // #ifndef lldb_NativeRegisterContextLinux_x86_64_h
-
-#endif // defined(__i386__) || defined(__x86_64__)
diff --git a/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/source/Plugins/Process/Linux/NativeThreadLinux.cpp
deleted file mode 100644
index b64689c9d17b0..0000000000000
--- a/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ /dev/null
@@ -1,451 +0,0 @@
-//===-- NativeThreadLinux.cpp --------------------------------- -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "NativeThreadLinux.h"
-
-#include <signal.h>
-#include <sstream>
-
-#include "NativeProcessLinux.h"
-#include "NativeRegisterContextLinux.h"
-#include "SingleStepCheck.h"
-
-#include "lldb/Host/HostNativeThread.h"
-#include "lldb/Host/linux/Ptrace.h"
-#include "lldb/Host/linux/Support.h"
-#include "lldb/Utility/LLDBAssert.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/State.h"
-#include "lldb/lldb-enumerations.h"
-
-#include "llvm/ADT/SmallString.h"
-
-#include "Plugins/Process/POSIX/CrashReason.h"
-
-#include <sys/syscall.h>
-// Try to define a macro to encapsulate the tgkill syscall
-#define tgkill(pid, tid, sig) \
- syscall(__NR_tgkill, static_cast<::pid_t>(pid), static_cast<::pid_t>(tid), \
- sig)
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::process_linux;
-
-namespace {
-void LogThreadStopInfo(Log &log, const ThreadStopInfo &stop_info,
- const char *const header) {
- switch (stop_info.reason) {
- case eStopReasonNone:
- log.Printf("%s: %s no stop reason", __FUNCTION__, header);
- return;
- case eStopReasonTrace:
- log.Printf("%s: %s trace, stopping signal 0x%" PRIx32, __FUNCTION__, header,
- stop_info.details.signal.signo);
- return;
- case eStopReasonBreakpoint:
- log.Printf("%s: %s breakpoint, stopping signal 0x%" PRIx32, __FUNCTION__,
- header, stop_info.details.signal.signo);
- return;
- case eStopReasonWatchpoint:
- log.Printf("%s: %s watchpoint, stopping signal 0x%" PRIx32, __FUNCTION__,
- header, stop_info.details.signal.signo);
- return;
- case eStopReasonSignal:
- log.Printf("%s: %s signal 0x%02" PRIx32, __FUNCTION__, header,
- stop_info.details.signal.signo);
- return;
- case eStopReasonException:
- log.Printf("%s: %s exception type 0x%02" PRIx64, __FUNCTION__, header,
- stop_info.details.exception.type);
- return;
- case eStopReasonExec:
- log.Printf("%s: %s exec, stopping signal 0x%" PRIx32, __FUNCTION__, header,
- stop_info.details.signal.signo);
- return;
- case eStopReasonPlanComplete:
- log.Printf("%s: %s plan complete", __FUNCTION__, header);
- return;
- case eStopReasonThreadExiting:
- log.Printf("%s: %s thread exiting", __FUNCTION__, header);
- return;
- case eStopReasonInstrumentation:
- log.Printf("%s: %s instrumentation", __FUNCTION__, header);
- return;
- default:
- log.Printf("%s: %s invalid stop reason %" PRIu32, __FUNCTION__, header,
- static_cast<uint32_t>(stop_info.reason));
- }
-}
-}
-
-NativeThreadLinux::NativeThreadLinux(NativeProcessLinux &process,
- lldb::tid_t tid)
- : NativeThreadProtocol(process, tid), m_state(StateType::eStateInvalid),
- m_stop_info(),
- m_reg_context_up(
- NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
- process.GetArchitecture(), *this)),
- m_stop_description() {}
-
-std::string NativeThreadLinux::GetName() {
- NativeProcessLinux &process = GetProcess();
-
- auto BufferOrError = getProcFile(process.GetID(), GetID(), "comm");
- if (!BufferOrError)
- return "";
- return BufferOrError.get()->getBuffer().rtrim('\n');
-}
-
-lldb::StateType NativeThreadLinux::GetState() { return m_state; }
-
-bool NativeThreadLinux::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:
- if (log)
- LogThreadStopInfo(*log, m_stop_info, "m_stop_info in thread:");
- stop_info = m_stop_info;
- description = m_stop_description;
- if (log)
- LogThreadStopInfo(*log, stop_info, "returned stop_info:");
-
- return true;
-
- case eStateInvalid:
- case eStateConnected:
- case eStateAttaching:
- case eStateLaunching:
- case eStateRunning:
- case eStateStepping:
- case eStateDetached:
- if (log) {
- log->Printf("NativeThreadLinux::%s tid %" PRIu64
- " in state %s cannot answer stop reason",
- __FUNCTION__, GetID(), StateAsCString(m_state));
- }
- return false;
- }
- llvm_unreachable("unhandled StateType!");
-}
-
-Status NativeThreadLinux::SetWatchpoint(lldb::addr_t addr, size_t size,
- uint32_t watch_flags, bool hardware) {
- if (!hardware)
- return Status("not implemented");
- if (m_state == eStateLaunching)
- return Status();
- Status error = RemoveWatchpoint(addr);
- if (error.Fail())
- return error;
- uint32_t wp_index =
- m_reg_context_up->SetHardwareWatchpoint(addr, size, watch_flags);
- if (wp_index == LLDB_INVALID_INDEX32)
- return Status("Setting hardware watchpoint failed.");
- m_watchpoint_index_map.insert({addr, wp_index});
- return Status();
-}
-
-Status NativeThreadLinux::RemoveWatchpoint(lldb::addr_t addr) {
- auto wp = m_watchpoint_index_map.find(addr);
- if (wp == m_watchpoint_index_map.end())
- return Status();
- uint32_t wp_index = wp->second;
- m_watchpoint_index_map.erase(wp);
- if (m_reg_context_up->ClearHardwareWatchpoint(wp_index))
- return Status();
- return Status("Clearing hardware watchpoint failed.");
-}
-
-Status NativeThreadLinux::SetHardwareBreakpoint(lldb::addr_t addr,
- size_t size) {
- if (m_state == eStateLaunching)
- return Status();
-
- Status error = RemoveHardwareBreakpoint(addr);
- if (error.Fail())
- return error;
-
- uint32_t bp_index = m_reg_context_up->SetHardwareBreakpoint(addr, size);
-
- if (bp_index == LLDB_INVALID_INDEX32)
- return Status("Setting hardware breakpoint failed.");
-
- m_hw_break_index_map.insert({addr, bp_index});
- return Status();
-}
-
-Status NativeThreadLinux::RemoveHardwareBreakpoint(lldb::addr_t addr) {
- auto bp = m_hw_break_index_map.find(addr);
- if (bp == m_hw_break_index_map.end())
- return Status();
-
- uint32_t bp_index = bp->second;
- if (m_reg_context_up->ClearHardwareBreakpoint(bp_index)) {
- m_hw_break_index_map.erase(bp);
- return Status();
- }
-
- return Status("Clearing hardware breakpoint failed.");
-}
-
-Status NativeThreadLinux::Resume(uint32_t signo) {
- const StateType new_state = StateType::eStateRunning;
- MaybeLogStateChange(new_state);
- m_state = new_state;
-
- m_stop_info.reason = StopReason::eStopReasonNone;
- m_stop_description.clear();
-
- // If watchpoints have been set, but none on this thread, then this is a new
- // thread. So set all existing watchpoints.
- if (m_watchpoint_index_map.empty()) {
- NativeProcessLinux &process = GetProcess();
-
- const auto &watchpoint_map = process.GetWatchpointMap();
- m_reg_context_up->ClearAllHardwareWatchpoints();
- for (const auto &pair : watchpoint_map) {
- const auto &wp = pair.second;
- SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags, wp.m_hardware);
- }
- }
-
- // Set all active hardware breakpoint on all threads.
- if (m_hw_break_index_map.empty()) {
- NativeProcessLinux &process = GetProcess();
-
- const auto &hw_breakpoint_map = process.GetHardwareBreakpointMap();
- m_reg_context_up->ClearAllHardwareBreakpoints();
- for (const auto &pair : hw_breakpoint_map) {
- const auto &bp = pair.second;
- SetHardwareBreakpoint(bp.m_addr, bp.m_size);
- }
- }
-
- intptr_t data = 0;
-
- if (signo != LLDB_INVALID_SIGNAL_NUMBER)
- data = signo;
-
- return NativeProcessLinux::PtraceWrapper(PTRACE_CONT, GetID(), nullptr,
- reinterpret_cast<void *>(data));
-}
-
-Status NativeThreadLinux::SingleStep(uint32_t signo) {
- const StateType new_state = StateType::eStateStepping;
- MaybeLogStateChange(new_state);
- m_state = new_state;
- m_stop_info.reason = StopReason::eStopReasonNone;
-
- if(!m_step_workaround) {
- // If we already hava a workaround inplace, don't reset it. Otherwise, the
- // destructor of the existing instance will run after the new instance has
- // fetched the cpu mask, and the thread will end up with the wrong mask.
- m_step_workaround = SingleStepWorkaround::Get(m_tid);
- }
-
- intptr_t data = 0;
- if (signo != LLDB_INVALID_SIGNAL_NUMBER)
- data = signo;
-
- // If hardware single-stepping is not supported, we just do a continue. The
- // breakpoint on the next instruction has been setup in
- // NativeProcessLinux::Resume.
- return NativeProcessLinux::PtraceWrapper(
- GetProcess().SupportHardwareSingleStepping() ? PTRACE_SINGLESTEP
- : PTRACE_CONT,
- m_tid, nullptr, reinterpret_cast<void *>(data));
-}
-
-void NativeThreadLinux::SetStoppedBySignal(uint32_t signo,
- const siginfo_t *info) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf("NativeThreadLinux::%s called with signal 0x%02" PRIx32,
- __FUNCTION__, signo);
-
- SetStopped();
-
- m_stop_info.reason = StopReason::eStopReasonSignal;
- m_stop_info.details.signal.signo = signo;
-
- m_stop_description.clear();
- if (info) {
- switch (signo) {
- case SIGSEGV:
- case SIGBUS:
- case SIGFPE:
- case SIGILL:
- // In case of MIPS64 target, SI_KERNEL is generated for invalid 64bit
- // address.
- const auto reason =
- (info->si_signo == SIGBUS && info->si_code == SI_KERNEL)
- ? CrashReason::eInvalidAddress
- : GetCrashReason(*info);
- m_stop_description = GetCrashReasonString(reason, *info);
- break;
- }
- }
-}
-
-bool NativeThreadLinux::IsStopped(int *signo) {
- if (!StateIsStoppedState(m_state, false))
- return false;
-
- // If we are stopped by a signal, return the signo.
- if (signo && m_state == StateType::eStateStopped &&
- m_stop_info.reason == StopReason::eStopReasonSignal) {
- *signo = m_stop_info.details.signal.signo;
- }
-
- // Regardless, we are stopped.
- return true;
-}
-
-void NativeThreadLinux::SetStopped() {
- if (m_state == StateType::eStateStepping)
- m_step_workaround.reset();
-
- const StateType new_state = StateType::eStateStopped;
- MaybeLogStateChange(new_state);
- m_state = new_state;
- m_stop_description.clear();
-}
-
-void NativeThreadLinux::SetStoppedByExec() {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- if (log)
- log->Printf("NativeThreadLinux::%s()", __FUNCTION__);
-
- SetStopped();
-
- m_stop_info.reason = StopReason::eStopReasonExec;
- m_stop_info.details.signal.signo = SIGSTOP;
-}
-
-void NativeThreadLinux::SetStoppedByBreakpoint() {
- SetStopped();
-
- m_stop_info.reason = StopReason::eStopReasonBreakpoint;
- m_stop_info.details.signal.signo = SIGTRAP;
- m_stop_description.clear();
-}
-
-void NativeThreadLinux::SetStoppedByWatchpoint(uint32_t wp_index) {
- SetStopped();
-
- lldbassert(wp_index != LLDB_INVALID_INDEX32 && "wp_index cannot be invalid");
-
- std::ostringstream ostr;
- ostr << m_reg_context_up->GetWatchpointAddress(wp_index) << " ";
- ostr << wp_index;
-
- /*
- * MIPS: Last 3bits of the watchpoint address are masked by the kernel. For
- * example:
- * 'n' is at 0x120010d00 and 'm' is 0x120010d04. When a watchpoint is set at
- * 'm', then
- * watch exception is generated even when 'n' is read/written. To handle this
- * case,
- * find the base address of the load/store instruction and append it in the
- * stop-info
- * packet.
- */
- ostr << " " << m_reg_context_up->GetWatchpointHitAddress(wp_index);
-
- m_stop_description = ostr.str();
-
- m_stop_info.reason = StopReason::eStopReasonWatchpoint;
- m_stop_info.details.signal.signo = SIGTRAP;
-}
-
-bool NativeThreadLinux::IsStoppedAtBreakpoint() {
- return GetState() == StateType::eStateStopped &&
- m_stop_info.reason == StopReason::eStopReasonBreakpoint;
-}
-
-bool NativeThreadLinux::IsStoppedAtWatchpoint() {
- return GetState() == StateType::eStateStopped &&
- m_stop_info.reason == StopReason::eStopReasonWatchpoint;
-}
-
-void NativeThreadLinux::SetStoppedByTrace() {
- SetStopped();
-
- m_stop_info.reason = StopReason::eStopReasonTrace;
- m_stop_info.details.signal.signo = SIGTRAP;
-}
-
-void NativeThreadLinux::SetStoppedWithNoReason() {
- SetStopped();
-
- m_stop_info.reason = StopReason::eStopReasonNone;
- m_stop_info.details.signal.signo = 0;
-}
-
-void NativeThreadLinux::SetExited() {
- const StateType new_state = StateType::eStateExited;
- MaybeLogStateChange(new_state);
- m_state = new_state;
-
- m_stop_info.reason = StopReason::eStopReasonThreadExiting;
-}
-
-Status NativeThreadLinux::RequestStop() {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
-
- NativeProcessLinux &process = GetProcess();
-
- lldb::pid_t pid = process.GetID();
- lldb::tid_t tid = GetID();
-
- if (log)
- log->Printf("NativeThreadLinux::%s requesting thread stop(pid: %" PRIu64
- ", tid: %" PRIu64 ")",
- __FUNCTION__, pid, tid);
-
- Status err;
- errno = 0;
- if (::tgkill(pid, tid, SIGSTOP) != 0) {
- err.SetErrorToErrno();
- if (log)
- log->Printf("NativeThreadLinux::%s tgkill(%" PRIu64 ", %" PRIu64
- ", SIGSTOP) failed: %s",
- __FUNCTION__, pid, tid, err.AsCString());
- }
-
- return err;
-}
-
-void NativeThreadLinux::MaybeLogStateChange(lldb::StateType new_state) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
- // If we're not logging, we're done.
- if (!log)
- return;
-
- // If this is a state change to the same state, we're done.
- lldb::StateType old_state = m_state;
- if (new_state == old_state)
- return;
-
- LLDB_LOG(log, "pid={0}, tid={1}: changing from state {2} to {3}",
- m_process.GetID(), GetID(), old_state, new_state);
-}
-
-NativeProcessLinux &NativeThreadLinux::GetProcess() {
- return static_cast<NativeProcessLinux &>(m_process);
-}
diff --git a/source/Plugins/Process/Linux/NativeThreadLinux.h b/source/Plugins/Process/Linux/NativeThreadLinux.h
deleted file mode 100644
index a7c4e982012d2..0000000000000
--- a/source/Plugins/Process/Linux/NativeThreadLinux.h
+++ /dev/null
@@ -1,119 +0,0 @@
-//===-- NativeThreadLinux.h ----------------------------------- -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_NativeThreadLinux_H_
-#define liblldb_NativeThreadLinux_H_
-
-#include "Plugins/Process/Linux/NativeRegisterContextLinux.h"
-#include "Plugins/Process/Linux/SingleStepCheck.h"
-#include "lldb/Host/common/NativeThreadProtocol.h"
-#include "lldb/lldb-private-forward.h"
-
-#include <csignal>
-#include <map>
-#include <memory>
-#include <string>
-
-namespace lldb_private {
-namespace process_linux {
-
-class NativeProcessLinux;
-
-class NativeThreadLinux : public NativeThreadProtocol {
- friend class NativeProcessLinux;
-
-public:
- NativeThreadLinux(NativeProcessLinux &process, lldb::tid_t tid);
-
- // ---------------------------------------------------------------------
- // NativeThreadProtocol Interface
- // ---------------------------------------------------------------------
- std::string GetName() override;
-
- lldb::StateType GetState() override;
-
- bool GetStopReason(ThreadStopInfo &stop_info,
- std::string &description) override;
-
- NativeRegisterContextLinux &GetRegisterContext() override {
- return *m_reg_context_up;
- }
-
- Status SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags,
- bool hardware) override;
-
- Status RemoveWatchpoint(lldb::addr_t addr) override;
-
- Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
-
- Status RemoveHardwareBreakpoint(lldb::addr_t addr) override;
-
-private:
- // ---------------------------------------------------------------------
- // Interface for friend classes
- // ---------------------------------------------------------------------
-
- /// Resumes the thread. If @p signo is anything but
- /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
- Status Resume(uint32_t signo);
-
- /// Single steps the thread. If @p signo is anything but
- /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
- Status SingleStep(uint32_t signo);
-
- void SetStoppedBySignal(uint32_t signo, const siginfo_t *info = nullptr);
-
- /// Return true if the thread is stopped.
- /// If stopped by a signal, indicate the signo in the signo argument.
- /// Otherwise, return LLDB_INVALID_SIGNAL_NUMBER.
- bool IsStopped(int *signo);
-
- void SetStoppedByExec();
-
- void SetStoppedByBreakpoint();
-
- void SetStoppedByWatchpoint(uint32_t wp_index);
-
- bool IsStoppedAtBreakpoint();
-
- bool IsStoppedAtWatchpoint();
-
- void SetStoppedByTrace();
-
- void SetStoppedWithNoReason();
-
- void SetExited();
-
- Status RequestStop();
-
- // ---------------------------------------------------------------------
- // Private interface
- // ---------------------------------------------------------------------
- void MaybeLogStateChange(lldb::StateType new_state);
-
- NativeProcessLinux &GetProcess();
-
- void SetStopped();
-
- // ---------------------------------------------------------------------
- // Member Variables
- // ---------------------------------------------------------------------
- lldb::StateType m_state;
- ThreadStopInfo m_stop_info;
- std::unique_ptr<NativeRegisterContextLinux> m_reg_context_up;
- std::string m_stop_description;
- using WatchpointIndexMap = std::map<lldb::addr_t, uint32_t>;
- WatchpointIndexMap m_watchpoint_index_map;
- WatchpointIndexMap m_hw_break_index_map;
- std::unique_ptr<SingleStepWorkaround> m_step_workaround;
-};
-} // namespace process_linux
-} // namespace lldb_private
-
-#endif // #ifndef liblldb_NativeThreadLinux_H_
diff --git a/source/Plugins/Process/Linux/ProcessorTrace.cpp b/source/Plugins/Process/Linux/ProcessorTrace.cpp
deleted file mode 100644
index 505c526ab70d7..0000000000000
--- a/source/Plugins/Process/Linux/ProcessorTrace.cpp
+++ /dev/null
@@ -1,395 +0,0 @@
-//===-- ProcessorTrace.cpp ------------------------------------ -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include <algorithm>
-#include <fstream>
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/MathExtras.h"
-
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "ProcessorTrace.h"
-#include "lldb/Host/linux/Support.h"
-
-#include <sys/syscall.h>
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace process_linux;
-using namespace llvm;
-
-lldb::user_id_t ProcessorTraceMonitor::m_trace_num = 1;
-
-Status ProcessorTraceMonitor::GetTraceConfig(TraceOptions &config) const {
-#ifndef PERF_ATTR_SIZE_VER5
- llvm_unreachable("perf event not supported");
-#else
- Status error;
-
- config.setType(lldb::TraceType::eTraceTypeProcessorTrace);
- config.setMetaDataBufferSize(m_mmap_meta->data_size);
-
- config.setTraceBufferSize(m_mmap_meta->aux_size);
-
- error = GetCPUType(config);
-
- return error;
-#endif
-}
-
-Status ProcessorTraceMonitor::StartTrace(lldb::pid_t pid, lldb::tid_t tid,
- const TraceOptions &config) {
-#ifndef PERF_ATTR_SIZE_VER5
- llvm_unreachable("perf event not supported");
-#else
- Status error;
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
- LLDB_LOG(log, "called thread id {0}", tid);
- uint64_t page_size = getpagesize();
- uint64_t bufsize = config.getTraceBufferSize();
- uint64_t metabufsize = config.getMetaDataBufferSize();
-
- uint64_t numpages = static_cast<uint64_t>(
- llvm::PowerOf2Floor((bufsize + page_size - 1) / page_size));
- numpages = std::max<uint64_t>(1, numpages);
- bufsize = page_size * numpages;
-
- numpages = static_cast<uint64_t>(
- llvm::PowerOf2Floor((metabufsize + page_size - 1) / page_size));
- metabufsize = page_size * numpages;
-
- perf_event_attr attr;
- memset(&attr, 0, sizeof(attr));
- attr.size = sizeof(attr);
- attr.exclude_kernel = 1;
- attr.sample_type = PERF_SAMPLE_TIME;
- attr.sample_id_all = 1;
- attr.exclude_hv = 1;
- attr.exclude_idle = 1;
- attr.mmap = 1;
-
- int intel_pt_type = 0;
-
- auto ret = llvm::MemoryBuffer::getFileAsStream(
- "/sys/bus/event_source/devices/intel_pt/type");
- if (!ret) {
- LLDB_LOG(log, "failed to open Config file");
- return ret.getError();
- }
-
- StringRef rest = ret.get()->getBuffer();
- if (rest.empty() || rest.trim().getAsInteger(10, intel_pt_type)) {
- LLDB_LOG(log, "failed to read Config file");
- error.SetErrorString("invalid file");
- return error;
- }
-
- rest.trim().getAsInteger(10, intel_pt_type);
- LLDB_LOG(log, "intel pt type {0}", intel_pt_type);
- attr.type = intel_pt_type;
-
- LLDB_LOG(log, "meta buffer size {0}", metabufsize);
- LLDB_LOG(log, "buffer size {0} ", bufsize);
-
- if (error.Fail()) {
- LLDB_LOG(log, "Status in custom config");
-
- return error;
- }
-
- errno = 0;
- auto fd =
- syscall(SYS_perf_event_open, &attr, static_cast<::tid_t>(tid), -1, -1, 0);
- if (fd == -1) {
- LLDB_LOG(log, "syscall error {0}", errno);
- error.SetErrorString("perf event syscall Failed");
- return error;
- }
-
- m_fd = std::unique_ptr<int, file_close>(new int(fd), file_close());
-
- errno = 0;
- auto base =
- mmap(NULL, (metabufsize + page_size), PROT_WRITE, MAP_SHARED, fd, 0);
-
- if (base == MAP_FAILED) {
- LLDB_LOG(log, "mmap base error {0}", errno);
- error.SetErrorString("Meta buffer allocation failed");
- return error;
- }
-
- m_mmap_meta = std::unique_ptr<perf_event_mmap_page, munmap_delete>(
- reinterpret_cast<perf_event_mmap_page *>(base),
- munmap_delete(metabufsize + page_size));
-
- m_mmap_meta->aux_offset = m_mmap_meta->data_offset + m_mmap_meta->data_size;
- m_mmap_meta->aux_size = bufsize;
-
- errno = 0;
- auto mmap_aux = mmap(NULL, bufsize, PROT_READ, MAP_SHARED, fd,
- static_cast<long int>(m_mmap_meta->aux_offset));
-
- if (mmap_aux == MAP_FAILED) {
- LLDB_LOG(log, "second mmap done {0}", errno);
- error.SetErrorString("Trace buffer allocation failed");
- return error;
- }
- m_mmap_aux = std::unique_ptr<uint8_t, munmap_delete>(
- reinterpret_cast<uint8_t *>(mmap_aux), munmap_delete(bufsize));
- return error;
-#endif
-}
-
-llvm::MutableArrayRef<uint8_t> ProcessorTraceMonitor::GetDataBuffer() {
-#ifndef PERF_ATTR_SIZE_VER5
- llvm_unreachable("perf event not supported");
-#else
- return MutableArrayRef<uint8_t>(
- (reinterpret_cast<uint8_t *>(m_mmap_meta.get()) +
- m_mmap_meta->data_offset),
- m_mmap_meta->data_size);
-#endif
-}
-
-llvm::MutableArrayRef<uint8_t> ProcessorTraceMonitor::GetAuxBuffer() {
-#ifndef PERF_ATTR_SIZE_VER5
- llvm_unreachable("perf event not supported");
-#else
- return MutableArrayRef<uint8_t>(m_mmap_aux.get(), m_mmap_meta->aux_size);
-#endif
-}
-
-Status ProcessorTraceMonitor::GetCPUType(TraceOptions &config) {
-
- Status error;
- uint64_t cpu_family = -1;
- uint64_t model = -1;
- uint64_t stepping = -1;
- std::string vendor_id;
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
- auto BufferOrError = getProcFile("cpuinfo");
- if (!BufferOrError)
- return BufferOrError.getError();
-
- LLDB_LOG(log, "GetCPUType Function");
-
- StringRef Rest = BufferOrError.get()->getBuffer();
- while (!Rest.empty()) {
- StringRef Line;
- std::tie(Line, Rest) = Rest.split('\n');
-
- SmallVector<StringRef, 2> columns;
- Line.split(columns, StringRef(":"), -1, false);
-
- if (columns.size() < 2)
- continue; // continue searching
-
- columns[1] = columns[1].trim(" ");
- if (columns[0].contains("cpu family") &&
- columns[1].getAsInteger(10, cpu_family))
- continue;
-
- else if (columns[0].contains("model") && columns[1].getAsInteger(10, model))
- continue;
-
- else if (columns[0].contains("stepping") &&
- columns[1].getAsInteger(10, stepping))
- continue;
-
- else if (columns[0].contains("vendor_id")) {
- vendor_id = columns[1].str();
- if (!vendor_id.empty())
- continue;
- }
- LLDB_LOG(log, "{0}:{1}:{2}:{3}", cpu_family, model, stepping, vendor_id);
-
- if ((cpu_family != static_cast<uint64_t>(-1)) &&
- (model != static_cast<uint64_t>(-1)) &&
- (stepping != static_cast<uint64_t>(-1)) && (!vendor_id.empty())) {
- auto params_dict = std::make_shared<StructuredData::Dictionary>();
- params_dict->AddIntegerItem("cpu_family", cpu_family);
- params_dict->AddIntegerItem("cpu_model", model);
- params_dict->AddIntegerItem("cpu_stepping", stepping);
- params_dict->AddStringItem("cpu_vendor", vendor_id);
-
- llvm::StringRef intel_custom_params_key("intel-pt");
-
- auto intel_custom_params = std::make_shared<StructuredData::Dictionary>();
- intel_custom_params->AddItem(
- intel_custom_params_key,
- StructuredData::ObjectSP(std::move(params_dict)));
-
- config.setTraceParams(intel_custom_params);
- return error; // we are done
- }
- }
-
- error.SetErrorString("cpu info not found");
- return error;
-}
-
-llvm::Expected<ProcessorTraceMonitorUP>
-ProcessorTraceMonitor::Create(lldb::pid_t pid, lldb::tid_t tid,
- const TraceOptions &config,
- bool useProcessSettings) {
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
- Status error;
- if (tid == LLDB_INVALID_THREAD_ID) {
- error.SetErrorString("thread not specified");
- return error.ToError();
- }
-
- ProcessorTraceMonitorUP pt_monitor_up(new ProcessorTraceMonitor);
-
- error = pt_monitor_up->StartTrace(pid, tid, config);
- if (error.Fail())
- return error.ToError();
-
- pt_monitor_up->SetThreadID(tid);
-
- if (useProcessSettings) {
- pt_monitor_up->SetTraceID(0);
- } else {
- pt_monitor_up->SetTraceID(m_trace_num++);
- LLDB_LOG(log, "Trace ID {0}", m_trace_num);
- }
- return std::move(pt_monitor_up);
-}
-
-Status
-ProcessorTraceMonitor::ReadPerfTraceAux(llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset) {
-#ifndef PERF_ATTR_SIZE_VER5
- llvm_unreachable("perf event not supported");
-#else
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
- Status error;
- uint64_t head = m_mmap_meta->aux_head;
-
- LLDB_LOG(log, "Aux size -{0} , Head - {1}", m_mmap_meta->aux_size, head);
-
- /**
- * When configured as ring buffer, the aux buffer keeps wrapping around
- * the buffer and its not possible to detect how many times the buffer
- * wrapped. Initially the buffer is filled with zeros,as shown below
- * so in order to get complete buffer we first copy firstpartsize, followed
- * by any left over part from beginning to aux_head
- *
- * aux_offset [d,d,d,d,d,d,d,d,0,0,0,0,0,0,0,0,0,0,0] aux_size
- * aux_head->||<- firstpartsize ->|
- *
- * */
-
- ReadCyclicBuffer(buffer, GetAuxBuffer(), static_cast<size_t>(head), offset);
- LLDB_LOG(log, "ReadCyclic BUffer Done");
- return error;
-#endif
-}
-
-Status
-ProcessorTraceMonitor::ReadPerfTraceData(llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset) {
-#ifndef PERF_ATTR_SIZE_VER5
- llvm_unreachable("perf event not supported");
-#else
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
- uint64_t bytes_remaining = buffer.size();
- Status error;
-
- uint64_t head = m_mmap_meta->data_head;
-
- /*
- * The data buffer and aux buffer have different implementations
- * with respect to their definition of head pointer. In the case
- * of Aux data buffer the head always wraps around the aux buffer
- * and we don't need to care about it, whereas the data_head keeps
- * increasing and needs to be wrapped by modulus operator
- */
-
- LLDB_LOG(log, "bytes_remaining - {0}", bytes_remaining);
-
- auto data_buffer = GetDataBuffer();
-
- if (head > data_buffer.size()) {
- head = head % data_buffer.size();
- LLDB_LOG(log, "Data size -{0} Head - {1}", m_mmap_meta->data_size, head);
-
- ReadCyclicBuffer(buffer, data_buffer, static_cast<size_t>(head), offset);
- bytes_remaining -= buffer.size();
- } else {
- LLDB_LOG(log, "Head - {0}", head);
- if (offset >= head) {
- LLDB_LOG(log, "Invalid Offset ");
- error.SetErrorString("invalid offset");
- buffer = buffer.slice(buffer.size());
- return error;
- }
-
- auto data = data_buffer.slice(offset, (head - offset));
- auto remaining = std::copy(data.begin(), data.end(), buffer.begin());
- bytes_remaining -= (remaining - buffer.begin());
- }
- buffer = buffer.drop_back(bytes_remaining);
- return error;
-#endif
-}
-
-void ProcessorTraceMonitor::ReadCyclicBuffer(
- llvm::MutableArrayRef<uint8_t> &dst, llvm::MutableArrayRef<uint8_t> src,
- size_t src_cyc_index, size_t offset) {
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
-
- if (dst.empty() || src.empty()) {
- dst = dst.drop_back(dst.size());
- return;
- }
-
- if (dst.data() == nullptr || src.data() == nullptr) {
- dst = dst.drop_back(dst.size());
- return;
- }
-
- if (src_cyc_index > src.size()) {
- dst = dst.drop_back(dst.size());
- return;
- }
-
- if (offset >= src.size()) {
- LLDB_LOG(log, "Too Big offset ");
- dst = dst.drop_back(dst.size());
- return;
- }
-
- llvm::SmallVector<MutableArrayRef<uint8_t>, 2> parts = {
- src.slice(src_cyc_index), src.take_front(src_cyc_index)};
-
- if (offset > parts[0].size()) {
- parts[1] = parts[1].slice(offset - parts[0].size());
- parts[0] = parts[0].drop_back(parts[0].size());
- } else if (offset == parts[0].size()) {
- parts[0] = parts[0].drop_back(parts[0].size());
- } else {
- parts[0] = parts[0].slice(offset);
- }
- auto next = dst.begin();
- auto bytes_left = dst.size();
- for (auto part : parts) {
- size_t chunk_size = std::min(part.size(), bytes_left);
- next = std::copy_n(part.begin(), chunk_size, next);
- bytes_left -= chunk_size;
- }
- dst = dst.drop_back(bytes_left);
-}
diff --git a/source/Plugins/Process/Linux/ProcessorTrace.h b/source/Plugins/Process/Linux/ProcessorTrace.h
deleted file mode 100644
index 6fd918c2bb58a..0000000000000
--- a/source/Plugins/Process/Linux/ProcessorTrace.h
+++ /dev/null
@@ -1,141 +0,0 @@
-//===-- ProcessorTrace.h -------------------------------------- -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ProcessorTrace_H_
-#define liblldb_ProcessorTrace_H_
-
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/TraceOptions.h"
-#include "lldb/lldb-types.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/DenseSet.h"
-
-#include <linux/perf_event.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-namespace lldb_private {
-
-namespace process_linux {
-
-// ---------------------------------------------------------------------
-// This class keeps track of one tracing instance of
-// Intel(R) Processor Trace on Linux OS. There is a map keeping track
-// of different tracing instances on each thread, which enables trace
-// gathering on a per thread level.
-//
-// The tracing instance is linked with a trace id. The trace id acts like
-// a key to the tracing instance and trace manipulations could be
-// performed using the trace id.
-//
-// The trace id could map to trace instances for a group of threads
-// (spanning to all the threads in the process) or a single thread.
-// The kernel interface for us is the perf_event_open.
-// ---------------------------------------------------------------------
-
-class ProcessorTraceMonitor;
-typedef std::unique_ptr<ProcessorTraceMonitor> ProcessorTraceMonitorUP;
-
-class ProcessorTraceMonitor {
-
- class munmap_delete {
- size_t m_length;
-
- public:
- munmap_delete(size_t length) : m_length(length) {}
- void operator()(void *ptr) {
- if (m_length)
- munmap(ptr, m_length);
- }
- };
-
- class file_close {
-
- public:
- file_close() = default;
- void operator()(int *ptr) {
- if (ptr == nullptr)
- return;
- if (*ptr == -1)
- return;
- close(*ptr);
- std::default_delete<int>()(ptr);
- }
- };
-
- std::unique_ptr<perf_event_mmap_page, munmap_delete> m_mmap_meta;
- std::unique_ptr<uint8_t, munmap_delete> m_mmap_aux;
- std::unique_ptr<int, file_close> m_fd;
-
- // perf_event_mmap_page *m_mmap_base;
- lldb::user_id_t m_traceid;
- lldb::tid_t m_thread_id;
-
- // Counter to track trace instances.
- static lldb::user_id_t m_trace_num;
-
- void SetTraceID(lldb::user_id_t traceid) { m_traceid = traceid; }
-
- Status StartTrace(lldb::pid_t pid, lldb::tid_t tid,
- const TraceOptions &config);
-
- llvm::MutableArrayRef<uint8_t> GetAuxBuffer();
- llvm::MutableArrayRef<uint8_t> GetDataBuffer();
-
- ProcessorTraceMonitor()
- : m_mmap_meta(nullptr, munmap_delete(0)),
- m_mmap_aux(nullptr, munmap_delete(0)), m_fd(nullptr, file_close()),
- m_traceid(LLDB_INVALID_UID), m_thread_id(LLDB_INVALID_THREAD_ID){};
-
- void SetThreadID(lldb::tid_t tid) { m_thread_id = tid; }
-
-public:
- static Status GetCPUType(TraceOptions &config);
-
- static llvm::Expected<ProcessorTraceMonitorUP>
- Create(lldb::pid_t pid, lldb::tid_t tid, const TraceOptions &config,
- bool useProcessSettings);
-
- Status ReadPerfTraceAux(llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset = 0);
-
- Status ReadPerfTraceData(llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset = 0);
-
- ~ProcessorTraceMonitor() = default;
-
- lldb::tid_t GetThreadID() const { return m_thread_id; }
-
- lldb::user_id_t GetTraceID() const { return m_traceid; }
-
- Status GetTraceConfig(TraceOptions &config) const;
-
- // ---------------------------------------------------------------------
- /// Read data from a cyclic buffer
- ///
- /// @param[in] [out] buf
- /// Destination buffer, the buffer will be truncated to written size.
- ///
- /// @param[in] src
- /// Source buffer which must be a cyclic buffer.
- ///
- /// @param[in] src_cyc_index
- /// The index pointer (start of the valid data in the cyclic
- /// buffer).
- ///
- /// @param[in] offset
- /// The offset to begin reading the data in the cyclic buffer.
- // ---------------------------------------------------------------------
- static void ReadCyclicBuffer(llvm::MutableArrayRef<uint8_t> &dst,
- llvm::MutableArrayRef<uint8_t> src,
- size_t src_cyc_index, size_t offset);
-};
-} // namespace process_linux
-} // namespace lldb_private
-#endif
diff --git a/source/Plugins/Process/Linux/Procfs.h b/source/Plugins/Process/Linux/Procfs.h
deleted file mode 100644
index 1d9c9dbe273fd..0000000000000
--- a/source/Plugins/Process/Linux/Procfs.h
+++ /dev/null
@@ -1,31 +0,0 @@
-//===-- Procfs.h ---------------------------------------------- -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// source/Plugins/Process/Linux/Procfs.h defines the symbols we need from
-// sys/procfs.h on Android/Linux for all supported architectures.
-
-#include <sys/ptrace.h>
-
-#ifdef __ANDROID__
-#if defined(__arm64__) || defined(__aarch64__)
-typedef unsigned long elf_greg_t;
-typedef elf_greg_t
- elf_gregset_t[(sizeof(struct user_pt_regs) / sizeof(elf_greg_t))];
-typedef struct user_fpsimd_state elf_fpregset_t;
-#ifndef NT_FPREGSET
-#define NT_FPREGSET NT_PRFPREG
-#endif // NT_FPREGSET
-#elif defined(__mips__)
-#ifndef NT_FPREGSET
-#define NT_FPREGSET NT_PRFPREG
-#endif // NT_FPREGSET
-#endif
-#else // __ANDROID__
-#include <sys/procfs.h>
-#endif // __ANDROID__
diff --git a/source/Plugins/Process/Linux/SingleStepCheck.cpp b/source/Plugins/Process/Linux/SingleStepCheck.cpp
deleted file mode 100644
index c57a2daf22757..0000000000000
--- a/source/Plugins/Process/Linux/SingleStepCheck.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-//===-- SingleStepCheck.cpp ----------------------------------- -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "SingleStepCheck.h"
-
-#include <sched.h>
-#include <signal.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include "NativeProcessLinux.h"
-
-#include "llvm/Support/Compiler.h"
-
-#include "Plugins/Process/POSIX/ProcessPOSIXLog.h"
-#include "lldb/Host/linux/Ptrace.h"
-#include "lldb/Utility/Status.h"
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::process_linux;
-
-#if defined(__arm64__) || defined(__aarch64__)
-namespace {
-
-void LLVM_ATTRIBUTE_NORETURN Child() {
- if (ptrace(PTRACE_TRACEME, 0, nullptr, nullptr) == -1)
- _exit(1);
-
- // We just do an endless loop SIGSTOPPING ourselves until killed. The tracer
- // will fiddle with our cpu affinities and monitor the behaviour.
- for (;;) {
- raise(SIGSTOP);
-
- // Generate a bunch of instructions here, so that a single-step does not
- // land in the raise() accidentally. If single-stepping works, we will be
- // spinning in this loop. If it doesn't, we'll land in the raise() call
- // above.
- for (volatile unsigned i = 0; i < CPU_SETSIZE; ++i)
- ;
- }
-}
-
-struct ChildDeleter {
- ::pid_t pid;
-
- ~ChildDeleter() {
- int status;
- kill(pid, SIGKILL); // Kill the child.
- waitpid(pid, &status, __WALL); // Pick up the remains.
- }
-};
-
-bool WorkaroundNeeded() {
- // We shall spawn a child, and use it to verify the debug capabilities of the
- // cpu. We shall iterate through the cpus, bind the child to each one in
- // turn, and verify that single-stepping works on that cpu. A workaround is
- // needed if we find at least one broken cpu.
-
- Log *log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD);
- ::pid_t child_pid = fork();
- if (child_pid == -1) {
- LLDB_LOG(log, "failed to fork(): {0}", Status(errno, eErrorTypePOSIX));
- return false;
- }
- if (child_pid == 0)
- Child();
-
- ChildDeleter child_deleter{child_pid};
- cpu_set_t available_cpus;
- if (sched_getaffinity(child_pid, sizeof available_cpus, &available_cpus) ==
- -1) {
- LLDB_LOG(log, "failed to get available cpus: {0}",
- Status(errno, eErrorTypePOSIX));
- return false;
- }
-
- int status;
- ::pid_t wpid = waitpid(child_pid, &status, __WALL);
- if (wpid != child_pid || !WIFSTOPPED(status)) {
- LLDB_LOG(log, "waitpid() failed (status = {0:x}): {1}", status,
- Status(errno, eErrorTypePOSIX));
- return false;
- }
-
- unsigned cpu;
- for (cpu = 0; cpu < CPU_SETSIZE; ++cpu) {
- if (!CPU_ISSET(cpu, &available_cpus))
- continue;
-
- cpu_set_t cpus;
- CPU_ZERO(&cpus);
- CPU_SET(cpu, &cpus);
- if (sched_setaffinity(child_pid, sizeof cpus, &cpus) == -1) {
- LLDB_LOG(log, "failed to switch to cpu {0}: {1}", cpu,
- Status(errno, eErrorTypePOSIX));
- continue;
- }
-
- int status;
- Status error =
- NativeProcessLinux::PtraceWrapper(PTRACE_SINGLESTEP, child_pid);
- if (error.Fail()) {
- LLDB_LOG(log, "single step failed: {0}", error);
- break;
- }
-
- wpid = waitpid(child_pid, &status, __WALL);
- if (wpid != child_pid || !WIFSTOPPED(status)) {
- LLDB_LOG(log, "waitpid() failed (status = {0:x}): {1}", status,
- Status(errno, eErrorTypePOSIX));
- break;
- }
- if (WSTOPSIG(status) != SIGTRAP) {
- LLDB_LOG(log, "single stepping on cpu {0} failed with status {1:x}", cpu,
- status);
- break;
- }
- }
-
- // cpu is either the index of the first broken cpu, or CPU_SETSIZE.
- if (cpu == 0) {
- LLDB_LOG(log,
- "SINGLE STEPPING ON FIRST CPU IS NOT WORKING. DEBUGGING "
- "LIKELY TO BE UNRELIABLE.");
- // No point in trying to fiddle with the affinities, just give it our best
- // shot and see how it goes.
- return false;
- }
-
- return cpu != CPU_SETSIZE;
-}
-
-} // end anonymous namespace
-
-std::unique_ptr<SingleStepWorkaround> SingleStepWorkaround::Get(::pid_t tid) {
- Log *log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD);
-
- static bool workaround_needed = WorkaroundNeeded();
- if (!workaround_needed) {
- LLDB_LOG(log, "workaround for thread {0} not needed", tid);
- return nullptr;
- }
-
- cpu_set_t original_set;
- if (sched_getaffinity(tid, sizeof original_set, &original_set) != 0) {
- // This should really not fail. But, just in case...
- LLDB_LOG(log, "Unable to get cpu affinity for thread {0}: {1}", tid,
- Status(errno, eErrorTypePOSIX));
- return nullptr;
- }
-
- cpu_set_t set;
- CPU_ZERO(&set);
- CPU_SET(0, &set);
- if (sched_setaffinity(tid, sizeof set, &set) != 0) {
- // This may fail in very locked down systems, if the thread is not allowed
- // to run on cpu 0. If that happens, only thing we can do is it log it and
- // continue...
- LLDB_LOG(log, "Unable to set cpu affinity for thread {0}: {1}", tid,
- Status(errno, eErrorTypePOSIX));
- }
-
- LLDB_LOG(log, "workaround for thread {0} prepared", tid);
- return llvm::make_unique<SingleStepWorkaround>(tid, original_set);
-}
-
-SingleStepWorkaround::~SingleStepWorkaround() {
- Log *log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD);
- LLDB_LOG(log, "Removing workaround");
- if (sched_setaffinity(m_tid, sizeof m_original_set, &m_original_set) != 0) {
- LLDB_LOG(log, "Unable to reset cpu affinity for thread {0}: {1}", m_tid,
- Status(errno, eErrorTypePOSIX));
- }
-}
-#endif
diff --git a/source/Plugins/Process/Linux/SingleStepCheck.h b/source/Plugins/Process/Linux/SingleStepCheck.h
deleted file mode 100644
index afeda7310349a..0000000000000
--- a/source/Plugins/Process/Linux/SingleStepCheck.h
+++ /dev/null
@@ -1,57 +0,0 @@
-//===-- SingleStepCheck.h ------------------------------------- -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_SingleStepCheck_H_
-#define liblldb_SingleStepCheck_H_
-
-#include <memory>
-#include <sched.h>
-#include <sys/types.h>
-
-namespace lldb_private {
-namespace process_linux {
-
-// arm64 linux had a bug which prevented single-stepping and watchpoints from
-// working on non-boot cpus, due to them being incorrectly initialized after
-// coming out of suspend. This issue is particularly affecting android M, which
-// uses suspend ("doze mode") quite aggressively. This code detects that
-// situation and makes single-stepping work by doing all the step operations on
-// the boot cpu.
-//
-// The underlying issue has been fixed in android N and linux 4.4. This code can
-// be removed once these systems become obsolete.
-
-#if defined(__arm64__) || defined(__aarch64__)
-class SingleStepWorkaround {
- ::pid_t m_tid;
- cpu_set_t m_original_set;
-
- SingleStepWorkaround(const SingleStepWorkaround &) = delete;
- void operator=(const SingleStepWorkaround &) = delete;
-
-public:
- SingleStepWorkaround(::pid_t tid, cpu_set_t original_set)
- : m_tid(tid), m_original_set(original_set) {}
- ~SingleStepWorkaround();
-
- static std::unique_ptr<SingleStepWorkaround> Get(::pid_t tid);
-};
-#else
-class SingleStepWorkaround {
-public:
- static std::unique_ptr<SingleStepWorkaround> Get(::pid_t tid) {
- return nullptr;
- }
-};
-#endif
-
-} // end namespace process_linux
-} // end namespace lldb_private
-
-#endif // #ifndef liblldb_SingleStepCheck_H_
diff --git a/source/Plugins/Process/MacOSX-Kernel/CMakeLists.txt b/source/Plugins/Process/MacOSX-Kernel/CMakeLists.txt
deleted file mode 100644
index bed0e3b7ab377..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/CMakeLists.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-add_lldb_library(lldbPluginProcessMacOSXKernel PLUGIN
- CommunicationKDP.cpp
- ProcessKDP.cpp
- ProcessKDPLog.cpp
- RegisterContextKDP_arm.cpp
- RegisterContextKDP_arm64.cpp
- RegisterContextKDP_i386.cpp
- RegisterContextKDP_x86_64.cpp
- ThreadKDP.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbHost
- lldbInterpreter
- lldbSymbol
- lldbTarget
- lldbUtility
- lldbPluginDynamicLoaderDarwinKernel
- lldbPluginDynamicLoaderStatic
- lldbPluginProcessUtility
- )
diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
deleted file mode 100644
index 8908108eff4bd..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
+++ /dev/null
@@ -1,1289 +0,0 @@
-//===-- CommunicationKDP.cpp ------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CommunicationKDP.h"
-
-#include <errno.h>
-#include <limits.h>
-#include <string.h>
-
-
-#include "lldb/Core/DumpDataExtractor.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/DataExtractor.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/State.h"
-#include "lldb/Utility/UUID.h"
-
-#include "ProcessKDPLog.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-//----------------------------------------------------------------------
-// CommunicationKDP constructor
-//----------------------------------------------------------------------
-CommunicationKDP::CommunicationKDP(const char *comm_name)
- : Communication(comm_name), m_addr_byte_size(4),
- m_byte_order(eByteOrderLittle), m_packet_timeout(5), m_sequence_mutex(),
- m_is_running(false), m_session_key(0u), m_request_sequence_id(0u),
- m_exception_sequence_id(0u), m_kdp_version_version(0u),
- m_kdp_version_feature(0u), m_kdp_hostinfo_cpu_mask(0u),
- m_kdp_hostinfo_cpu_type(0u), m_kdp_hostinfo_cpu_subtype(0u) {}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-CommunicationKDP::~CommunicationKDP() {
- if (IsConnected()) {
- Disconnect();
- }
-}
-
-bool CommunicationKDP::SendRequestPacket(
- const PacketStreamType &request_packet) {
- std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
- return SendRequestPacketNoLock(request_packet);
-}
-
-void CommunicationKDP::MakeRequestPacketHeader(CommandType request_type,
- PacketStreamType &request_packet,
- uint16_t request_length) {
- request_packet.Clear();
- request_packet.PutHex8(request_type |
- ePacketTypeRequest); // Set the request type
- request_packet.PutHex8(m_request_sequence_id++); // Sequence number
- request_packet.PutHex16(
- request_length); // Length of the packet including this header
- request_packet.PutHex32(m_session_key); // Session key
-}
-
-bool CommunicationKDP::SendRequestAndGetReply(
- const CommandType command, const PacketStreamType &request_packet,
- DataExtractor &reply_packet) {
- if (IsRunning()) {
- Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS));
- if (log) {
- PacketStreamType log_strm;
- DumpPacket(log_strm, request_packet.GetData(), request_packet.GetSize());
- log->Printf("error: kdp running, not sending packet: %.*s",
- (uint32_t)log_strm.GetSize(), log_strm.GetData());
- }
- return false;
- }
-
- std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
-#ifdef LLDB_CONFIGURATION_DEBUG
- // NOTE: this only works for packets that are in native endian byte order
- assert(request_packet.GetSize() ==
- *((const uint16_t *)(request_packet.GetData() + 2)));
-#endif
- lldb::offset_t offset = 1;
- const uint32_t num_retries = 3;
- for (uint32_t i = 0; i < num_retries; ++i) {
- if (SendRequestPacketNoLock(request_packet)) {
- const uint8_t request_sequence_id = (uint8_t)request_packet.GetData()[1];
- while (1) {
- if (WaitForPacketWithTimeoutMicroSecondsNoLock(
- reply_packet,
- std::chrono::microseconds(GetPacketTimeout()).count())) {
- offset = 0;
- const uint8_t reply_command = reply_packet.GetU8(&offset);
- const uint8_t reply_sequence_id = reply_packet.GetU8(&offset);
- if (request_sequence_id == reply_sequence_id) {
- // The sequent ID was correct, now verify we got the response we
- // were looking for
- if ((reply_command & eCommandTypeMask) == command) {
- // Success
- if (command == KDP_RESUMECPUS)
- m_is_running.SetValue(true, eBroadcastAlways);
- return true;
- } else {
- // Failed to get the correct response, bail
- reply_packet.Clear();
- return false;
- }
- } else if (reply_sequence_id > request_sequence_id) {
- // Sequence ID was greater than the sequence ID of the packet we
- // sent, something is really wrong...
- reply_packet.Clear();
- return false;
- } else {
- // The reply sequence ID was less than our current packet's
- // sequence ID so we should keep trying to get a response because
- // this was a response for a previous packet that we must have
- // retried.
- }
- } else {
- // Break and retry sending the packet as we didn't get a response due
- // to timeout
- break;
- }
- }
- }
- }
- reply_packet.Clear();
- return false;
-}
-
-bool CommunicationKDP::SendRequestPacketNoLock(
- const PacketStreamType &request_packet) {
- if (IsConnected()) {
- const char *packet_data = request_packet.GetData();
- const size_t packet_size = request_packet.GetSize();
-
- Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS));
- if (log) {
- PacketStreamType log_strm;
- DumpPacket(log_strm, packet_data, packet_size);
- log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
- }
- ConnectionStatus status = eConnectionStatusSuccess;
-
- size_t bytes_written = Write(packet_data, packet_size, status, NULL);
-
- if (bytes_written == packet_size)
- return true;
-
- if (log)
- log->Printf("error: failed to send packet entire packet %" PRIu64
- " of %" PRIu64 " bytes sent",
- (uint64_t)bytes_written, (uint64_t)packet_size);
- }
- return false;
-}
-
-bool CommunicationKDP::GetSequenceMutex(
- std::unique_lock<std::recursive_mutex> &lock) {
- return (lock = std::unique_lock<std::recursive_mutex>(m_sequence_mutex,
- std::try_to_lock))
- .owns_lock();
-}
-
-bool CommunicationKDP::WaitForNotRunningPrivate(
- const std::chrono::microseconds &timeout) {
- return m_is_running.WaitForValueEqualTo(false, timeout);
-}
-
-size_t
-CommunicationKDP::WaitForPacketWithTimeoutMicroSeconds(DataExtractor &packet,
- uint32_t timeout_usec) {
- std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
- return WaitForPacketWithTimeoutMicroSecondsNoLock(packet, timeout_usec);
-}
-
-size_t CommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock(
- DataExtractor &packet, uint32_t timeout_usec) {
- uint8_t buffer[8192];
- Status error;
-
- Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS));
-
- // Check for a packet from our cache first without trying any reading...
- if (CheckForPacket(NULL, 0, packet))
- return packet.GetByteSize();
-
- bool timed_out = false;
- while (IsConnected() && !timed_out) {
- lldb::ConnectionStatus status = eConnectionStatusNoConnection;
- size_t bytes_read = Read(buffer, sizeof(buffer),
- timeout_usec == UINT32_MAX
- ? Timeout<std::micro>(llvm::None)
- : std::chrono::microseconds(timeout_usec),
- status, &error);
-
- LLDB_LOGV(log,
- "Read (buffer, sizeof(buffer), timeout_usec = 0x{0:x}, "
- "status = {1}, error = {2}) => bytes_read = {4}",
- timeout_usec,
- Communication::ConnectionStatusAsCString(status),
- error, bytes_read);
-
- if (bytes_read > 0) {
- if (CheckForPacket(buffer, bytes_read, packet))
- return packet.GetByteSize();
- } else {
- switch (status) {
- case eConnectionStatusInterrupted:
- case eConnectionStatusTimedOut:
- timed_out = true;
- break;
- case eConnectionStatusSuccess:
- // printf ("status = success but error = %s\n",
- // error.AsCString("<invalid>"));
- break;
-
- case eConnectionStatusEndOfFile:
- case eConnectionStatusNoConnection:
- case eConnectionStatusLostConnection:
- case eConnectionStatusError:
- Disconnect();
- break;
- }
- }
- }
- packet.Clear();
- return 0;
-}
-
-bool CommunicationKDP::CheckForPacket(const uint8_t *src, size_t src_len,
- DataExtractor &packet) {
- // Put the packet data into the buffer in a thread safe fashion
- std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
-
- Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS));
-
- if (src && src_len > 0) {
- if (log && log->GetVerbose()) {
- PacketStreamType log_strm;
- DumpHexBytes(&log_strm, src, src_len, UINT32_MAX, LLDB_INVALID_ADDRESS);
- log->Printf("CommunicationKDP::%s adding %u bytes: %s", __FUNCTION__,
- (uint32_t)src_len, log_strm.GetData());
- }
- m_bytes.append((const char *)src, src_len);
- }
-
- // Make sure we at least have enough bytes for a packet header
- const size_t bytes_available = m_bytes.size();
- if (bytes_available >= 8) {
- packet.SetData(&m_bytes[0], bytes_available, m_byte_order);
- lldb::offset_t offset = 0;
- uint8_t reply_command = packet.GetU8(&offset);
- switch (reply_command) {
- case ePacketTypeRequest | KDP_EXCEPTION:
- case ePacketTypeRequest | KDP_TERMINATION:
- // We got an exception request, so be sure to send an ACK
- {
- PacketStreamType request_ack_packet(Stream::eBinary, m_addr_byte_size,
- m_byte_order);
- // Set the reply but and make the ACK packet
- request_ack_packet.PutHex8(reply_command | ePacketTypeReply);
- request_ack_packet.PutHex8(packet.GetU8(&offset));
- request_ack_packet.PutHex16(packet.GetU16(&offset));
- request_ack_packet.PutHex32(packet.GetU32(&offset));
- m_is_running.SetValue(false, eBroadcastAlways);
- // Ack to the exception or termination
- SendRequestPacketNoLock(request_ack_packet);
- }
- // Fall through to case below to get packet contents
- LLVM_FALLTHROUGH;
- case ePacketTypeReply | KDP_CONNECT:
- case ePacketTypeReply | KDP_DISCONNECT:
- case ePacketTypeReply | KDP_HOSTINFO:
- case ePacketTypeReply | KDP_VERSION:
- case ePacketTypeReply | KDP_MAXBYTES:
- case ePacketTypeReply | KDP_READMEM:
- case ePacketTypeReply | KDP_WRITEMEM:
- case ePacketTypeReply | KDP_READREGS:
- case ePacketTypeReply | KDP_WRITEREGS:
- case ePacketTypeReply | KDP_LOAD:
- case ePacketTypeReply | KDP_IMAGEPATH:
- case ePacketTypeReply | KDP_SUSPEND:
- case ePacketTypeReply | KDP_RESUMECPUS:
- case ePacketTypeReply | KDP_BREAKPOINT_SET:
- case ePacketTypeReply | KDP_BREAKPOINT_REMOVE:
- case ePacketTypeReply | KDP_REGIONS:
- case ePacketTypeReply | KDP_REATTACH:
- case ePacketTypeReply | KDP_HOSTREBOOT:
- case ePacketTypeReply | KDP_READMEM64:
- case ePacketTypeReply | KDP_WRITEMEM64:
- case ePacketTypeReply | KDP_BREAKPOINT_SET64:
- case ePacketTypeReply | KDP_BREAKPOINT_REMOVE64:
- case ePacketTypeReply | KDP_KERNELVERSION:
- case ePacketTypeReply | KDP_READPHYSMEM64:
- case ePacketTypeReply | KDP_WRITEPHYSMEM64:
- case ePacketTypeReply | KDP_READIOPORT:
- case ePacketTypeReply | KDP_WRITEIOPORT:
- case ePacketTypeReply | KDP_READMSR64:
- case ePacketTypeReply | KDP_WRITEMSR64:
- case ePacketTypeReply | KDP_DUMPINFO: {
- offset = 2;
- const uint16_t length = packet.GetU16(&offset);
- if (length <= bytes_available) {
- // We have an entire packet ready, we need to copy the data bytes into
- // a buffer that will be owned by the packet and erase the bytes from
- // our communcation buffer "m_bytes"
- packet.SetData(DataBufferSP(new DataBufferHeap(&m_bytes[0], length)));
- m_bytes.erase(0, length);
-
- if (log) {
- PacketStreamType log_strm;
- DumpPacket(log_strm, packet);
-
- log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
- }
- return true;
- }
- } break;
-
- default:
- // Unrecognized reply command byte, erase this byte and try to get back
- // on track
- if (log)
- log->Printf("CommunicationKDP::%s: tossing junk byte: 0x%2.2x",
- __FUNCTION__, (uint8_t)m_bytes[0]);
- m_bytes.erase(0, 1);
- break;
- }
- }
- packet.Clear();
- return false;
-}
-
-bool CommunicationKDP::SendRequestConnect(uint16_t reply_port,
- uint16_t exc_port,
- const char *greeting) {
- PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
- m_byte_order);
- if (greeting == NULL)
- greeting = "";
-
- const CommandType command = KDP_CONNECT;
- // Length is 82 uint16_t and the length of the greeting C string with the
- // terminating NULL
- const uint32_t command_length = 8 + 2 + 2 + ::strlen(greeting) + 1;
- MakeRequestPacketHeader(command, request_packet, command_length);
- // Always send connect ports as little endian
- request_packet.SetByteOrder(eByteOrderLittle);
- request_packet.PutHex16(htons(reply_port));
- request_packet.PutHex16(htons(exc_port));
- request_packet.SetByteOrder(m_byte_order);
- request_packet.PutCString(greeting);
- DataExtractor reply_packet;
- return SendRequestAndGetReply(command, request_packet, reply_packet);
-}
-
-void CommunicationKDP::ClearKDPSettings() {
- m_request_sequence_id = 0;
- m_kdp_version_version = 0;
- m_kdp_version_feature = 0;
- m_kdp_hostinfo_cpu_mask = 0;
- m_kdp_hostinfo_cpu_type = 0;
- m_kdp_hostinfo_cpu_subtype = 0;
-}
-
-bool CommunicationKDP::SendRequestReattach(uint16_t reply_port) {
- PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
- m_byte_order);
- const CommandType command = KDP_REATTACH;
- // Length is 8 bytes for the header plus 2 bytes for the reply UDP port
- const uint32_t command_length = 8 + 2;
- MakeRequestPacketHeader(command, request_packet, command_length);
- // Always send connect ports as little endian
- request_packet.SetByteOrder(eByteOrderLittle);
- request_packet.PutHex16(htons(reply_port));
- request_packet.SetByteOrder(m_byte_order);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
- // Reset the sequence ID to zero for reattach
- ClearKDPSettings();
- lldb::offset_t offset = 4;
- m_session_key = reply_packet.GetU32(&offset);
- return true;
- }
- return false;
-}
-
-uint32_t CommunicationKDP::GetVersion() {
- if (!VersionIsValid())
- SendRequestVersion();
- return m_kdp_version_version;
-}
-
-uint32_t CommunicationKDP::GetFeatureFlags() {
- if (!VersionIsValid())
- SendRequestVersion();
- return m_kdp_version_feature;
-}
-
-bool CommunicationKDP::SendRequestVersion() {
- PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
- m_byte_order);
- const CommandType command = KDP_VERSION;
- const uint32_t command_length = 8;
- MakeRequestPacketHeader(command, request_packet, command_length);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
- lldb::offset_t offset = 8;
- m_kdp_version_version = reply_packet.GetU32(&offset);
- m_kdp_version_feature = reply_packet.GetU32(&offset);
- return true;
- }
- return false;
-}
-
-uint32_t CommunicationKDP::GetCPUMask() {
- if (!HostInfoIsValid())
- SendRequestHostInfo();
- return m_kdp_hostinfo_cpu_mask;
-}
-
-uint32_t CommunicationKDP::GetCPUType() {
- if (!HostInfoIsValid())
- SendRequestHostInfo();
- return m_kdp_hostinfo_cpu_type;
-}
-
-uint32_t CommunicationKDP::GetCPUSubtype() {
- if (!HostInfoIsValid())
- SendRequestHostInfo();
- return m_kdp_hostinfo_cpu_subtype;
-}
-
-lldb_private::UUID CommunicationKDP::GetUUID() {
- UUID uuid;
- if (GetKernelVersion() == NULL)
- return uuid;
-
- if (m_kernel_version.find("UUID=") == std::string::npos)
- return uuid;
-
- size_t p = m_kernel_version.find("UUID=") + strlen("UUID=");
- std::string uuid_str = m_kernel_version.substr(p, 36);
- if (uuid_str.size() < 32)
- return uuid;
-
- if (uuid.SetFromStringRef(uuid_str) == 0) {
- UUID invalid_uuid;
- return invalid_uuid;
- }
-
- return uuid;
-}
-
-bool CommunicationKDP::RemoteIsEFI() {
- if (GetKernelVersion() == NULL)
- return false;
- return strncmp(m_kernel_version.c_str(), "EFI", 3) == 0;
-}
-
-bool CommunicationKDP::RemoteIsDarwinKernel() {
- if (GetKernelVersion() == NULL)
- return false;
- return m_kernel_version.find("Darwin Kernel") != std::string::npos;
-}
-
-lldb::addr_t CommunicationKDP::GetLoadAddress() {
- if (GetKernelVersion() == NULL)
- return LLDB_INVALID_ADDRESS;
-
- if (m_kernel_version.find("stext=") == std::string::npos)
- return LLDB_INVALID_ADDRESS;
- size_t p = m_kernel_version.find("stext=") + strlen("stext=");
- if (m_kernel_version[p] != '0' || m_kernel_version[p + 1] != 'x')
- return LLDB_INVALID_ADDRESS;
-
- addr_t kernel_load_address;
- errno = 0;
- kernel_load_address = ::strtoul(m_kernel_version.c_str() + p, NULL, 16);
- if (errno != 0 || kernel_load_address == 0)
- return LLDB_INVALID_ADDRESS;
-
- return kernel_load_address;
-}
-
-bool CommunicationKDP::SendRequestHostInfo() {
- PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
- m_byte_order);
- const CommandType command = KDP_HOSTINFO;
- const uint32_t command_length = 8;
- MakeRequestPacketHeader(command, request_packet, command_length);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
- lldb::offset_t offset = 8;
- m_kdp_hostinfo_cpu_mask = reply_packet.GetU32(&offset);
- m_kdp_hostinfo_cpu_type = reply_packet.GetU32(&offset);
- m_kdp_hostinfo_cpu_subtype = reply_packet.GetU32(&offset);
-
- ArchSpec kernel_arch;
- kernel_arch.SetArchitecture(eArchTypeMachO, m_kdp_hostinfo_cpu_type,
- m_kdp_hostinfo_cpu_subtype);
-
- m_addr_byte_size = kernel_arch.GetAddressByteSize();
- m_byte_order = kernel_arch.GetByteOrder();
- return true;
- }
- return false;
-}
-
-const char *CommunicationKDP::GetKernelVersion() {
- if (m_kernel_version.empty())
- SendRequestKernelVersion();
- return m_kernel_version.c_str();
-}
-
-bool CommunicationKDP::SendRequestKernelVersion() {
- PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
- m_byte_order);
- const CommandType command = KDP_KERNELVERSION;
- const uint32_t command_length = 8;
- MakeRequestPacketHeader(command, request_packet, command_length);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
- const char *kernel_version_cstr = reply_packet.PeekCStr(8);
- if (kernel_version_cstr && kernel_version_cstr[0])
- m_kernel_version.assign(kernel_version_cstr);
- return true;
- }
- return false;
-}
-
-bool CommunicationKDP::SendRequestDisconnect() {
- PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
- m_byte_order);
- const CommandType command = KDP_DISCONNECT;
- const uint32_t command_length = 8;
- MakeRequestPacketHeader(command, request_packet, command_length);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
- // Are we supposed to get a reply for disconnect?
- }
- ClearKDPSettings();
- return true;
-}
-
-uint32_t CommunicationKDP::SendRequestReadMemory(lldb::addr_t addr, void *dst,
- uint32_t dst_len,
- Status &error) {
- PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
- m_byte_order);
- bool use_64 = (GetVersion() >= 11);
- uint32_t command_addr_byte_size = use_64 ? 8 : 4;
- const CommandType command = use_64 ? KDP_READMEM64 : KDP_READMEM;
- // Size is header + address size + uint32_t length
- const uint32_t command_length = 8 + command_addr_byte_size + 4;
- MakeRequestPacketHeader(command, request_packet, command_length);
- request_packet.PutMaxHex64(addr, command_addr_byte_size);
- request_packet.PutHex32(dst_len);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
- lldb::offset_t offset = 8;
- uint32_t kdp_error = reply_packet.GetU32(&offset);
- uint32_t src_len = reply_packet.GetByteSize() - 12;
-
- if (src_len > 0) {
- const void *src = reply_packet.GetData(&offset, src_len);
- if (src) {
- ::memcpy(dst, src, src_len);
- error.Clear();
- return src_len;
- }
- }
- if (kdp_error)
- error.SetErrorStringWithFormat("kdp read memory failed (error %u)",
- kdp_error);
- else
- error.SetErrorString("kdp read memory failed");
- } else {
- error.SetErrorString("failed to send packet");
- }
- return 0;
-}
-
-uint32_t CommunicationKDP::SendRequestWriteMemory(lldb::addr_t addr,
- const void *src,
- uint32_t src_len,
- Status &error) {
- PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
- m_byte_order);
- bool use_64 = (GetVersion() >= 11);
- uint32_t command_addr_byte_size = use_64 ? 8 : 4;
- const CommandType command = use_64 ? KDP_WRITEMEM64 : KDP_WRITEMEM;
- // Size is header + address size + uint32_t length
- const uint32_t command_length = 8 + command_addr_byte_size + 4 + src_len;
- MakeRequestPacketHeader(command, request_packet, command_length);
- request_packet.PutMaxHex64(addr, command_addr_byte_size);
- request_packet.PutHex32(src_len);
- request_packet.PutRawBytes(src, src_len);
-
- DataExtractor reply_packet;
- if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
- lldb::offset_t offset = 8;
- uint32_t kdp_error = reply_packet.GetU32(&offset);
- if (kdp_error)
- error.SetErrorStringWithFormat("kdp write memory failed (error %u)",
- kdp_error);
- else {
- error.Clear();
- return src_len;
- }
- } else {
- error.SetErrorString("failed to send packet");
- }
- return 0;
-}
-
-bool CommunicationKDP::SendRawRequest(
- uint8_t command_byte,
- const void *src, // Raw packet payload bytes
- uint32_t src_len, // Raw packet payload length
- DataExtractor &reply_packet, Status &error) {
- PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
- m_byte_order);
- // Size is header + address size + uint32_t length
- const uint32_t command_length = 8 + src_len;
- const CommandType command = (CommandType)command_byte;
- MakeRequestPacketHeader(command, request_packet, command_length);
- request_packet.PutRawBytes(src, src_len);
-
- if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
- lldb::offset_t offset = 8;
- uint32_t kdp_error = reply_packet.GetU32(&offset);
- if (kdp_error && (command_byte != KDP_DUMPINFO))
- error.SetErrorStringWithFormat("request packet 0x%8.8x failed (error %u)",
- command_byte, kdp_error);
- else {
- error.Clear();
- return true;
- }
- } else {
- error.SetErrorString("failed to send packet");
- }
- return false;
-}
-
-const char *CommunicationKDP::GetCommandAsCString(uint8_t command) {
- switch (command) {
- case KDP_CONNECT:
- return "KDP_CONNECT";
- case KDP_DISCONNECT:
- return "KDP_DISCONNECT";
- case KDP_HOSTINFO:
- return "KDP_HOSTINFO";
- case KDP_VERSION:
- return "KDP_VERSION";
- case KDP_MAXBYTES:
- return "KDP_MAXBYTES";
- case KDP_READMEM:
- return "KDP_READMEM";
- case KDP_WRITEMEM:
- return "KDP_WRITEMEM";
- case KDP_READREGS:
- return "KDP_READREGS";
- case KDP_WRITEREGS:
- return "KDP_WRITEREGS";
- case KDP_LOAD:
- return "KDP_LOAD";
- case KDP_IMAGEPATH:
- return "KDP_IMAGEPATH";
- case KDP_SUSPEND:
- return "KDP_SUSPEND";
- case KDP_RESUMECPUS:
- return "KDP_RESUMECPUS";
- case KDP_EXCEPTION:
- return "KDP_EXCEPTION";
- case KDP_TERMINATION:
- return "KDP_TERMINATION";
- case KDP_BREAKPOINT_SET:
- return "KDP_BREAKPOINT_SET";
- case KDP_BREAKPOINT_REMOVE:
- return "KDP_BREAKPOINT_REMOVE";
- case KDP_REGIONS:
- return "KDP_REGIONS";
- case KDP_REATTACH:
- return "KDP_REATTACH";
- case KDP_HOSTREBOOT:
- return "KDP_HOSTREBOOT";
- case KDP_READMEM64:
- return "KDP_READMEM64";
- case KDP_WRITEMEM64:
- return "KDP_WRITEMEM64";
- case KDP_BREAKPOINT_SET64:
- return "KDP_BREAKPOINT64_SET";
- case KDP_BREAKPOINT_REMOVE64:
- return "KDP_BREAKPOINT64_REMOVE";
- case KDP_KERNELVERSION:
- return "KDP_KERNELVERSION";
- case KDP_READPHYSMEM64:
- return "KDP_READPHYSMEM64";
- case KDP_WRITEPHYSMEM64:
- return "KDP_WRITEPHYSMEM64";
- case KDP_READIOPORT:
- return "KDP_READIOPORT";
- case KDP_WRITEIOPORT:
- return "KDP_WRITEIOPORT";
- case KDP_READMSR64:
- return "KDP_READMSR64";
- case KDP_WRITEMSR64:
- return "KDP_WRITEMSR64";
- case KDP_DUMPINFO:
- return "KDP_DUMPINFO";
- }
- return NULL;
-}
-
-void CommunicationKDP::DumpPacket(Stream &s, const void *data,
- uint32_t data_len) {
- DataExtractor extractor(data, data_len, m_byte_order, m_addr_byte_size);
- DumpPacket(s, extractor);
-}
-
-void CommunicationKDP::DumpPacket(Stream &s, const DataExtractor &packet) {
- const char *error_desc = NULL;
- if (packet.GetByteSize() < 8) {
- error_desc = "error: invalid packet (too short): ";
- } else {
- lldb::offset_t offset = 0;
- const uint8_t first_packet_byte = packet.GetU8(&offset);
- const uint8_t sequence_id = packet.GetU8(&offset);
- const uint16_t length = packet.GetU16(&offset);
- const uint32_t key = packet.GetU32(&offset);
- const CommandType command = ExtractCommand(first_packet_byte);
- const char *command_name = GetCommandAsCString(command);
- if (command_name) {
- const bool is_reply = ExtractIsReply(first_packet_byte);
- s.Printf("(running=%i) %s %24s: 0x%2.2x 0x%2.2x 0x%4.4x 0x%8.8x ",
- IsRunning(), is_reply ? "<--" : "-->", command_name,
- first_packet_byte, sequence_id, length, key);
-
- if (is_reply) {
- // Dump request reply packets
- switch (command) {
- // Commands that return a single 32 bit error
- case KDP_CONNECT:
- case KDP_WRITEMEM:
- case KDP_WRITEMEM64:
- case KDP_BREAKPOINT_SET:
- case KDP_BREAKPOINT_REMOVE:
- case KDP_BREAKPOINT_SET64:
- case KDP_BREAKPOINT_REMOVE64:
- case KDP_WRITEREGS:
- case KDP_LOAD:
- case KDP_WRITEIOPORT:
- case KDP_WRITEMSR64: {
- const uint32_t error = packet.GetU32(&offset);
- s.Printf(" (error=0x%8.8x)", error);
- } break;
-
- case KDP_DISCONNECT:
- case KDP_REATTACH:
- case KDP_HOSTREBOOT:
- case KDP_SUSPEND:
- case KDP_RESUMECPUS:
- case KDP_EXCEPTION:
- case KDP_TERMINATION:
- // No return value for the reply, just the header to ack
- s.PutCString(" ()");
- break;
-
- case KDP_HOSTINFO: {
- const uint32_t cpu_mask = packet.GetU32(&offset);
- const uint32_t cpu_type = packet.GetU32(&offset);
- const uint32_t cpu_subtype = packet.GetU32(&offset);
- s.Printf(" (cpu_mask=0x%8.8x, cpu_type=0x%8.8x, cpu_subtype=0x%8.8x)",
- cpu_mask, cpu_type, cpu_subtype);
- } break;
-
- case KDP_VERSION: {
- const uint32_t version = packet.GetU32(&offset);
- const uint32_t feature = packet.GetU32(&offset);
- s.Printf(" (version=0x%8.8x, feature=0x%8.8x)", version, feature);
- } break;
-
- case KDP_REGIONS: {
- const uint32_t region_count = packet.GetU32(&offset);
- s.Printf(" (count = %u", region_count);
- for (uint32_t i = 0; i < region_count; ++i) {
- const addr_t region_addr = packet.GetPointer(&offset);
- const uint32_t region_size = packet.GetU32(&offset);
- const uint32_t region_prot = packet.GetU32(&offset);
- s.Printf("\n\tregion[%" PRIu64 "] = { range = [0x%16.16" PRIx64
- " - 0x%16.16" PRIx64 "), size = 0x%8.8x, prot = %s }",
- region_addr, region_addr, region_addr + region_size,
- region_size, GetPermissionsAsCString(region_prot));
- }
- } break;
-
- case KDP_READMEM:
- case KDP_READMEM64:
- case KDP_READPHYSMEM64: {
- const uint32_t error = packet.GetU32(&offset);
- const uint32_t count = packet.GetByteSize() - offset;
- s.Printf(" (error = 0x%8.8x:\n", error);
- if (count > 0)
- DumpDataExtractor(packet,
- &s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatBytesWithASCII, // Format to use
- 1, // Size of each item
- // in bytes
- count, // Number of items
- 16, // Number per line
- m_last_read_memory_addr, // Don't show addresses
- // before each line
- 0, 0); // No bitfields
- } break;
-
- case KDP_READREGS: {
- const uint32_t error = packet.GetU32(&offset);
- const uint32_t count = packet.GetByteSize() - offset;
- s.Printf(" (error = 0x%8.8x regs:\n", error);
- if (count > 0)
- DumpDataExtractor(packet,
- &s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- m_addr_byte_size, // Size of each item
- // in bytes
- count / m_addr_byte_size, // Number of items
- 16 / m_addr_byte_size, // Number per line
- LLDB_INVALID_ADDRESS,
- // Don't
- // show addresses before
- // each line
- 0, 0); // No bitfields
- } break;
-
- case KDP_KERNELVERSION: {
- const char *kernel_version = packet.PeekCStr(8);
- s.Printf(" (version = \"%s\")", kernel_version);
- } break;
-
- case KDP_MAXBYTES: {
- const uint32_t max_bytes = packet.GetU32(&offset);
- s.Printf(" (max_bytes = 0x%8.8x (%u))", max_bytes, max_bytes);
- } break;
- case KDP_IMAGEPATH: {
- const char *path = packet.GetCStr(&offset);
- s.Printf(" (path = \"%s\")", path);
- } break;
-
- case KDP_READIOPORT:
- case KDP_READMSR64: {
- const uint32_t error = packet.GetU32(&offset);
- const uint32_t count = packet.GetByteSize() - offset;
- s.Printf(" (error = 0x%8.8x io:\n", error);
- if (count > 0)
- DumpDataExtractor(packet,
- &s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- 1, // Size of each item in bytes
- count, // Number of items
- 16, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses
- // before each line
- 0, 0); // No bitfields
- } break;
- case KDP_DUMPINFO: {
- const uint32_t count = packet.GetByteSize() - offset;
- s.Printf(" (count = %u, bytes = \n", count);
- if (count > 0)
- DumpDataExtractor(packet,
- &s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- 1, // Size of each item in
- // bytes
- count, // Number of items
- 16, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses
- // before each line
- 0, 0); // No bitfields
-
- } break;
-
- default:
- s.Printf(" (add support for dumping this packet reply!!!");
- break;
- }
- } else {
- // Dump request packets
- switch (command) {
- case KDP_CONNECT: {
- const uint16_t reply_port = ntohs(packet.GetU16(&offset));
- const uint16_t exc_port = ntohs(packet.GetU16(&offset));
- s.Printf(" (reply_port = %u, exc_port = %u, greeting = \"%s\")",
- reply_port, exc_port, packet.GetCStr(&offset));
- } break;
-
- case KDP_DISCONNECT:
- case KDP_HOSTREBOOT:
- case KDP_HOSTINFO:
- case KDP_VERSION:
- case KDP_REGIONS:
- case KDP_KERNELVERSION:
- case KDP_MAXBYTES:
- case KDP_IMAGEPATH:
- case KDP_SUSPEND:
- // No args, just the header in the request...
- s.PutCString(" ()");
- break;
-
- case KDP_RESUMECPUS: {
- const uint32_t cpu_mask = packet.GetU32(&offset);
- s.Printf(" (cpu_mask = 0x%8.8x)", cpu_mask);
- } break;
-
- case KDP_READMEM: {
- const uint32_t addr = packet.GetU32(&offset);
- const uint32_t size = packet.GetU32(&offset);
- s.Printf(" (addr = 0x%8.8x, size = %u)", addr, size);
- m_last_read_memory_addr = addr;
- } break;
-
- case KDP_WRITEMEM: {
- const uint32_t addr = packet.GetU32(&offset);
- const uint32_t size = packet.GetU32(&offset);
- s.Printf(" (addr = 0x%8.8x, size = %u, bytes = \n", addr, size);
- if (size > 0)
- DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
- } break;
-
- case KDP_READMEM64: {
- const uint64_t addr = packet.GetU64(&offset);
- const uint32_t size = packet.GetU32(&offset);
- s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u)", addr, size);
- m_last_read_memory_addr = addr;
- } break;
-
- case KDP_READPHYSMEM64: {
- const uint64_t addr = packet.GetU64(&offset);
- const uint32_t size = packet.GetU32(&offset);
- const uint32_t lcpu = packet.GetU16(&offset);
- s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u)", addr, size,
- lcpu);
- m_last_read_memory_addr = addr;
- } break;
-
- case KDP_WRITEMEM64: {
- const uint64_t addr = packet.GetU64(&offset);
- const uint32_t size = packet.GetU32(&offset);
- s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u, bytes = \n", addr,
- size);
- if (size > 0)
- DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
- } break;
-
- case KDP_WRITEPHYSMEM64: {
- const uint64_t addr = packet.GetU64(&offset);
- const uint32_t size = packet.GetU32(&offset);
- const uint32_t lcpu = packet.GetU16(&offset);
- s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u, bytes = \n",
- addr, size, lcpu);
- if (size > 0)
- DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
- } break;
-
- case KDP_READREGS: {
- const uint32_t cpu = packet.GetU32(&offset);
- const uint32_t flavor = packet.GetU32(&offset);
- s.Printf(" (cpu = %u, flavor = %u)", cpu, flavor);
- } break;
-
- case KDP_WRITEREGS: {
- const uint32_t cpu = packet.GetU32(&offset);
- const uint32_t flavor = packet.GetU32(&offset);
- const uint32_t nbytes = packet.GetByteSize() - offset;
- s.Printf(" (cpu = %u, flavor = %u, regs = \n", cpu, flavor);
- if (nbytes > 0)
- DumpDataExtractor(packet,
- &s, // Stream to dump to
- offset, // Offset within
- // "packet"
- eFormatHex, // Format to use
- m_addr_byte_size, // Size of each item in
- // bytes
- nbytes / m_addr_byte_size, // Number of items
- 16 / m_addr_byte_size, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses
- // before each line
- 0, 0); // No bitfields
- } break;
-
- case KDP_BREAKPOINT_SET:
- case KDP_BREAKPOINT_REMOVE: {
- const uint32_t addr = packet.GetU32(&offset);
- s.Printf(" (addr = 0x%8.8x)", addr);
- } break;
-
- case KDP_BREAKPOINT_SET64:
- case KDP_BREAKPOINT_REMOVE64: {
- const uint64_t addr = packet.GetU64(&offset);
- s.Printf(" (addr = 0x%16.16" PRIx64 ")", addr);
- } break;
-
- case KDP_LOAD: {
- const char *path = packet.GetCStr(&offset);
- s.Printf(" (path = \"%s\")", path);
- } break;
-
- case KDP_EXCEPTION: {
- const uint32_t count = packet.GetU32(&offset);
-
- for (uint32_t i = 0; i < count; ++i) {
- const uint32_t cpu = packet.GetU32(&offset);
- const uint32_t exc = packet.GetU32(&offset);
- const uint32_t code = packet.GetU32(&offset);
- const uint32_t subcode = packet.GetU32(&offset);
- const char *exc_cstr = NULL;
- switch (exc) {
- case 1:
- exc_cstr = "EXC_BAD_ACCESS";
- break;
- case 2:
- exc_cstr = "EXC_BAD_INSTRUCTION";
- break;
- case 3:
- exc_cstr = "EXC_ARITHMETIC";
- break;
- case 4:
- exc_cstr = "EXC_EMULATION";
- break;
- case 5:
- exc_cstr = "EXC_SOFTWARE";
- break;
- case 6:
- exc_cstr = "EXC_BREAKPOINT";
- break;
- case 7:
- exc_cstr = "EXC_SYSCALL";
- break;
- case 8:
- exc_cstr = "EXC_MACH_SYSCALL";
- break;
- case 9:
- exc_cstr = "EXC_RPC_ALERT";
- break;
- case 10:
- exc_cstr = "EXC_CRASH";
- break;
- default:
- break;
- }
-
- s.Printf("{ cpu = 0x%8.8x, exc = %s (%u), code = %u (0x%8.8x), "
- "subcode = %u (0x%8.8x)} ",
- cpu, exc_cstr, exc, code, code, subcode, subcode);
- }
- } break;
-
- case KDP_TERMINATION: {
- const uint32_t term_code = packet.GetU32(&offset);
- const uint32_t exit_code = packet.GetU32(&offset);
- s.Printf(" (term_code = 0x%8.8x (%u), exit_code = 0x%8.8x (%u))",
- term_code, term_code, exit_code, exit_code);
- } break;
-
- case KDP_REATTACH: {
- const uint16_t reply_port = ntohs(packet.GetU16(&offset));
- s.Printf(" (reply_port = %u)", reply_port);
- } break;
-
- case KDP_READMSR64: {
- const uint32_t address = packet.GetU32(&offset);
- const uint16_t lcpu = packet.GetU16(&offset);
- s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x)", address, lcpu);
- } break;
-
- case KDP_WRITEMSR64: {
- const uint32_t address = packet.GetU32(&offset);
- const uint16_t lcpu = packet.GetU16(&offset);
- const uint32_t nbytes = packet.GetByteSize() - offset;
- s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x, nbytes=0x%8.8x)", lcpu,
- address, nbytes);
- if (nbytes > 0)
- DumpDataExtractor(packet,
- &s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- 1, // Size of each item in
- // bytes
- nbytes, // Number of items
- 16, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses
- // before each line
- 0, 0); // No bitfields
- } break;
-
- case KDP_READIOPORT: {
- const uint16_t lcpu = packet.GetU16(&offset);
- const uint16_t address = packet.GetU16(&offset);
- const uint16_t nbytes = packet.GetU16(&offset);
- s.Printf(" (lcpu=0x%4.4x, address=0x%4.4x, nbytes=%u)", lcpu, address,
- nbytes);
- } break;
-
- case KDP_WRITEIOPORT: {
- const uint16_t lcpu = packet.GetU16(&offset);
- const uint16_t address = packet.GetU16(&offset);
- const uint16_t nbytes = packet.GetU16(&offset);
- s.Printf(" (lcpu = %u, addr = 0x%4.4x, nbytes = %u, bytes = \n", lcpu,
- address, nbytes);
- if (nbytes > 0)
- DumpDataExtractor(packet,
- &s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- 1, // Size of each item in
- // bytes
- nbytes, // Number of items
- 16, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses
- // before each line
- 0, 0); // No bitfields
- } break;
-
- case KDP_DUMPINFO: {
- const uint32_t count = packet.GetByteSize() - offset;
- s.Printf(" (count = %u, bytes = \n", count);
- if (count > 0)
- DumpDataExtractor(packet,
- &s, // Stream to dump to
- offset, // Offset within "packet"
- eFormatHex, // Format to use
- 1, // Size of each item in bytes
- count, // Number of items
- 16, // Number per line
- LLDB_INVALID_ADDRESS, // Don't show addresses before each line
- 0, 0); // No bitfields
-
- } break;
- }
- }
- } else {
- error_desc = "error: invalid packet command: ";
- }
- }
-
- if (error_desc) {
- s.PutCString(error_desc);
-
- DumpDataExtractor(packet,
- &s, // Stream to dump to
- 0, // Offset into "packet"
- eFormatBytes, // Dump as hex bytes
- 1, // Size of each item is 1 for
- // single bytes
- packet.GetByteSize(), // Number of bytes
- UINT32_MAX, // Num bytes per line
- LLDB_INVALID_ADDRESS, // Base address
- 0, 0); // Bitfield info set to not do
- // anything bitfield related
- }
-}
-
-uint32_t CommunicationKDP::SendRequestReadRegisters(uint32_t cpu,
- uint32_t flavor, void *dst,
- uint32_t dst_len,
- Status &error) {
- PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
- m_byte_order);
- const CommandType command = KDP_READREGS;
- // Size is header + 4 byte cpu and 4 byte flavor
- const uint32_t command_length = 8 + 4 + 4;
- MakeRequestPacketHeader(command, request_packet, command_length);
- request_packet.PutHex32(cpu);
- request_packet.PutHex32(flavor);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
- lldb::offset_t offset = 8;
- uint32_t kdp_error = reply_packet.GetU32(&offset);
- uint32_t src_len = reply_packet.GetByteSize() - 12;
-
- if (src_len > 0) {
- const uint32_t bytes_to_copy = std::min<uint32_t>(src_len, dst_len);
- const void *src = reply_packet.GetData(&offset, bytes_to_copy);
- if (src) {
- ::memcpy(dst, src, bytes_to_copy);
- error.Clear();
- // Return the number of bytes we could have returned regardless if we
- // copied them or not, just so we know when things don't match up
- return src_len;
- }
- }
- if (kdp_error)
- error.SetErrorStringWithFormat(
- "failed to read kdp registers for cpu %u flavor %u (error %u)", cpu,
- flavor, kdp_error);
- else
- error.SetErrorStringWithFormat(
- "failed to read kdp registers for cpu %u flavor %u", cpu, flavor);
- } else {
- error.SetErrorString("failed to send packet");
- }
- return 0;
-}
-
-uint32_t CommunicationKDP::SendRequestWriteRegisters(uint32_t cpu,
- uint32_t flavor,
- const void *src,
- uint32_t src_len,
- Status &error) {
- PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
- m_byte_order);
- const CommandType command = KDP_WRITEREGS;
- // Size is header + 4 byte cpu and 4 byte flavor
- const uint32_t command_length = 8 + 4 + 4 + src_len;
- MakeRequestPacketHeader(command, request_packet, command_length);
- request_packet.PutHex32(cpu);
- request_packet.PutHex32(flavor);
- request_packet.Write(src, src_len);
- DataExtractor reply_packet;
- if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
- lldb::offset_t offset = 8;
- uint32_t kdp_error = reply_packet.GetU32(&offset);
- if (kdp_error == 0)
- return src_len;
- error.SetErrorStringWithFormat(
- "failed to read kdp registers for cpu %u flavor %u (error %u)", cpu,
- flavor, kdp_error);
- } else {
- error.SetErrorString("failed to send packet");
- }
- return 0;
-}
-
-bool CommunicationKDP::SendRequestResume() {
- PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
- m_byte_order);
- const CommandType command = KDP_RESUMECPUS;
- const uint32_t command_length = 12;
- MakeRequestPacketHeader(command, request_packet, command_length);
- request_packet.PutHex32(GetCPUMask());
-
- DataExtractor reply_packet;
- return SendRequestAndGetReply(command, request_packet, reply_packet);
-}
-
-bool CommunicationKDP::SendRequestBreakpoint(bool set, addr_t addr) {
- PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
- m_byte_order);
- bool use_64 = (GetVersion() >= 11);
- uint32_t command_addr_byte_size = use_64 ? 8 : 4;
- const CommandType command =
- set ? (use_64 ? KDP_BREAKPOINT_SET64 : KDP_BREAKPOINT_SET)
- : (use_64 ? KDP_BREAKPOINT_REMOVE64 : KDP_BREAKPOINT_REMOVE);
-
- const uint32_t command_length = 8 + command_addr_byte_size;
- MakeRequestPacketHeader(command, request_packet, command_length);
- request_packet.PutMaxHex64(addr, command_addr_byte_size);
-
- DataExtractor reply_packet;
- if (SendRequestAndGetReply(command, request_packet, reply_packet)) {
- lldb::offset_t offset = 8;
- uint32_t kdp_error = reply_packet.GetU32(&offset);
- if (kdp_error == 0)
- return true;
- }
- return false;
-}
-
-bool CommunicationKDP::SendRequestSuspend() {
- PacketStreamType request_packet(Stream::eBinary, m_addr_byte_size,
- m_byte_order);
- const CommandType command = KDP_SUSPEND;
- const uint32_t command_length = 8;
- MakeRequestPacketHeader(command, request_packet, command_length);
- DataExtractor reply_packet;
- return SendRequestAndGetReply(command, request_packet, reply_packet);
-}
diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
deleted file mode 100644
index 64bfe55147350..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
+++ /dev/null
@@ -1,260 +0,0 @@
-//===-- CommunicationKDP.h --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_CommunicationKDP_h_
-#define liblldb_CommunicationKDP_h_
-
-#include <list>
-#include <mutex>
-#include <string>
-
-#include "lldb/Core/Communication.h"
-#include "lldb/Core/StreamBuffer.h"
-#include "lldb/Utility/Listener.h"
-#include "lldb/Utility/Predicate.h"
-#include "lldb/lldb-private.h"
-
-class CommunicationKDP : public lldb_private::Communication {
-public:
- enum { eBroadcastBitRunPacketSent = kLoUserBroadcastBit };
-
- const static uint32_t kMaxPacketSize = 1200;
- const static uint32_t kMaxDataSize = 1024;
- typedef lldb_private::StreamBuffer<1024> PacketStreamType;
- typedef enum {
- KDP_CONNECT = 0u,
- KDP_DISCONNECT,
- KDP_HOSTINFO,
- KDP_VERSION,
- KDP_MAXBYTES,
- KDP_READMEM,
- KDP_WRITEMEM,
- KDP_READREGS,
- KDP_WRITEREGS,
- KDP_LOAD,
- KDP_IMAGEPATH,
- KDP_SUSPEND,
- KDP_RESUMECPUS,
- KDP_EXCEPTION,
- KDP_TERMINATION,
- KDP_BREAKPOINT_SET,
- KDP_BREAKPOINT_REMOVE,
- KDP_REGIONS,
- KDP_REATTACH,
- KDP_HOSTREBOOT,
- KDP_READMEM64,
- KDP_WRITEMEM64,
- KDP_BREAKPOINT_SET64,
- KDP_BREAKPOINT_REMOVE64,
- KDP_KERNELVERSION,
- KDP_READPHYSMEM64,
- KDP_WRITEPHYSMEM64,
- KDP_READIOPORT,
- KDP_WRITEIOPORT,
- KDP_READMSR64,
- KDP_WRITEMSR64,
- KDP_DUMPINFO
- } CommandType;
-
- enum { KDP_FEATURE_BP = (1u << 0) };
-
- typedef enum {
- KDP_PROTERR_SUCCESS = 0,
- KDP_PROTERR_ALREADY_CONNECTED,
- KDP_PROTERR_BAD_NBYTES,
- KDP_PROTERR_BADFLAVOR
- } KDPError;
-
- typedef enum {
- ePacketTypeRequest = 0x00u,
- ePacketTypeReply = 0x80u,
- ePacketTypeMask = 0x80u,
- eCommandTypeMask = 0x7fu
- } PacketType;
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CommunicationKDP(const char *comm_name);
-
- virtual ~CommunicationKDP();
-
- bool SendRequestPacket(const PacketStreamType &request_packet);
-
- // Wait for a packet within 'nsec' seconds
- size_t
- WaitForPacketWithTimeoutMicroSeconds(lldb_private::DataExtractor &response,
- uint32_t usec);
-
- bool GetSequenceMutex(std::unique_lock<std::recursive_mutex> &lock);
-
- bool CheckForPacket(const uint8_t *src, size_t src_len,
- lldb_private::DataExtractor &packet);
- bool IsRunning() const { return m_is_running.GetValue(); }
-
- //------------------------------------------------------------------
- // Set the global packet timeout.
- //
- // For clients, this is the timeout that gets used when sending
- // packets and waiting for responses. For servers, this might not
- // get used, and if it doesn't this should be moved to the
- // CommunicationKDPClient.
- //------------------------------------------------------------------
- std::chrono::seconds SetPacketTimeout(std::chrono::seconds packet_timeout) {
- const auto old_packet_timeout = m_packet_timeout;
- m_packet_timeout = packet_timeout;
- return old_packet_timeout;
- }
-
- std::chrono::seconds GetPacketTimeout() const { return m_packet_timeout; }
-
- //------------------------------------------------------------------
- // Public Request Packets
- //------------------------------------------------------------------
- bool SendRequestConnect(uint16_t reply_port, uint16_t exc_port,
- const char *greeting);
-
- bool SendRequestReattach(uint16_t reply_port);
-
- bool SendRequestDisconnect();
-
- uint32_t SendRequestReadMemory(lldb::addr_t addr, void *dst,
- uint32_t dst_size,
- lldb_private::Status &error);
-
- uint32_t SendRequestWriteMemory(lldb::addr_t addr, const void *src,
- uint32_t src_len,
- lldb_private::Status &error);
-
- bool SendRawRequest(uint8_t command_byte, const void *src, uint32_t src_len,
- lldb_private::DataExtractor &reply,
- lldb_private::Status &error);
-
- uint32_t SendRequestReadRegisters(uint32_t cpu, uint32_t flavor, void *dst,
- uint32_t dst_size,
- lldb_private::Status &error);
-
- uint32_t SendRequestWriteRegisters(uint32_t cpu, uint32_t flavor,
- const void *src, uint32_t src_size,
- lldb_private::Status &error);
-
- const char *GetKernelVersion();
-
- // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
- // const char *
- // GetImagePath ();
-
- uint32_t GetVersion();
-
- uint32_t GetFeatureFlags();
-
- bool LocalBreakpointsAreSupported() {
- return (GetFeatureFlags() & KDP_FEATURE_BP) != 0;
- }
-
- uint32_t GetCPUMask();
-
- uint32_t GetCPUType();
-
- uint32_t GetCPUSubtype();
-
- lldb_private::UUID GetUUID();
-
- bool RemoteIsEFI();
-
- bool RemoteIsDarwinKernel();
-
- lldb::addr_t GetLoadAddress();
-
- bool SendRequestResume();
-
- bool SendRequestSuspend();
-
- bool SendRequestBreakpoint(bool set, lldb::addr_t addr);
-
-protected:
- bool SendRequestPacketNoLock(const PacketStreamType &request_packet);
-
- size_t WaitForPacketWithTimeoutMicroSecondsNoLock(
- lldb_private::DataExtractor &response, uint32_t timeout_usec);
-
- bool WaitForNotRunningPrivate(const std::chrono::microseconds &timeout);
-
- void MakeRequestPacketHeader(CommandType request_type,
- PacketStreamType &request_packet,
- uint16_t request_length);
-
- //------------------------------------------------------------------
- // Protected Request Packets (use public accessors which will cache
- // results.
- //------------------------------------------------------------------
- bool SendRequestVersion();
-
- bool SendRequestHostInfo();
-
- bool SendRequestKernelVersion();
-
- // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection...
- // bool
- // SendRequestImagePath ();
-
- void DumpPacket(lldb_private::Stream &s, const void *data, uint32_t data_len);
-
- void DumpPacket(lldb_private::Stream &s,
- const lldb_private::DataExtractor &extractor);
-
- bool VersionIsValid() const { return m_kdp_version_version != 0; }
-
- bool HostInfoIsValid() const { return m_kdp_hostinfo_cpu_type != 0; }
-
- bool ExtractIsReply(uint8_t first_packet_byte) const {
- // TODO: handle big endian...
- return (first_packet_byte & ePacketTypeMask) != 0;
- }
-
- CommandType ExtractCommand(uint8_t first_packet_byte) const {
- // TODO: handle big endian...
- return (CommandType)(first_packet_byte & eCommandTypeMask);
- }
-
- static const char *GetCommandAsCString(uint8_t command);
-
- void ClearKDPSettings();
-
- bool SendRequestAndGetReply(const CommandType command,
- const PacketStreamType &request_packet,
- lldb_private::DataExtractor &reply_packet);
- //------------------------------------------------------------------
- // Classes that inherit from CommunicationKDP can see and modify these
- //------------------------------------------------------------------
- uint32_t m_addr_byte_size;
- lldb::ByteOrder m_byte_order;
- std::chrono::seconds m_packet_timeout;
- std::recursive_mutex m_sequence_mutex; // Restrict access to sending/receiving
- // packets to a single thread at a time
- lldb_private::Predicate<bool> m_is_running;
- uint32_t m_session_key;
- uint8_t m_request_sequence_id;
- uint8_t m_exception_sequence_id;
- uint32_t m_kdp_version_version;
- uint32_t m_kdp_version_feature;
- uint32_t m_kdp_hostinfo_cpu_mask;
- uint32_t m_kdp_hostinfo_cpu_type;
- uint32_t m_kdp_hostinfo_cpu_subtype;
- std::string m_kernel_version;
- // std::string m_image_path; // Disable KDP_IMAGEPATH for now, it seems to
- // hang the KDP connection...
- lldb::addr_t m_last_read_memory_addr; // Last memory read address for logging
-private:
- //------------------------------------------------------------------
- // For CommunicationKDP only
- //------------------------------------------------------------------
- DISALLOW_COPY_AND_ASSIGN(CommunicationKDP);
-};
-
-#endif // liblldb_CommunicationKDP_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
deleted file mode 100644
index c1c3678617c09..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ /dev/null
@@ -1,1037 +0,0 @@
-//===-- ProcessKDP.cpp ------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include <errno.h>
-#include <stdlib.h>
-
-#include <mutex>
-
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Host/ConnectionFileDescriptor.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/Symbols.h"
-#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Host/common/TCPSocket.h"
-#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/CommandObject.h"
-#include "lldb/Interpreter/CommandObjectMultiword.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
-#include "lldb/Interpreter/OptionGroupString.h"
-#include "lldb/Interpreter/OptionGroupUInt64.h"
-#include "lldb/Interpreter/OptionValueProperties.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/State.h"
-#include "lldb/Utility/StringExtractor.h"
-#include "lldb/Utility/UUID.h"
-
-#include "llvm/Support/Threading.h"
-
-#define USEC_PER_SEC 1000000
-
-#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
-#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
-#include "ProcessKDP.h"
-#include "ProcessKDPLog.h"
-#include "ThreadKDP.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-
-static constexpr PropertyDefinition g_properties[] = {
- {"packet-timeout", OptionValue::eTypeUInt64, true, 5, NULL, {},
- "Specify the default packet timeout in seconds."}};
-
-enum { ePropertyPacketTimeout };
-
-class PluginProperties : public Properties {
-public:
- static ConstString GetSettingName() {
- return ProcessKDP::GetPluginNameStatic();
- }
-
- PluginProperties() : Properties() {
- m_collection_sp.reset(new OptionValueProperties(GetSettingName()));
- m_collection_sp->Initialize(g_properties);
- }
-
- virtual ~PluginProperties() {}
-
- uint64_t GetPacketTimeout() {
- const uint32_t idx = ePropertyPacketTimeout;
- return m_collection_sp->GetPropertyAtIndexAsUInt64(
- NULL, idx, g_properties[idx].default_uint_value);
- }
-};
-
-typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
-
-static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() {
- static ProcessKDPPropertiesSP g_settings_sp;
- if (!g_settings_sp)
- g_settings_sp.reset(new PluginProperties());
- return g_settings_sp;
-}
-
-} // anonymous namespace end
-
-static const lldb::tid_t g_kernel_tid = 1;
-
-ConstString ProcessKDP::GetPluginNameStatic() {
- static ConstString g_name("kdp-remote");
- return g_name;
-}
-
-const char *ProcessKDP::GetPluginDescriptionStatic() {
- return "KDP Remote protocol based debugging plug-in for darwin kernel "
- "debugging.";
-}
-
-void ProcessKDP::Terminate() {
- PluginManager::UnregisterPlugin(ProcessKDP::CreateInstance);
-}
-
-lldb::ProcessSP ProcessKDP::CreateInstance(TargetSP target_sp,
- ListenerSP listener_sp,
- const FileSpec *crash_file_path) {
- lldb::ProcessSP process_sp;
- if (crash_file_path == NULL)
- process_sp.reset(new ProcessKDP(target_sp, listener_sp));
- return process_sp;
-}
-
-bool ProcessKDP::CanDebug(TargetSP target_sp, bool plugin_specified_by_name) {
- if (plugin_specified_by_name)
- return true;
-
- // For now we are just making sure the file exists for a given module
- Module *exe_module = target_sp->GetExecutableModulePointer();
- if (exe_module) {
- const llvm::Triple &triple_ref = target_sp->GetArchitecture().GetTriple();
- switch (triple_ref.getOS()) {
- case llvm::Triple::Darwin: // Should use "macosx" for desktop and "ios" for
- // iOS, but accept darwin just in case
- case llvm::Triple::MacOSX: // For desktop targets
- case llvm::Triple::IOS: // For arm targets
- case llvm::Triple::TvOS:
- case llvm::Triple::WatchOS:
- if (triple_ref.getVendor() == llvm::Triple::Apple) {
- ObjectFile *exe_objfile = exe_module->GetObjectFile();
- if (exe_objfile->GetType() == ObjectFile::eTypeExecutable &&
- exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
- return true;
- }
- break;
-
- default:
- break;
- }
- }
- return false;
-}
-
-//----------------------------------------------------------------------
-// ProcessKDP constructor
-//----------------------------------------------------------------------
-ProcessKDP::ProcessKDP(TargetSP target_sp, ListenerSP listener_sp)
- : Process(target_sp, listener_sp),
- m_comm("lldb.process.kdp-remote.communication"),
- m_async_broadcaster(NULL, "lldb.process.kdp-remote.async-broadcaster"),
- m_dyld_plugin_name(), m_kernel_load_addr(LLDB_INVALID_ADDRESS),
- m_command_sp(), m_kernel_thread_wp() {
- m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit,
- "async thread should exit");
- m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue,
- "async thread continue");
- const uint64_t timeout_seconds =
- GetGlobalPluginProperties()->GetPacketTimeout();
- if (timeout_seconds > 0)
- m_comm.SetPacketTimeout(std::chrono::seconds(timeout_seconds));
-}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-ProcessKDP::~ProcessKDP() {
- Clear();
- // We need to call finalize on the process before destroying ourselves to
- // make sure all of the broadcaster cleanup goes as planned. If we destruct
- // this class, then Process::~Process() might have problems trying to fully
- // destroy the broadcaster.
- Finalize();
-}
-
-//----------------------------------------------------------------------
-// PluginInterface
-//----------------------------------------------------------------------
-lldb_private::ConstString ProcessKDP::GetPluginName() {
- return GetPluginNameStatic();
-}
-
-uint32_t ProcessKDP::GetPluginVersion() { return 1; }
-
-Status ProcessKDP::WillLaunch(Module *module) {
- Status error;
- error.SetErrorString("launching not supported in kdp-remote plug-in");
- return error;
-}
-
-Status ProcessKDP::WillAttachToProcessWithID(lldb::pid_t pid) {
- Status error;
- error.SetErrorString(
- "attaching to a by process ID not supported in kdp-remote plug-in");
- return error;
-}
-
-Status ProcessKDP::WillAttachToProcessWithName(const char *process_name,
- bool wait_for_launch) {
- Status error;
- error.SetErrorString(
- "attaching to a by process name not supported in kdp-remote plug-in");
- return error;
-}
-
-bool ProcessKDP::GetHostArchitecture(ArchSpec &arch) {
- uint32_t cpu = m_comm.GetCPUType();
- if (cpu) {
- uint32_t sub = m_comm.GetCPUSubtype();
- arch.SetArchitecture(eArchTypeMachO, cpu, sub);
- // Leave architecture vendor as unspecified unknown
- arch.GetTriple().setVendor(llvm::Triple::UnknownVendor);
- arch.GetTriple().setVendorName(llvm::StringRef());
- return true;
- }
- arch.Clear();
- return false;
-}
-
-Status ProcessKDP::DoConnectRemote(Stream *strm, llvm::StringRef remote_url) {
- Status error;
-
- // Don't let any JIT happen when doing KDP as we can't allocate memory and we
- // don't want to be mucking with threads that might already be handling
- // exceptions
- SetCanJIT(false);
-
- if (remote_url.empty()) {
- error.SetErrorStringWithFormat("empty connection URL");
- return error;
- }
-
- std::unique_ptr<ConnectionFileDescriptor> conn_ap(
- new ConnectionFileDescriptor());
- if (conn_ap.get()) {
- // Only try once for now.
- // TODO: check if we should be retrying?
- const uint32_t max_retry_count = 1;
- for (uint32_t retry_count = 0; retry_count < max_retry_count;
- ++retry_count) {
- if (conn_ap->Connect(remote_url, &error) == eConnectionStatusSuccess)
- break;
- usleep(100000);
- }
- }
-
- if (conn_ap->IsConnected()) {
- const TCPSocket &socket =
- static_cast<const TCPSocket &>(*conn_ap->GetReadObject());
- const uint16_t reply_port = socket.GetLocalPortNumber();
-
- if (reply_port != 0) {
- m_comm.SetConnection(conn_ap.release());
-
- if (m_comm.SendRequestReattach(reply_port)) {
- if (m_comm.SendRequestConnect(reply_port, reply_port,
- "Greetings from LLDB...")) {
- m_comm.GetVersion();
-
- Target &target = GetTarget();
- ArchSpec kernel_arch;
- // The host architecture
- GetHostArchitecture(kernel_arch);
- ArchSpec target_arch = target.GetArchitecture();
- // Merge in any unspecified stuff into the target architecture in
- // case the target arch isn't set at all or incompletely.
- target_arch.MergeFrom(kernel_arch);
- target.SetArchitecture(target_arch);
-
- /* Get the kernel's UUID and load address via KDP_KERNELVERSION
- * packet. */
- /* An EFI kdp session has neither UUID nor load address. */
-
- UUID kernel_uuid = m_comm.GetUUID();
- addr_t kernel_load_addr = m_comm.GetLoadAddress();
-
- if (m_comm.RemoteIsEFI()) {
- // Select an invalid plugin name for the dynamic loader so one
- // doesn't get used since EFI does its own manual loading via
- // python scripting
- static ConstString g_none_dynamic_loader("none");
- m_dyld_plugin_name = g_none_dynamic_loader;
-
- if (kernel_uuid.IsValid()) {
- // If EFI passed in a UUID= try to lookup UUID The slide will not
- // be provided. But the UUID lookup will be used to launch EFI
- // debug scripts from the dSYM, that can load all of the symbols.
- ModuleSpec module_spec;
- module_spec.GetUUID() = kernel_uuid;
- module_spec.GetArchitecture() = target.GetArchitecture();
-
- // Lookup UUID locally, before attempting dsymForUUID like action
- module_spec.GetSymbolFileSpec() =
- Symbols::LocateExecutableSymbolFile(module_spec);
- if (module_spec.GetSymbolFileSpec()) {
- ModuleSpec executable_module_spec =
- Symbols::LocateExecutableObjectFile(module_spec);
- if (FileSystem::Instance().Exists(
- executable_module_spec.GetFileSpec())) {
- module_spec.GetFileSpec() =
- executable_module_spec.GetFileSpec();
- }
- }
- if (!module_spec.GetSymbolFileSpec() ||
- !module_spec.GetSymbolFileSpec())
- Symbols::DownloadObjectAndSymbolFile(module_spec, true);
-
- if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
- ModuleSP module_sp(new Module(module_spec));
- if (module_sp.get() && module_sp->GetObjectFile()) {
- // Get the current target executable
- ModuleSP exe_module_sp(target.GetExecutableModule());
-
- // Make sure you don't already have the right module loaded
- // and they will be uniqued
- if (exe_module_sp.get() != module_sp.get())
- target.SetExecutableModule(module_sp, eLoadDependentsNo);
- }
- }
- }
- } else if (m_comm.RemoteIsDarwinKernel()) {
- m_dyld_plugin_name =
- DynamicLoaderDarwinKernel::GetPluginNameStatic();
- if (kernel_load_addr != LLDB_INVALID_ADDRESS) {
- m_kernel_load_addr = kernel_load_addr;
- }
- }
-
- // Set the thread ID
- UpdateThreadListIfNeeded();
- SetID(1);
- GetThreadList();
- SetPrivateState(eStateStopped);
- StreamSP async_strm_sp(target.GetDebugger().GetAsyncOutputStream());
- if (async_strm_sp) {
- const char *cstr;
- if ((cstr = m_comm.GetKernelVersion()) != NULL) {
- async_strm_sp->Printf("Version: %s\n", cstr);
- async_strm_sp->Flush();
- }
- // if ((cstr = m_comm.GetImagePath ()) != NULL)
- // {
- // async_strm_sp->Printf ("Image Path:
- // %s\n", cstr);
- // async_strm_sp->Flush();
- // }
- }
- } else {
- error.SetErrorString("KDP_REATTACH failed");
- }
- } else {
- error.SetErrorString("KDP_REATTACH failed");
- }
- } else {
- error.SetErrorString("invalid reply port from UDP connection");
- }
- } else {
- if (error.Success())
- error.SetErrorStringWithFormat("failed to connect to '%s'",
- remote_url.str().c_str());
- }
- if (error.Fail())
- m_comm.Disconnect();
-
- return error;
-}
-
-//----------------------------------------------------------------------
-// Process Control
-//----------------------------------------------------------------------
-Status ProcessKDP::DoLaunch(Module *exe_module,
- ProcessLaunchInfo &launch_info) {
- Status error;
- error.SetErrorString("launching not supported in kdp-remote plug-in");
- return error;
-}
-
-Status
-ProcessKDP::DoAttachToProcessWithID(lldb::pid_t attach_pid,
- const ProcessAttachInfo &attach_info) {
- Status error;
- error.SetErrorString(
- "attach to process by ID is not supported in kdp remote debugging");
- return error;
-}
-
-Status
-ProcessKDP::DoAttachToProcessWithName(const char *process_name,
- const ProcessAttachInfo &attach_info) {
- Status error;
- error.SetErrorString(
- "attach to process by name is not supported in kdp remote debugging");
- return error;
-}
-
-void ProcessKDP::DidAttach(ArchSpec &process_arch) {
- Process::DidAttach(process_arch);
-
- Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
- if (log)
- log->Printf("ProcessKDP::DidAttach()");
- if (GetID() != LLDB_INVALID_PROCESS_ID) {
- GetHostArchitecture(process_arch);
- }
-}
-
-addr_t ProcessKDP::GetImageInfoAddress() { return m_kernel_load_addr; }
-
-lldb_private::DynamicLoader *ProcessKDP::GetDynamicLoader() {
- if (m_dyld_ap.get() == NULL)
- m_dyld_ap.reset(DynamicLoader::FindPlugin(
- this,
- m_dyld_plugin_name.IsEmpty() ? NULL : m_dyld_plugin_name.GetCString()));
- return m_dyld_ap.get();
-}
-
-Status ProcessKDP::WillResume() { return Status(); }
-
-Status ProcessKDP::DoResume() {
- Status error;
- Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
- // Only start the async thread if we try to do any process control
- if (!m_async_thread.IsJoinable())
- StartAsyncThread();
-
- bool resume = false;
-
- // With KDP there is only one thread we can tell what to do
- ThreadSP kernel_thread_sp(m_thread_list.FindThreadByProtocolID(g_kernel_tid));
-
- if (kernel_thread_sp) {
- const StateType thread_resume_state =
- kernel_thread_sp->GetTemporaryResumeState();
-
- if (log)
- log->Printf("ProcessKDP::DoResume() thread_resume_state = %s",
- StateAsCString(thread_resume_state));
- switch (thread_resume_state) {
- case eStateSuspended:
- // Nothing to do here when a thread will stay suspended we just leave the
- // CPU mask bit set to zero for the thread
- if (log)
- log->Printf("ProcessKDP::DoResume() = suspended???");
- break;
-
- case eStateStepping: {
- lldb::RegisterContextSP reg_ctx_sp(
- kernel_thread_sp->GetRegisterContext());
-
- if (reg_ctx_sp) {
- if (log)
- log->Printf(
- "ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep (true);");
- reg_ctx_sp->HardwareSingleStep(true);
- resume = true;
- } else {
- error.SetErrorStringWithFormat(
- "KDP thread 0x%llx has no register context",
- kernel_thread_sp->GetID());
- }
- } break;
-
- case eStateRunning: {
- lldb::RegisterContextSP reg_ctx_sp(
- kernel_thread_sp->GetRegisterContext());
-
- if (reg_ctx_sp) {
- if (log)
- log->Printf("ProcessKDP::DoResume () reg_ctx_sp->HardwareSingleStep "
- "(false);");
- reg_ctx_sp->HardwareSingleStep(false);
- resume = true;
- } else {
- error.SetErrorStringWithFormat(
- "KDP thread 0x%llx has no register context",
- kernel_thread_sp->GetID());
- }
- } break;
-
- default:
- // The only valid thread resume states are listed above
- llvm_unreachable("invalid thread resume state");
- }
- }
-
- if (resume) {
- if (log)
- log->Printf("ProcessKDP::DoResume () sending resume");
-
- if (m_comm.SendRequestResume()) {
- m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue);
- SetPrivateState(eStateRunning);
- } else
- error.SetErrorString("KDP resume failed");
- } else {
- error.SetErrorString("kernel thread is suspended");
- }
-
- return error;
-}
-
-lldb::ThreadSP ProcessKDP::GetKernelThread() {
- // KDP only tells us about one thread/core. Any other threads will usually
- // be the ones that are read from memory by the OS plug-ins.
-
- ThreadSP thread_sp(m_kernel_thread_wp.lock());
- if (!thread_sp) {
- thread_sp.reset(new ThreadKDP(*this, g_kernel_tid));
- m_kernel_thread_wp = thread_sp;
- }
- return thread_sp;
-}
-
-bool ProcessKDP::UpdateThreadList(ThreadList &old_thread_list,
- ThreadList &new_thread_list) {
- // locker will keep a mutex locked until it goes out of scope
- Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_THREAD));
- LLDB_LOGV(log, "pid = {0}", GetID());
-
- // Even though there is a CPU mask, it doesn't mean we can see each CPU
- // individually, there is really only one. Lets call this thread 1.
- ThreadSP thread_sp(
- old_thread_list.FindThreadByProtocolID(g_kernel_tid, false));
- if (!thread_sp)
- thread_sp = GetKernelThread();
- new_thread_list.AddThread(thread_sp);
-
- return new_thread_list.GetSize(false) > 0;
-}
-
-void ProcessKDP::RefreshStateAfterStop() {
- // Let all threads recover from stopping and do any clean up based on the
- // previous thread state (if any).
- m_thread_list.RefreshStateAfterStop();
-}
-
-Status ProcessKDP::DoHalt(bool &caused_stop) {
- Status error;
-
- if (m_comm.IsRunning()) {
- if (m_destroy_in_process) {
- // If we are attempting to destroy, we need to not return an error to Halt
- // or DoDestroy won't get called. We are also currently running, so send
- // a process stopped event
- SetPrivateState(eStateStopped);
- } else {
- error.SetErrorString("KDP cannot interrupt a running kernel");
- }
- }
- return error;
-}
-
-Status ProcessKDP::DoDetach(bool keep_stopped) {
- Status error;
- Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
- if (log)
- log->Printf("ProcessKDP::DoDetach(keep_stopped = %i)", keep_stopped);
-
- if (m_comm.IsRunning()) {
- // We are running and we can't interrupt a running kernel, so we need to
- // just close the connection to the kernel and hope for the best
- } else {
- // If we are going to keep the target stopped, then don't send the
- // disconnect message.
- if (!keep_stopped && m_comm.IsConnected()) {
- const bool success = m_comm.SendRequestDisconnect();
- if (log) {
- if (success)
- log->PutCString(
- "ProcessKDP::DoDetach() detach packet sent successfully");
- else
- log->PutCString(
- "ProcessKDP::DoDetach() connection channel shutdown failed");
- }
- m_comm.Disconnect();
- }
- }
- StopAsyncThread();
- m_comm.Clear();
-
- SetPrivateState(eStateDetached);
- ResumePrivateStateThread();
-
- // KillDebugserverProcess ();
- return error;
-}
-
-Status ProcessKDP::DoDestroy() {
- // For KDP there really is no difference between destroy and detach
- bool keep_stopped = false;
- return DoDetach(keep_stopped);
-}
-
-//------------------------------------------------------------------
-// Process Queries
-//------------------------------------------------------------------
-
-bool ProcessKDP::IsAlive() {
- return m_comm.IsConnected() && Process::IsAlive();
-}
-
-//------------------------------------------------------------------
-// Process Memory
-//------------------------------------------------------------------
-size_t ProcessKDP::DoReadMemory(addr_t addr, void *buf, size_t size,
- Status &error) {
- uint8_t *data_buffer = (uint8_t *)buf;
- if (m_comm.IsConnected()) {
- const size_t max_read_size = 512;
- size_t total_bytes_read = 0;
-
- // Read the requested amount of memory in 512 byte chunks
- while (total_bytes_read < size) {
- size_t bytes_to_read_this_request = size - total_bytes_read;
- if (bytes_to_read_this_request > max_read_size) {
- bytes_to_read_this_request = max_read_size;
- }
- size_t bytes_read = m_comm.SendRequestReadMemory(
- addr + total_bytes_read, data_buffer + total_bytes_read,
- bytes_to_read_this_request, error);
- total_bytes_read += bytes_read;
- if (error.Fail() || bytes_read == 0) {
- return total_bytes_read;
- }
- }
-
- return total_bytes_read;
- }
- error.SetErrorString("not connected");
- return 0;
-}
-
-size_t ProcessKDP::DoWriteMemory(addr_t addr, const void *buf, size_t size,
- Status &error) {
- if (m_comm.IsConnected())
- return m_comm.SendRequestWriteMemory(addr, buf, size, error);
- error.SetErrorString("not connected");
- return 0;
-}
-
-lldb::addr_t ProcessKDP::DoAllocateMemory(size_t size, uint32_t permissions,
- Status &error) {
- error.SetErrorString(
- "memory allocation not supported in kdp remote debugging");
- return LLDB_INVALID_ADDRESS;
-}
-
-Status ProcessKDP::DoDeallocateMemory(lldb::addr_t addr) {
- Status error;
- error.SetErrorString(
- "memory deallocation not supported in kdp remote debugging");
- return error;
-}
-
-Status ProcessKDP::EnableBreakpointSite(BreakpointSite *bp_site) {
- if (m_comm.LocalBreakpointsAreSupported()) {
- Status error;
- if (!bp_site->IsEnabled()) {
- if (m_comm.SendRequestBreakpoint(true, bp_site->GetLoadAddress())) {
- bp_site->SetEnabled(true);
- bp_site->SetType(BreakpointSite::eExternal);
- } else {
- error.SetErrorString("KDP set breakpoint failed");
- }
- }
- return error;
- }
- return EnableSoftwareBreakpoint(bp_site);
-}
-
-Status ProcessKDP::DisableBreakpointSite(BreakpointSite *bp_site) {
- if (m_comm.LocalBreakpointsAreSupported()) {
- Status error;
- if (bp_site->IsEnabled()) {
- BreakpointSite::Type bp_type = bp_site->GetType();
- if (bp_type == BreakpointSite::eExternal) {
- if (m_destroy_in_process && m_comm.IsRunning()) {
- // We are trying to destroy our connection and we are running
- bp_site->SetEnabled(false);
- } else {
- if (m_comm.SendRequestBreakpoint(false, bp_site->GetLoadAddress()))
- bp_site->SetEnabled(false);
- else
- error.SetErrorString("KDP remove breakpoint failed");
- }
- } else {
- error = DisableSoftwareBreakpoint(bp_site);
- }
- }
- return error;
- }
- return DisableSoftwareBreakpoint(bp_site);
-}
-
-Status ProcessKDP::EnableWatchpoint(Watchpoint *wp, bool notify) {
- Status error;
- error.SetErrorString(
- "watchpoints are not supported in kdp remote debugging");
- return error;
-}
-
-Status ProcessKDP::DisableWatchpoint(Watchpoint *wp, bool notify) {
- Status error;
- error.SetErrorString(
- "watchpoints are not supported in kdp remote debugging");
- return error;
-}
-
-void ProcessKDP::Clear() { m_thread_list.Clear(); }
-
-Status ProcessKDP::DoSignal(int signo) {
- Status error;
- error.SetErrorString(
- "sending signals is not supported in kdp remote debugging");
- return error;
-}
-
-void ProcessKDP::Initialize() {
- static llvm::once_flag g_once_flag;
-
- llvm::call_once(g_once_flag, []() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(), CreateInstance,
- DebuggerInitialize);
-
- ProcessKDPLog::Initialize();
- });
-}
-
-void ProcessKDP::DebuggerInitialize(lldb_private::Debugger &debugger) {
- if (!PluginManager::GetSettingForProcessPlugin(
- debugger, PluginProperties::GetSettingName())) {
- const bool is_global_setting = true;
- PluginManager::CreateSettingForProcessPlugin(
- debugger, GetGlobalPluginProperties()->GetValueProperties(),
- ConstString("Properties for the kdp-remote process plug-in."),
- is_global_setting);
- }
-}
-
-bool ProcessKDP::StartAsyncThread() {
- Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
-
- if (log)
- log->Printf("ProcessKDP::StartAsyncThread ()");
-
- if (m_async_thread.IsJoinable())
- return true;
-
- m_async_thread = ThreadLauncher::LaunchThread(
- "<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL);
- return m_async_thread.IsJoinable();
-}
-
-void ProcessKDP::StopAsyncThread() {
- Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
-
- if (log)
- log->Printf("ProcessKDP::StopAsyncThread ()");
-
- m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit);
-
- // Stop the stdio thread
- if (m_async_thread.IsJoinable())
- m_async_thread.Join(nullptr);
-}
-
-void *ProcessKDP::AsyncThread(void *arg) {
- ProcessKDP *process = (ProcessKDP *)arg;
-
- const lldb::pid_t pid = process->GetID();
-
- Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
- if (log)
- log->Printf("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64
- ") thread starting...",
- arg, pid);
-
- ListenerSP listener_sp(Listener::MakeListener("ProcessKDP::AsyncThread"));
- EventSP event_sp;
- const uint32_t desired_event_mask =
- eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit;
-
- if (listener_sp->StartListeningForEvents(&process->m_async_broadcaster,
- desired_event_mask) ==
- desired_event_mask) {
- bool done = false;
- while (!done) {
- if (log)
- log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
- ") listener.WaitForEvent (NULL, event_sp)...",
- pid);
- if (listener_sp->GetEvent(event_sp, llvm::None)) {
- uint32_t event_type = event_sp->GetType();
- if (log)
- log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
- ") Got an event of type: %d...",
- pid, event_type);
-
- // When we are running, poll for 1 second to try and get an exception
- // to indicate the process has stopped. If we don't get one, check to
- // make sure no one asked us to exit
- bool is_running = false;
- DataExtractor exc_reply_packet;
- do {
- switch (event_type) {
- case eBroadcastBitAsyncContinue: {
- is_running = true;
- if (process->m_comm.WaitForPacketWithTimeoutMicroSeconds(
- exc_reply_packet, 1 * USEC_PER_SEC)) {
- ThreadSP thread_sp(process->GetKernelThread());
- if (thread_sp) {
- lldb::RegisterContextSP reg_ctx_sp(
- thread_sp->GetRegisterContext());
- if (reg_ctx_sp)
- reg_ctx_sp->InvalidateAllRegisters();
- static_cast<ThreadKDP *>(thread_sp.get())
- ->SetStopInfoFrom_KDP_EXCEPTION(exc_reply_packet);
- }
-
- // TODO: parse the stop reply packet
- is_running = false;
- process->SetPrivateState(eStateStopped);
- } else {
- // Check to see if we are supposed to exit. There is no way to
- // interrupt a running kernel, so all we can do is wait for an
- // exception or detach...
- if (listener_sp->GetEvent(event_sp,
- std::chrono::microseconds(0))) {
- // We got an event, go through the loop again
- event_type = event_sp->GetType();
- }
- }
- } break;
-
- case eBroadcastBitAsyncThreadShouldExit:
- if (log)
- log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
- ") got eBroadcastBitAsyncThreadShouldExit...",
- pid);
- done = true;
- is_running = false;
- break;
-
- default:
- if (log)
- log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
- ") got unknown event 0x%8.8x",
- pid, event_type);
- done = true;
- is_running = false;
- break;
- }
- } while (is_running);
- } else {
- if (log)
- log->Printf("ProcessKDP::AsyncThread (pid = %" PRIu64
- ") listener.WaitForEvent (NULL, event_sp) => false",
- pid);
- done = true;
- }
- }
- }
-
- if (log)
- log->Printf("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64
- ") thread exiting...",
- arg, pid);
-
- process->m_async_thread.Reset();
- return NULL;
-}
-
-class CommandObjectProcessKDPPacketSend : public CommandObjectParsed {
-private:
- OptionGroupOptions m_option_group;
- OptionGroupUInt64 m_command_byte;
- OptionGroupString m_packet_data;
-
- virtual Options *GetOptions() { return &m_option_group; }
-
-public:
- CommandObjectProcessKDPPacketSend(CommandInterpreter &interpreter)
- : CommandObjectParsed(interpreter, "process plugin packet send",
- "Send a custom packet through the KDP protocol by "
- "specifying the command byte and the packet "
- "payload data. A packet will be sent with a "
- "correct header and payload, and the raw result "
- "bytes will be displayed as a string value. ",
- NULL),
- m_option_group(),
- m_command_byte(LLDB_OPT_SET_1, true, "command", 'c', 0, eArgTypeNone,
- "Specify the command byte to use when sending the KDP "
- "request packet.",
- 0),
- m_packet_data(LLDB_OPT_SET_1, false, "payload", 'p', 0, eArgTypeNone,
- "Specify packet payload bytes as a hex ASCII string with "
- "no spaces or hex prefixes.",
- NULL) {
- m_option_group.Append(&m_command_byte, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Append(&m_packet_data, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
- m_option_group.Finalize();
- }
-
- ~CommandObjectProcessKDPPacketSend() {}
-
- bool DoExecute(Args &command, CommandReturnObject &result) {
- const size_t argc = command.GetArgumentCount();
- if (argc == 0) {
- if (!m_command_byte.GetOptionValue().OptionWasSet()) {
- result.AppendError(
- "the --command option must be set to a valid command byte");
- result.SetStatus(eReturnStatusFailed);
- } else {
- const uint64_t command_byte =
- m_command_byte.GetOptionValue().GetUInt64Value(0);
- if (command_byte > 0 && command_byte <= UINT8_MAX) {
- ProcessKDP *process =
- (ProcessKDP *)m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process) {
- const StateType state = process->GetState();
-
- if (StateIsStoppedState(state, true)) {
- std::vector<uint8_t> payload_bytes;
- const char *ascii_hex_bytes_cstr =
- m_packet_data.GetOptionValue().GetCurrentValue();
- if (ascii_hex_bytes_cstr && ascii_hex_bytes_cstr[0]) {
- StringExtractor extractor(ascii_hex_bytes_cstr);
- const size_t ascii_hex_bytes_cstr_len =
- extractor.GetStringRef().size();
- if (ascii_hex_bytes_cstr_len & 1) {
- result.AppendErrorWithFormat("payload data must contain an "
- "even number of ASCII hex "
- "characters: '%s'",
- ascii_hex_bytes_cstr);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- payload_bytes.resize(ascii_hex_bytes_cstr_len / 2);
- if (extractor.GetHexBytes(payload_bytes, '\xdd') !=
- payload_bytes.size()) {
- result.AppendErrorWithFormat("payload data must only contain "
- "ASCII hex characters (no "
- "spaces or hex prefixes): '%s'",
- ascii_hex_bytes_cstr);
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- }
- Status error;
- DataExtractor reply;
- process->GetCommunication().SendRawRequest(
- command_byte,
- payload_bytes.empty() ? NULL : payload_bytes.data(),
- payload_bytes.size(), reply, error);
-
- if (error.Success()) {
- // Copy the binary bytes into a hex ASCII string for the result
- StreamString packet;
- packet.PutBytesAsRawHex8(
- reply.GetDataStart(), reply.GetByteSize(),
- endian::InlHostByteOrder(), endian::InlHostByteOrder());
- result.AppendMessage(packet.GetString());
- result.SetStatus(eReturnStatusSuccessFinishResult);
- return true;
- } else {
- const char *error_cstr = error.AsCString();
- if (error_cstr && error_cstr[0])
- result.AppendError(error_cstr);
- else
- result.AppendErrorWithFormat("unknown error 0x%8.8x",
- error.GetError());
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- } else {
- result.AppendErrorWithFormat("process must be stopped in order "
- "to send KDP packets, state is %s",
- StateAsCString(state));
- result.SetStatus(eReturnStatusFailed);
- }
- } else {
- result.AppendError("invalid process");
- result.SetStatus(eReturnStatusFailed);
- }
- } else {
- result.AppendErrorWithFormat("invalid command byte 0x%" PRIx64
- ", valid values are 1 - 255",
- command_byte);
- result.SetStatus(eReturnStatusFailed);
- }
- }
- } else {
- result.AppendErrorWithFormat("'%s' takes no arguments, only options.",
- m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
- }
- return false;
- }
-};
-
-class CommandObjectProcessKDPPacket : public CommandObjectMultiword {
-private:
-public:
- CommandObjectProcessKDPPacket(CommandInterpreter &interpreter)
- : CommandObjectMultiword(interpreter, "process plugin packet",
- "Commands that deal with KDP remote packets.",
- NULL) {
- LoadSubCommand(
- "send",
- CommandObjectSP(new CommandObjectProcessKDPPacketSend(interpreter)));
- }
-
- ~CommandObjectProcessKDPPacket() {}
-};
-
-class CommandObjectMultiwordProcessKDP : public CommandObjectMultiword {
-public:
- CommandObjectMultiwordProcessKDP(CommandInterpreter &interpreter)
- : CommandObjectMultiword(
- interpreter, "process plugin",
- "Commands for operating on a ProcessKDP process.",
- "process plugin <subcommand> [<subcommand-options>]") {
- LoadSubCommand("packet", CommandObjectSP(new CommandObjectProcessKDPPacket(
- interpreter)));
- }
-
- ~CommandObjectMultiwordProcessKDP() {}
-};
-
-CommandObject *ProcessKDP::GetPluginCommandObject() {
- if (!m_command_sp)
- m_command_sp.reset(new CommandObjectMultiwordProcessKDP(
- GetTarget().GetDebugger().GetCommandInterpreter()));
- return m_command_sp.get();
-}
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
deleted file mode 100644
index f9102442de935..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
+++ /dev/null
@@ -1,220 +0,0 @@
-//===-- ProcessKDP.h --------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ProcessKDP_h_
-#define liblldb_ProcessKDP_h_
-
-
-#include <list>
-#include <vector>
-
-#include "lldb/Core/ThreadSafeValue.h"
-#include "lldb/Host/HostThread.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/Broadcaster.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StreamString.h"
-#include "lldb/Utility/StringList.h"
-
-#include "CommunicationKDP.h"
-
-class ThreadKDP;
-
-class ProcessKDP : public lldb_private::Process {
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- static lldb::ProcessSP
- CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
- const lldb_private::FileSpec *crash_file_path);
-
- static void Initialize();
-
- static void DebuggerInitialize(lldb_private::Debugger &debugger);
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetPluginDescriptionStatic();
-
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- ProcessKDP(lldb::TargetSP target_sp, lldb::ListenerSP listener);
-
- ~ProcessKDP() override;
-
- //------------------------------------------------------------------
- // Check if a given Process
- //------------------------------------------------------------------
- bool CanDebug(lldb::TargetSP target_sp,
- bool plugin_specified_by_name) override;
- lldb_private::CommandObject *GetPluginCommandObject() override;
-
- //------------------------------------------------------------------
- // Creating a new process, or attaching to an existing one
- //------------------------------------------------------------------
- lldb_private::Status WillLaunch(lldb_private::Module *module) override;
-
- lldb_private::Status
- DoLaunch(lldb_private::Module *exe_module,
- lldb_private::ProcessLaunchInfo &launch_info) override;
-
- lldb_private::Status WillAttachToProcessWithID(lldb::pid_t pid) override;
-
- lldb_private::Status
- WillAttachToProcessWithName(const char *process_name,
- bool wait_for_launch) override;
-
- lldb_private::Status DoConnectRemote(lldb_private::Stream *strm,
- llvm::StringRef remote_url) override;
-
- lldb_private::Status DoAttachToProcessWithID(
- lldb::pid_t pid,
- const lldb_private::ProcessAttachInfo &attach_info) override;
-
- lldb_private::Status DoAttachToProcessWithName(
- const char *process_name,
- const lldb_private::ProcessAttachInfo &attach_info) override;
-
- void DidAttach(lldb_private::ArchSpec &process_arch) override;
-
- lldb::addr_t GetImageInfoAddress() override;
-
- lldb_private::DynamicLoader *GetDynamicLoader() override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override;
-
- //------------------------------------------------------------------
- // Process Control
- //------------------------------------------------------------------
- lldb_private::Status WillResume() override;
-
- lldb_private::Status DoResume() override;
-
- lldb_private::Status DoHalt(bool &caused_stop) override;
-
- lldb_private::Status DoDetach(bool keep_stopped) override;
-
- lldb_private::Status DoSignal(int signal) override;
-
- lldb_private::Status DoDestroy() override;
-
- void RefreshStateAfterStop() override;
-
- //------------------------------------------------------------------
- // Process Queries
- //------------------------------------------------------------------
- bool IsAlive() override;
-
- //------------------------------------------------------------------
- // Process Memory
- //------------------------------------------------------------------
- size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
- lldb_private::Status &error) override;
-
- size_t DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size,
- lldb_private::Status &error) override;
-
- lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
- lldb_private::Status &error) override;
-
- lldb_private::Status DoDeallocateMemory(lldb::addr_t ptr) override;
-
- //----------------------------------------------------------------------
- // Process Breakpoints
- //----------------------------------------------------------------------
- lldb_private::Status
- EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
-
- lldb_private::Status
- DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
-
- //----------------------------------------------------------------------
- // Process Watchpoints
- //----------------------------------------------------------------------
- lldb_private::Status EnableWatchpoint(lldb_private::Watchpoint *wp,
- bool notify = true) override;
-
- lldb_private::Status DisableWatchpoint(lldb_private::Watchpoint *wp,
- bool notify = true) override;
-
- CommunicationKDP &GetCommunication() { return m_comm; }
-
-protected:
- friend class ThreadKDP;
- friend class CommunicationKDP;
-
- //----------------------------------------------------------------------
- // Accessors
- //----------------------------------------------------------------------
- bool IsRunning(lldb::StateType state) {
- return state == lldb::eStateRunning || IsStepping(state);
- }
-
- bool IsStepping(lldb::StateType state) {
- return state == lldb::eStateStepping;
- }
-
- bool CanResume(lldb::StateType state) { return state == lldb::eStateStopped; }
-
- bool HasExited(lldb::StateType state) { return state == lldb::eStateExited; }
-
- bool GetHostArchitecture(lldb_private::ArchSpec &arch);
-
- bool ProcessIDIsValid() const;
-
- void Clear();
-
- bool UpdateThreadList(lldb_private::ThreadList &old_thread_list,
- lldb_private::ThreadList &new_thread_list) override;
-
- enum {
- eBroadcastBitAsyncContinue = (1 << 0),
- eBroadcastBitAsyncThreadShouldExit = (1 << 1)
- };
-
- lldb::ThreadSP GetKernelThread();
-
- //------------------------------------------------------------------
- /// Broadcaster event bits definitions.
- //------------------------------------------------------------------
- CommunicationKDP m_comm;
- lldb_private::Broadcaster m_async_broadcaster;
- lldb_private::HostThread m_async_thread;
- lldb_private::ConstString m_dyld_plugin_name;
- lldb::addr_t m_kernel_load_addr;
- lldb::CommandObjectSP m_command_sp;
- lldb::ThreadWP m_kernel_thread_wp;
-
- bool StartAsyncThread();
-
- void StopAsyncThread();
-
- static void *AsyncThread(void *arg);
-
-private:
- //------------------------------------------------------------------
- // For ProcessKDP only
- //------------------------------------------------------------------
-
- DISALLOW_COPY_AND_ASSIGN(ProcessKDP);
-};
-
-#endif // liblldb_ProcessKDP_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp b/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp
deleted file mode 100644
index ffab3e5e23c77..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-//===-- ProcessKDPLog.cpp ---------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ProcessKDPLog.h"
-
-using namespace lldb_private;
-
-static constexpr Log::Category g_categories[] = {
- {{"async"}, {"log asynchronous activity"}, KDP_LOG_ASYNC},
- {{"break"}, {"log breakpoints"}, KDP_LOG_BREAKPOINTS},
- {{"comm"}, {"log communication activity"}, KDP_LOG_COMM},
- {{"data-long"},
- {"log memory bytes for memory reads and writes for all transactions"},
- KDP_LOG_MEMORY_DATA_LONG},
- {{"data-short"},
- {"log memory bytes for memory reads and writes for short transactions "
- "only"},
- KDP_LOG_MEMORY_DATA_SHORT},
- {{"memory"}, {"log memory reads and writes"}, KDP_LOG_MEMORY},
- {{"packets"}, {"log gdb remote packets"}, KDP_LOG_PACKETS},
- {{"process"}, {"log process events and activities"}, KDP_LOG_PROCESS},
- {{"step"}, {"log step related activities"}, KDP_LOG_STEP},
- {{"thread"}, {"log thread events and activities"}, KDP_LOG_THREAD},
- {{"watch"}, {"log watchpoint related activities"}, KDP_LOG_WATCHPOINTS},
-};
-
-Log::Channel ProcessKDPLog::g_channel(g_categories, KDP_LOG_DEFAULT);
-
-void ProcessKDPLog::Initialize() { Log::Register("kdp-remote", g_channel); }
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h b/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h
deleted file mode 100644
index 908754ec992b1..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===-- ProcessKDPLog.h -----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ProcessKDPLog_h_
-#define liblldb_ProcessKDPLog_h_
-
-#include "lldb/Utility/Log.h"
-
-#define KDP_LOG_PROCESS (1u << 1)
-#define KDP_LOG_THREAD (1u << 2)
-#define KDP_LOG_PACKETS (1u << 3)
-#define KDP_LOG_MEMORY (1u << 4) // Log memory reads/writes calls
-#define KDP_LOG_MEMORY_DATA_SHORT \
- (1u << 5) // Log short memory reads/writes bytes
-#define KDP_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes
-#define KDP_LOG_BREAKPOINTS (1u << 7)
-#define KDP_LOG_WATCHPOINTS (1u << 8)
-#define KDP_LOG_STEP (1u << 9)
-#define KDP_LOG_COMM (1u << 10)
-#define KDP_LOG_ASYNC (1u << 11)
-#define KDP_LOG_ALL (UINT32_MAX)
-#define KDP_LOG_DEFAULT KDP_LOG_PACKETS
-
-namespace lldb_private {
-class ProcessKDPLog {
- static Log::Channel g_channel;
-
-public:
- static void Initialize();
-
- static Log *GetLogIfAllCategoriesSet(uint32_t mask) {
- return g_channel.GetLogIfAll(mask);
- }
-};
-}
-
-#endif // liblldb_ProcessKDPLog_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
deleted file mode 100644
index 0f9e62ce355a0..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-//===-- RegisterContextKDP_arm.cpp ------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "RegisterContextKDP_arm.h"
-
-#include "ProcessKDP.h"
-#include "ThreadKDP.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-RegisterContextKDP_arm::RegisterContextKDP_arm(ThreadKDP &thread,
- uint32_t concrete_frame_idx)
- : RegisterContextDarwin_arm(thread, concrete_frame_idx),
- m_kdp_thread(thread) {}
-
-RegisterContextKDP_arm::~RegisterContextKDP_arm() {}
-
-int RegisterContextKDP_arm::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm::DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm::DoWriteGPR(lldb::tid_t tid, int flavor,
- const GPR &gpr) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm::DoWriteFPU(lldb::tid_t tid, int flavor,
- const FPU &fpu) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm::DoWriteEXC(lldb::tid_t tid, int flavor,
- const EXC &exc) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm::DoWriteDBG(lldb::tid_t tid, int flavor,
- const DBG &dbg) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h
deleted file mode 100644
index 1532f23207f42..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//===-- RegisterContextKDP_arm.h --------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextKDP_arm_h_
-#define liblldb_RegisterContextKDP_arm_h_
-
-
-#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
-
-class ThreadKDP;
-
-class RegisterContextKDP_arm : public RegisterContextDarwin_arm {
-public:
- RegisterContextKDP_arm(ThreadKDP &thread, uint32_t concrete_frame_idx);
-
- virtual ~RegisterContextKDP_arm();
-
-protected:
- virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
-
- int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
-
- int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
-
- int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg);
-
- int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
-
- int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
-
- int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
-
- int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg);
-
- ThreadKDP &m_kdp_thread;
-};
-
-#endif // liblldb_RegisterContextKDP_arm_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp
deleted file mode 100644
index e13a7f3ad9079..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-//===-- RegisterContextKDP_arm64.cpp ------------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "RegisterContextKDP_arm64.h"
-
-#include "ProcessKDP.h"
-#include "ThreadKDP.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-RegisterContextKDP_arm64::RegisterContextKDP_arm64(ThreadKDP &thread,
- uint32_t concrete_frame_idx)
- : RegisterContextDarwin_arm64(thread, concrete_frame_idx),
- m_kdp_thread(thread) {}
-
-RegisterContextKDP_arm64::~RegisterContextKDP_arm64() {}
-
-int RegisterContextKDP_arm64::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm64::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm64::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm64::DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm64::DoWriteGPR(lldb::tid_t tid, int flavor,
- const GPR &gpr) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm64::DoWriteFPU(lldb::tid_t tid, int flavor,
- const FPU &fpu) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm64::DoWriteEXC(lldb::tid_t tid, int flavor,
- const EXC &exc) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_arm64::DoWriteDBG(lldb::tid_t tid, int flavor,
- const DBG &dbg) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, DBGRegSet, &dbg, sizeof(dbg),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h
deleted file mode 100644
index be4038ba96eaf..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm64.h
+++ /dev/null
@@ -1,45 +0,0 @@
-//===-- RegisterContextKDP_arm64.h --------------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextKDP_arm64_h_
-#define liblldb_RegisterContextKDP_arm64_h_
-
-
-#include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"
-
-class ThreadKDP;
-
-class RegisterContextKDP_arm64 : public RegisterContextDarwin_arm64 {
-public:
- RegisterContextKDP_arm64(ThreadKDP &thread, uint32_t concrete_frame_idx);
-
- virtual ~RegisterContextKDP_arm64();
-
-protected:
- virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
-
- int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
-
- int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
-
- int DoReadDBG(lldb::tid_t tid, int flavor, DBG &dbg);
-
- int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
-
- int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
-
- int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
-
- int DoWriteDBG(lldb::tid_t tid, int flavor, const DBG &dbg);
-
- ThreadKDP &m_kdp_thread;
-};
-
-#endif // liblldb_RegisterContextKDP_arm64_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
deleted file mode 100644
index 096aa0f95d009..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-//===-- RegisterContextKDP_i386.cpp -----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "RegisterContextKDP_i386.h"
-#include "ProcessKDP.h"
-#include "ThreadKDP.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-RegisterContextKDP_i386::RegisterContextKDP_i386(ThreadKDP &thread,
- uint32_t concrete_frame_idx)
- : RegisterContextDarwin_i386(thread, concrete_frame_idx),
- m_kdp_thread(thread) {}
-
-RegisterContextKDP_i386::~RegisterContextKDP_i386() {}
-
-int RegisterContextKDP_i386::DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_i386::DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_i386::DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_i386::DoWriteGPR(lldb::tid_t tid, int flavor,
- const GPR &gpr) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_i386::DoWriteFPU(lldb::tid_t tid, int flavor,
- const FPU &fpu) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_i386::DoWriteEXC(lldb::tid_t tid, int flavor,
- const EXC &exc) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h
deleted file mode 100644
index 699d5fabe1570..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//===-- RegisterContextKDP_i386.h -------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextKDP_i386_h_
-#define liblldb_RegisterContextKDP_i386_h_
-
-#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
-
-class ThreadKDP;
-
-class RegisterContextKDP_i386 : public RegisterContextDarwin_i386 {
-public:
- RegisterContextKDP_i386(ThreadKDP &thread, uint32_t concrete_frame_idx);
-
- virtual ~RegisterContextKDP_i386();
-
-protected:
- virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
-
- int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
-
- int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
-
- int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
-
- int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
-
- int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
-
- ThreadKDP &m_kdp_thread;
-};
-
-#endif // liblldb_RegisterContextKDP_i386_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp
deleted file mode 100644
index 9d85145f2eaf2..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-//===-- RegisterContextKDP_x86_64.cpp ---------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "RegisterContextKDP_x86_64.h"
-#include "ProcessKDP.h"
-#include "ThreadKDP.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-RegisterContextKDP_x86_64::RegisterContextKDP_x86_64(
- ThreadKDP &thread, uint32_t concrete_frame_idx)
- : RegisterContextDarwin_x86_64(thread, concrete_frame_idx),
- m_kdp_thread(thread) {}
-
-RegisterContextKDP_x86_64::~RegisterContextKDP_x86_64() {}
-
-int RegisterContextKDP_x86_64::DoReadGPR(lldb::tid_t tid, int flavor,
- GPR &gpr) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_x86_64::DoReadFPU(lldb::tid_t tid, int flavor,
- FPU &fpu) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_x86_64::DoReadEXC(lldb::tid_t tid, int flavor,
- EXC &exc) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestReadRegisters(tid, EXCRegSet, &exc, sizeof(exc),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_x86_64::DoWriteGPR(lldb::tid_t tid, int flavor,
- const GPR &gpr) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, GPRRegSet, &gpr, sizeof(gpr),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_x86_64::DoWriteFPU(lldb::tid_t tid, int flavor,
- const FPU &fpu) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, FPURegSet, &fpu, sizeof(fpu),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
-
-int RegisterContextKDP_x86_64::DoWriteEXC(lldb::tid_t tid, int flavor,
- const EXC &exc) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- Status error;
- if (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .SendRequestWriteRegisters(tid, EXCRegSet, &exc, sizeof(exc),
- error)) {
- if (error.Success())
- return 0;
- }
- }
- return -1;
-}
diff --git a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h b/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h
deleted file mode 100644
index 9841ad77b0044..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h
+++ /dev/null
@@ -1,39 +0,0 @@
-//===-- RegisterContextKDP_x86_64.h -----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextKDP_x86_64_h_
-#define liblldb_RegisterContextKDP_x86_64_h_
-
-#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
-
-class ThreadKDP;
-
-class RegisterContextKDP_x86_64 : public RegisterContextDarwin_x86_64 {
-public:
- RegisterContextKDP_x86_64(ThreadKDP &thread, uint32_t concrete_frame_idx);
-
- virtual ~RegisterContextKDP_x86_64();
-
-protected:
- virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr);
-
- int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu);
-
- int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc);
-
- int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr);
-
- int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu);
-
- int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc);
-
- ThreadKDP &m_kdp_thread;
-};
-
-#endif // liblldb_RegisterContextKDP_x86_64_h_
diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
deleted file mode 100644
index 6f26acd0b8aa7..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-//===-- ThreadKDP.cpp -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ThreadKDP.h"
-
-#include "lldb/Host/SafeMachO.h"
-
-#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/StopInfo.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Unwind.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/DataExtractor.h"
-#include "lldb/Utility/State.h"
-#include "lldb/Utility/StreamString.h"
-
-#include "Plugins/Process/Utility/StopInfoMachException.h"
-#include "ProcessKDP.h"
-#include "ProcessKDPLog.h"
-#include "RegisterContextKDP_arm.h"
-#include "RegisterContextKDP_arm64.h"
-#include "RegisterContextKDP_i386.h"
-#include "RegisterContextKDP_x86_64.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-//----------------------------------------------------------------------
-// Thread Registers
-//----------------------------------------------------------------------
-
-ThreadKDP::ThreadKDP(Process &process, lldb::tid_t tid)
- : Thread(process, tid), m_thread_name(), m_dispatch_queue_name(),
- m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS) {
- Log *log = ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_THREAD);
- LLDB_LOG(log, "this = {0}, tid = {1:x}", this, GetID());
-}
-
-ThreadKDP::~ThreadKDP() {
- Log *log = ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_THREAD);
- LLDB_LOG(log, "this = {0}, tid = {1:x}", this, GetID());
- DestroyThread();
-}
-
-const char *ThreadKDP::GetName() {
- if (m_thread_name.empty())
- return nullptr;
- return m_thread_name.c_str();
-}
-
-const char *ThreadKDP::GetQueueName() { return nullptr; }
-
-void ThreadKDP::RefreshStateAfterStop() {
- // Invalidate all registers in our register context. We don't set "force" to
- // true because the stop reply packet might have had some register values
- // that were expedited and these will already be copied into the register
- // context by the time this function gets called. The KDPRegisterContext
- // class has been made smart enough to detect when it needs to invalidate
- // which registers are valid by putting hooks in the register read and
- // register supply functions where they check the process stop ID and do the
- // right thing.
- const bool force = false;
- lldb::RegisterContextSP reg_ctx_sp(GetRegisterContext());
- if (reg_ctx_sp)
- reg_ctx_sp->InvalidateIfNeeded(force);
-}
-
-bool ThreadKDP::ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
-
-void ThreadKDP::Dump(Log *log, uint32_t index) {}
-
-bool ThreadKDP::ShouldStop(bool &step_more) { return true; }
-lldb::RegisterContextSP ThreadKDP::GetRegisterContext() {
- if (!m_reg_context_sp)
- m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
- return m_reg_context_sp;
-}
-
-lldb::RegisterContextSP
-ThreadKDP::CreateRegisterContextForFrame(StackFrame *frame) {
- lldb::RegisterContextSP reg_ctx_sp;
- uint32_t concrete_frame_idx = 0;
-
- if (frame)
- concrete_frame_idx = frame->GetConcreteFrameIndex();
-
- if (concrete_frame_idx == 0) {
- ProcessSP process_sp(CalculateProcess());
- if (process_sp) {
- switch (static_cast<ProcessKDP *>(process_sp.get())
- ->GetCommunication()
- .GetCPUType()) {
- case llvm::MachO::CPU_TYPE_ARM:
- reg_ctx_sp.reset(new RegisterContextKDP_arm(*this, concrete_frame_idx));
- break;
- case llvm::MachO::CPU_TYPE_ARM64:
- reg_ctx_sp.reset(
- new RegisterContextKDP_arm64(*this, concrete_frame_idx));
- break;
- case llvm::MachO::CPU_TYPE_I386:
- reg_ctx_sp.reset(
- new RegisterContextKDP_i386(*this, concrete_frame_idx));
- break;
- case llvm::MachO::CPU_TYPE_X86_64:
- reg_ctx_sp.reset(
- new RegisterContextKDP_x86_64(*this, concrete_frame_idx));
- break;
- default:
- llvm_unreachable("Add CPU type support in KDP");
- }
- }
- } else {
- Unwind *unwinder = GetUnwinder();
- if (unwinder != nullptr)
- reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
- }
- return reg_ctx_sp;
-}
-
-bool ThreadKDP::CalculateStopInfo() {
- ProcessSP process_sp(GetProcess());
- if (process_sp) {
- if (m_cached_stop_info_sp) {
- SetStopInfo(m_cached_stop_info_sp);
- } else {
- SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, SIGSTOP));
- }
- return true;
- }
- return false;
-}
-
-void ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION(
- const DataExtractor &exc_reply_packet) {
- lldb::offset_t offset = 0;
- uint8_t reply_command = exc_reply_packet.GetU8(&offset);
- if (reply_command == CommunicationKDP::KDP_EXCEPTION) {
- offset = 8;
- const uint32_t count = exc_reply_packet.GetU32(&offset);
- if (count >= 1) {
- // const uint32_t cpu = exc_reply_packet.GetU32 (&offset);
- offset += 4; // Skip the useless CPU field
- const uint32_t exc_type = exc_reply_packet.GetU32(&offset);
- const uint32_t exc_code = exc_reply_packet.GetU32(&offset);
- const uint32_t exc_subcode = exc_reply_packet.GetU32(&offset);
- // We have to make a copy of the stop info because the thread list will
- // iterate through the threads and clear all stop infos..
-
- // Let the StopInfoMachException::CreateStopReasonWithMachException()
- // function update the PC if needed as we might hit a software breakpoint
- // and need to decrement the PC (i386 and x86_64 need this) and KDP
- // doesn't do this for us.
- const bool pc_already_adjusted = false;
- const bool adjust_pc_if_needed = true;
-
- m_cached_stop_info_sp =
- StopInfoMachException::CreateStopReasonWithMachException(
- *this, exc_type, 2, exc_code, exc_subcode, 0, pc_already_adjusted,
- adjust_pc_if_needed);
- }
- }
-}
diff --git a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h b/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h
deleted file mode 100644
index ea517b4254fc9..0000000000000
--- a/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h
+++ /dev/null
@@ -1,77 +0,0 @@
-//===-- ThreadKDP.h ---------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ThreadKDP_h_
-#define liblldb_ThreadKDP_h_
-
-#include <string>
-
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Thread.h"
-
-class ProcessKDP;
-
-class ThreadKDP : public lldb_private::Thread {
-public:
- ThreadKDP(lldb_private::Process &process, lldb::tid_t tid);
-
- virtual ~ThreadKDP();
-
- virtual void RefreshStateAfterStop();
-
- virtual const char *GetName();
-
- virtual const char *GetQueueName();
-
- virtual lldb::RegisterContextSP GetRegisterContext();
-
- virtual lldb::RegisterContextSP
- CreateRegisterContextForFrame(lldb_private::StackFrame *frame);
-
- void Dump(lldb_private::Log *log, uint32_t index);
-
- static bool ThreadIDIsValid(lldb::tid_t thread);
-
- bool ShouldStop(bool &step_more);
-
- const char *GetBasicInfoAsString();
-
- void SetName(const char *name) {
- if (name && name[0])
- m_thread_name.assign(name);
- else
- m_thread_name.clear();
- }
-
- lldb::addr_t GetThreadDispatchQAddr() { return m_thread_dispatch_qaddr; }
-
- void SetThreadDispatchQAddr(lldb::addr_t thread_dispatch_qaddr) {
- m_thread_dispatch_qaddr = thread_dispatch_qaddr;
- }
-
- void SetStopInfoFrom_KDP_EXCEPTION(
- const lldb_private::DataExtractor &exc_reply_packet);
-
-protected:
- friend class ProcessKDP;
-
- //------------------------------------------------------------------
- // Member variables.
- //------------------------------------------------------------------
- std::string m_thread_name;
- std::string m_dispatch_queue_name;
- lldb::addr_t m_thread_dispatch_qaddr;
- lldb::StopInfoSP m_cached_stop_info_sp;
- //------------------------------------------------------------------
- // Protected member functions.
- //------------------------------------------------------------------
- virtual bool CalculateStopInfo();
-};
-
-#endif // liblldb_ThreadKDP_h_
diff --git a/source/Plugins/Process/NetBSD/CMakeLists.txt b/source/Plugins/Process/NetBSD/CMakeLists.txt
deleted file mode 100644
index e131e6d70468b..0000000000000
--- a/source/Plugins/Process/NetBSD/CMakeLists.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-add_lldb_library(lldbPluginProcessNetBSD PLUGIN
- NativeProcessNetBSD.cpp
- NativeRegisterContextNetBSD.cpp
- NativeRegisterContextNetBSD_x86_64.cpp
- NativeThreadNetBSD.cpp
-
- LINK_LIBS
- lldbHost
- lldbSymbol
- lldbTarget
- lldbUtility
- lldbPluginProcessPOSIX
- lldbPluginProcessUtility
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Process/POSIX/CMakeLists.txt b/source/Plugins/Process/POSIX/CMakeLists.txt
deleted file mode 100644
index f058e01c74394..0000000000000
--- a/source/Plugins/Process/POSIX/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_lldb_library(lldbPluginProcessPOSIX PLUGIN
- CrashReason.cpp
- ProcessMessage.cpp
- ProcessPOSIXLog.cpp
-
- LINK_LIBS
- lldbInterpreter
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Process/Utility/CMakeLists.txt b/source/Plugins/Process/Utility/CMakeLists.txt
deleted file mode 100644
index e36ce4dec98a8..0000000000000
--- a/source/Plugins/Process/Utility/CMakeLists.txt
+++ /dev/null
@@ -1,64 +0,0 @@
-add_lldb_library(lldbPluginProcessUtility PLUGIN
- DynamicRegisterInfo.cpp
- FreeBSDSignals.cpp
- GDBRemoteSignals.cpp
- HistoryThread.cpp
- HistoryUnwind.cpp
- InferiorCallPOSIX.cpp
- LinuxProcMaps.cpp
- LinuxSignals.cpp
- MipsLinuxSignals.cpp
- NativeRegisterContextRegisterInfo.cpp
- NetBSDSignals.cpp
- RegisterContextDarwin_arm.cpp
- RegisterContextDarwin_arm64.cpp
- RegisterContextDarwin_i386.cpp
- RegisterContextDarwin_x86_64.cpp
- RegisterContextDummy.cpp
- RegisterContextFreeBSD_i386.cpp
- RegisterContextFreeBSD_mips64.cpp
- RegisterContextFreeBSD_powerpc.cpp
- RegisterContextFreeBSD_x86_64.cpp
- RegisterContextHistory.cpp
- RegisterContextLinux_i386.cpp
- RegisterContextLinux_x86_64.cpp
- RegisterContextLinux_mips64.cpp
- RegisterContextLinux_mips.cpp
- RegisterContextLinux_s390x.cpp
- RegisterContextLLDB.cpp
- RegisterContextMacOSXFrameBackchain.cpp
- RegisterContextMach_arm.cpp
- RegisterContextMach_i386.cpp
- RegisterContextMach_x86_64.cpp
- RegisterContextMemory.cpp
- RegisterContextNetBSD_x86_64.cpp
- RegisterContextOpenBSD_i386.cpp
- RegisterContextOpenBSD_x86_64.cpp
- RegisterContextPOSIX_arm.cpp
- RegisterContextPOSIX_arm64.cpp
- RegisterContextPOSIX_mips64.cpp
- RegisterContextPOSIX_powerpc.cpp
- RegisterContextPOSIX_ppc64le.cpp
- RegisterContextPOSIX_s390x.cpp
- RegisterContextPOSIX_x86.cpp
- RegisterContextThreadMemory.cpp
- RegisterInfoPOSIX_arm.cpp
- RegisterInfoPOSIX_arm64.cpp
- RegisterInfoPOSIX_ppc64le.cpp
- StopInfoMachException.cpp
- ThreadMemory.cpp
- UnwindLLDB.cpp
- UnwindMacOSXFrameBackchain.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbDataFormatters
- lldbExpression
- lldbHost
- lldbSymbol
- lldbTarget
- lldbUtility
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Process/Windows/Common/CMakeLists.txt b/source/Plugins/Process/Windows/Common/CMakeLists.txt
deleted file mode 100644
index 0926290861833..0000000000000
--- a/source/Plugins/Process/Windows/Common/CMakeLists.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-set(PROC_WINDOWS_COMMON_SOURCES
- DebuggerThread.cpp
- LocalDebugDelegate.cpp
- ProcessWindows.cpp
- ProcessWindowsLog.cpp
- RegisterContextWindows.cpp
- TargetThreadWindows.cpp
- )
-
-if (CMAKE_SIZEOF_VOID_P EQUAL 4)
- set(PROC_WINDOWS_COMMON_SOURCES ${PROC_WINDOWS_COMMON_SOURCES}
- x86/RegisterContextWindows_x86.cpp
- )
-elseif (CMAKE_SIZEOF_VOID_P EQUAL 8)
- set(PROC_WINDOWS_COMMON_SOURCES ${PROC_WINDOWS_COMMON_SOURCES}
- x64/RegisterContextWindows_x64.cpp
- )
-endif()
-
-add_lldb_library(lldbPluginProcessWindowsCommon PLUGIN
- ${PROC_WINDOWS_COMMON_SOURCES}
-
- LINK_LIBS
- lldbCore
- lldbHost
- lldbInterpreter
- lldbSymbol
- lldbTarget
- ws2_32
- rpcrt4
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Process/Windows/Common/DebuggerThread.cpp b/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
deleted file mode 100644
index 81ec25871c577..0000000000000
--- a/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
+++ /dev/null
@@ -1,520 +0,0 @@
-//===-- DebuggerThread.cpp --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DebuggerThread.h"
-#include "ExceptionRecord.h"
-#include "IDebugDelegate.h"
-
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Host/windows/HostProcessWindows.h"
-#include "lldb/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/ProcessLauncherWindows.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/ProcessLaunchInfo.h"
-#include "lldb/Utility/FileSpec.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Predicate.h"
-#include "lldb/Utility/Status.h"
-
-#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/Threading.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-struct DebugLaunchContext {
- DebugLaunchContext(DebuggerThread *thread,
- const ProcessLaunchInfo &launch_info)
- : m_thread(thread), m_launch_info(launch_info) {}
- DebuggerThread *m_thread;
- ProcessLaunchInfo m_launch_info;
-};
-
-struct DebugAttachContext {
- DebugAttachContext(DebuggerThread *thread, lldb::pid_t pid,
- const ProcessAttachInfo &attach_info)
- : m_thread(thread), m_pid(pid), m_attach_info(attach_info) {}
- DebuggerThread *m_thread;
- lldb::pid_t m_pid;
- ProcessAttachInfo m_attach_info;
-};
-} // namespace
-
-DebuggerThread::DebuggerThread(DebugDelegateSP debug_delegate)
- : m_debug_delegate(debug_delegate), m_pid_to_detach(0),
- m_is_shutting_down(false) {
- m_debugging_ended_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
-}
-
-DebuggerThread::~DebuggerThread() { ::CloseHandle(m_debugging_ended_event); }
-
-Status DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- LLDB_LOG(log, "launching '{0}'", launch_info.GetExecutableFile().GetPath());
-
- Status error;
- DebugLaunchContext *context = new DebugLaunchContext(this, launch_info);
- HostThread slave_thread(ThreadLauncher::LaunchThread(
- "lldb.plugin.process-windows.slave[?]", DebuggerThreadLaunchRoutine,
- context, &error));
-
- if (!error.Success())
- LLDB_LOG(log, "couldn't launch debugger thread. {0}", error);
-
- return error;
-}
-
-Status DebuggerThread::DebugAttach(lldb::pid_t pid,
- const ProcessAttachInfo &attach_info) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- LLDB_LOG(log, "attaching to '{0}'", pid);
-
- Status error;
- DebugAttachContext *context = new DebugAttachContext(this, pid, attach_info);
- HostThread slave_thread(ThreadLauncher::LaunchThread(
- "lldb.plugin.process-windows.slave[?]", DebuggerThreadAttachRoutine,
- context, &error));
-
- if (!error.Success())
- LLDB_LOG(log, "couldn't attach to process '{0}'. {1}", pid, error);
-
- return error;
-}
-
-lldb::thread_result_t DebuggerThread::DebuggerThreadLaunchRoutine(void *data) {
- DebugLaunchContext *context = static_cast<DebugLaunchContext *>(data);
- lldb::thread_result_t result =
- context->m_thread->DebuggerThreadLaunchRoutine(context->m_launch_info);
- delete context;
- return result;
-}
-
-lldb::thread_result_t DebuggerThread::DebuggerThreadAttachRoutine(void *data) {
- DebugAttachContext *context = static_cast<DebugAttachContext *>(data);
- lldb::thread_result_t result = context->m_thread->DebuggerThreadAttachRoutine(
- context->m_pid, context->m_attach_info);
- delete context;
- return result;
-}
-
-lldb::thread_result_t DebuggerThread::DebuggerThreadLaunchRoutine(
- const ProcessLaunchInfo &launch_info) {
- // Grab a shared_ptr reference to this so that we know it won't get deleted
- // until after the thread routine has exited.
- std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
-
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- LLDB_LOG(log, "preparing to launch '{0}' on background thread.",
- launch_info.GetExecutableFile().GetPath());
-
- Status error;
- ProcessLauncherWindows launcher;
- HostProcess process(launcher.LaunchProcess(launch_info, error));
- // If we couldn't create the process, notify waiters immediately. Otherwise
- // enter the debug loop and wait until we get the create process debug
- // notification. Note that if the process was created successfully, we can
- // throw away the process handle we got from CreateProcess because Windows
- // will give us another (potentially more useful?) handle when it sends us
- // the CREATE_PROCESS_DEBUG_EVENT.
- if (error.Success())
- DebugLoop();
- else
- m_debug_delegate->OnDebuggerError(error, 0);
-
- return 0;
-}
-
-lldb::thread_result_t DebuggerThread::DebuggerThreadAttachRoutine(
- lldb::pid_t pid, const ProcessAttachInfo &attach_info) {
- // Grab a shared_ptr reference to this so that we know it won't get deleted
- // until after the thread routine has exited.
- std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
-
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- LLDB_LOG(log, "preparing to attach to process '{0}' on background thread.",
- pid);
-
- if (!DebugActiveProcess((DWORD)pid)) {
- Status error(::GetLastError(), eErrorTypeWin32);
- m_debug_delegate->OnDebuggerError(error, 0);
- return 0;
- }
-
- // The attach was successful, enter the debug loop. From here on out, this
- // is no different than a create process operation, so all the same comments
- // in DebugLaunch should apply from this point out.
- DebugLoop();
-
- return 0;
-}
-
-Status DebuggerThread::StopDebugging(bool terminate) {
- Status error;
-
- lldb::pid_t pid = m_process.GetProcessId();
-
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- LLDB_LOG(log, "terminate = {0}, inferior={1}.", terminate, pid);
-
- // Set m_is_shutting_down to true if it was false. Return if it was already
- // true.
- bool expected = false;
- if (!m_is_shutting_down.compare_exchange_strong(expected, true))
- return error;
-
- // Make a copy of the process, since the termination sequence will reset
- // DebuggerThread's internal copy and it needs to remain open for the Wait
- // operation.
- HostProcess process_copy = m_process;
- lldb::process_t handle = m_process.GetNativeProcess().GetSystemHandle();
-
- if (terminate) {
- if (handle != nullptr && handle != LLDB_INVALID_PROCESS) {
- // Initiate the termination before continuing the exception, so that the
- // next debug event we get is the exit process event, and not some other
- // event.
- BOOL terminate_suceeded = TerminateProcess(handle, 0);
- LLDB_LOG(log,
- "calling TerminateProcess({0}, 0) (inferior={1}), success={2}",
- handle, pid, terminate_suceeded);
- } else {
- LLDB_LOG(log,
- "NOT calling TerminateProcess because the inferior is not valid "
- "({0}, 0) (inferior={1})",
- handle, pid);
- }
- }
-
- // If we're stuck waiting for an exception to continue (e.g. the user is at a
- // breakpoint messing around in the debugger), continue it now. But only
- // AFTER calling TerminateProcess to make sure that the very next call to
- // WaitForDebugEvent is an exit process event.
- if (m_active_exception.get()) {
- LLDB_LOG(log, "masking active exception");
- ContinueAsyncException(ExceptionResult::MaskException);
- }
-
- if (!terminate) {
- // Indicate that we want to detach.
- m_pid_to_detach = GetProcess().GetProcessId();
-
- // Force a fresh break so that the detach can happen from the debugger
- // thread.
- if (!::DebugBreakProcess(
- GetProcess().GetNativeProcess().GetSystemHandle())) {
- error.SetError(::GetLastError(), eErrorTypeWin32);
- }
- }
-
- LLDB_LOG(log, "waiting for detach from process {0} to complete.", pid);
-
- DWORD wait_result = WaitForSingleObject(m_debugging_ended_event, 5000);
- if (wait_result != WAIT_OBJECT_0) {
- error.SetError(GetLastError(), eErrorTypeWin32);
- LLDB_LOG(log, "error: WaitForSingleObject({0}, 5000) returned {1}",
- m_debugging_ended_event, wait_result);
- } else
- LLDB_LOG(log, "detach from process {0} completed successfully.", pid);
-
- if (!error.Success()) {
- LLDB_LOG(log, "encountered an error while trying to stop process {0}. {1}",
- pid, error);
- }
- return error;
-}
-
-void DebuggerThread::ContinueAsyncException(ExceptionResult result) {
- if (!m_active_exception.get())
- return;
-
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS |
- WINDOWS_LOG_EXCEPTION);
- LLDB_LOG(log, "broadcasting for inferior process {0}.",
- m_process.GetProcessId());
-
- m_active_exception.reset();
- m_exception_pred.SetValue(result, eBroadcastAlways);
-}
-
-void DebuggerThread::FreeProcessHandles() {
- m_process = HostProcess();
- m_main_thread = HostThread();
- if (m_image_file) {
- ::CloseHandle(m_image_file);
- m_image_file = nullptr;
- }
-}
-
-void DebuggerThread::DebugLoop() {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT);
- DEBUG_EVENT dbe = {};
- bool should_debug = true;
- LLDB_LOGV(log, "Entering WaitForDebugEvent loop");
- while (should_debug) {
- LLDB_LOGV(log, "Calling WaitForDebugEvent");
- BOOL wait_result = WaitForDebugEvent(&dbe, INFINITE);
- if (wait_result) {
- DWORD continue_status = DBG_CONTINUE;
- switch (dbe.dwDebugEventCode) {
- default:
- llvm_unreachable("Unhandle debug event code!");
- case EXCEPTION_DEBUG_EVENT: {
- ExceptionResult status =
- HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId);
-
- if (status == ExceptionResult::MaskException)
- continue_status = DBG_CONTINUE;
- else if (status == ExceptionResult::SendToApplication)
- continue_status = DBG_EXCEPTION_NOT_HANDLED;
-
- break;
- }
- case CREATE_THREAD_DEBUG_EVENT:
- continue_status =
- HandleCreateThreadEvent(dbe.u.CreateThread, dbe.dwThreadId);
- break;
- case CREATE_PROCESS_DEBUG_EVENT:
- continue_status =
- HandleCreateProcessEvent(dbe.u.CreateProcessInfo, dbe.dwThreadId);
- break;
- case EXIT_THREAD_DEBUG_EVENT:
- continue_status =
- HandleExitThreadEvent(dbe.u.ExitThread, dbe.dwThreadId);
- break;
- case EXIT_PROCESS_DEBUG_EVENT:
- continue_status =
- HandleExitProcessEvent(dbe.u.ExitProcess, dbe.dwThreadId);
- should_debug = false;
- break;
- case LOAD_DLL_DEBUG_EVENT:
- continue_status = HandleLoadDllEvent(dbe.u.LoadDll, dbe.dwThreadId);
- break;
- case UNLOAD_DLL_DEBUG_EVENT:
- continue_status = HandleUnloadDllEvent(dbe.u.UnloadDll, dbe.dwThreadId);
- break;
- case OUTPUT_DEBUG_STRING_EVENT:
- continue_status = HandleODSEvent(dbe.u.DebugString, dbe.dwThreadId);
- break;
- case RIP_EVENT:
- continue_status = HandleRipEvent(dbe.u.RipInfo, dbe.dwThreadId);
- if (dbe.u.RipInfo.dwType == SLE_ERROR)
- should_debug = false;
- break;
- }
-
- LLDB_LOGV(log, "calling ContinueDebugEvent({0}, {1}, {2}) on thread {3}.",
- dbe.dwProcessId, dbe.dwThreadId, continue_status,
- ::GetCurrentThreadId());
-
- ::ContinueDebugEvent(dbe.dwProcessId, dbe.dwThreadId, continue_status);
-
- if (m_detached) {
- should_debug = false;
- }
- } else {
- LLDB_LOG(log, "returned FALSE from WaitForDebugEvent. Error = {0}",
- ::GetLastError());
-
- should_debug = false;
- }
- }
- FreeProcessHandles();
-
- LLDB_LOG(log, "WaitForDebugEvent loop completed, exiting.");
- ::SetEvent(m_debugging_ended_event);
-}
-
-ExceptionResult
-DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info,
- DWORD thread_id) {
- Log *log =
- ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION);
- if (m_is_shutting_down) {
- // A breakpoint that occurs while `m_pid_to_detach` is non-zero is a magic
- // exception that
- // we use simply to wake up the DebuggerThread so that we can close out the
- // debug loop.
- if (m_pid_to_detach != 0 &&
- info.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) {
- LLDB_LOG(log, "Breakpoint exception is cue to detach from process {0:x}",
- m_pid_to_detach.load());
- ::DebugActiveProcessStop(m_pid_to_detach);
- m_detached = true;
- }
-
- // Don't perform any blocking operations while we're shutting down. That
- // will cause TerminateProcess -> WaitForSingleObject to time out.
- return ExceptionResult::SendToApplication;
- }
-
- bool first_chance = (info.dwFirstChance != 0);
-
- m_active_exception.reset(
- new ExceptionRecord(info.ExceptionRecord, thread_id));
- LLDB_LOG(log, "encountered {0} chance exception {1:x} on thread {2:x}",
- first_chance ? "first" : "second",
- info.ExceptionRecord.ExceptionCode, thread_id);
-
- ExceptionResult result =
- m_debug_delegate->OnDebugException(first_chance, *m_active_exception);
- m_exception_pred.SetValue(result, eBroadcastNever);
-
- LLDB_LOG(log, "waiting for ExceptionPred != BreakInDebugger");
- result = *m_exception_pred.WaitForValueNotEqualTo(
- ExceptionResult::BreakInDebugger);
-
- LLDB_LOG(log, "got ExceptionPred = {0}", (int)m_exception_pred.GetValue());
- return result;
-}
-
-DWORD
-DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info,
- DWORD thread_id) {
- Log *log =
- ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD);
- LLDB_LOG(log, "Thread {0} spawned in process {1}", thread_id,
- m_process.GetProcessId());
- HostThread thread(info.hThread);
- thread.GetNativeThread().SetOwnsHandle(false);
- m_debug_delegate->OnCreateThread(thread);
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info,
- DWORD thread_id) {
- Log *log =
- ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT | WINDOWS_LOG_PROCESS);
- uint32_t process_id = ::GetProcessId(info.hProcess);
-
- LLDB_LOG(log, "process {0} spawned", process_id);
-
- std::string thread_name;
- llvm::raw_string_ostream name_stream(thread_name);
- name_stream << "lldb.plugin.process-windows.slave[" << process_id << "]";
- name_stream.flush();
- llvm::set_thread_name(thread_name);
-
- // info.hProcess and info.hThread are closed automatically by Windows when
- // EXIT_PROCESS_DEBUG_EVENT is received.
- m_process = HostProcess(info.hProcess);
- ((HostProcessWindows &)m_process.GetNativeProcess()).SetOwnsHandle(false);
- m_main_thread = HostThread(info.hThread);
- m_main_thread.GetNativeThread().SetOwnsHandle(false);
- m_image_file = info.hFile;
-
- lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfImage);
- m_debug_delegate->OnDebuggerConnected(load_addr);
-
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info,
- DWORD thread_id) {
- Log *log =
- ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD);
- LLDB_LOG(log, "Thread {0} exited with code {1} in process {2}", thread_id,
- info.dwExitCode, m_process.GetProcessId());
- m_debug_delegate->OnExitThread(thread_id, info.dwExitCode);
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info,
- DWORD thread_id) {
- Log *log =
- ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD);
- LLDB_LOG(log, "process {0} exited with code {1}", m_process.GetProcessId(),
- info.dwExitCode);
-
- m_debug_delegate->OnExitProcess(info.dwExitCode);
-
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info,
- DWORD thread_id) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT);
- if (info.hFile == nullptr) {
- // Not sure what this is, so just ignore it.
- LLDB_LOG(log, "Warning: Inferior {0} has a NULL file handle, returning...",
- m_process.GetProcessId());
- return DBG_CONTINUE;
- }
-
- std::vector<wchar_t> buffer(1);
- DWORD required_size =
- GetFinalPathNameByHandleW(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
- if (required_size > 0) {
- buffer.resize(required_size + 1);
- required_size = GetFinalPathNameByHandleW(info.hFile, &buffer[0],
- required_size, VOLUME_NAME_DOS);
- std::string path_str_utf8;
- llvm::convertWideToUTF8(buffer.data(), path_str_utf8);
- llvm::StringRef path_str = path_str_utf8;
- const char *path = path_str.data();
- if (path_str.startswith("\\\\?\\"))
- path += 4;
-
- FileSpec file_spec(path);
- ModuleSpec module_spec(file_spec);
- lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll);
-
- LLDB_LOG(log, "Inferior {0} - DLL '{1}' loaded at address {2:x}...",
- m_process.GetProcessId(), path, info.lpBaseOfDll);
-
- m_debug_delegate->OnLoadDll(module_spec, load_addr);
- } else {
- LLDB_LOG(
- log,
- "Inferior {0} - Error {1} occurred calling GetFinalPathNameByHandle",
- m_process.GetProcessId(), ::GetLastError());
- }
- // Windows does not automatically close info.hFile, so we need to do it.
- ::CloseHandle(info.hFile);
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info,
- DWORD thread_id) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT);
- LLDB_LOG(log, "process {0} unloading DLL at addr {1:x}.",
- m_process.GetProcessId(), info.lpBaseOfDll);
-
- m_debug_delegate->OnUnloadDll(
- reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll));
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info,
- DWORD thread_id) {
- return DBG_CONTINUE;
-}
-
-DWORD
-DebuggerThread::HandleRipEvent(const RIP_INFO &info, DWORD thread_id) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT);
- LLDB_LOG(log, "encountered error {0} (type={1}) in process {2} thread {3}",
- info.dwError, info.dwType, m_process.GetProcessId(), thread_id);
-
- Status error(info.dwError, eErrorTypeWin32);
- m_debug_delegate->OnDebuggerError(error, info.dwType);
-
- return DBG_CONTINUE;
-}
diff --git a/source/Plugins/Process/Windows/Common/DebuggerThread.h b/source/Plugins/Process/Windows/Common/DebuggerThread.h
deleted file mode 100644
index 047d3ccb7296b..0000000000000
--- a/source/Plugins/Process/Windows/Common/DebuggerThread.h
+++ /dev/null
@@ -1,106 +0,0 @@
-//===-- DebuggerThread.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_Plugins_Process_Windows_DebuggerThread_H_
-#define liblldb_Plugins_Process_Windows_DebuggerThread_H_
-
-#include <atomic>
-#include <memory>
-
-#include "ForwardDecl.h"
-#include "lldb/Host/HostProcess.h"
-#include "lldb/Host/HostThread.h"
-#include "lldb/Host/windows/windows.h"
-#include "lldb/Utility/Predicate.h"
-
-namespace lldb_private {
-
-//----------------------------------------------------------------------
-// DebuggerThread
-//
-// Debugs a single process, notifying listeners as appropriate when interesting
-// things occur.
-//----------------------------------------------------------------------
-class DebuggerThread : public std::enable_shared_from_this<DebuggerThread> {
-public:
- DebuggerThread(DebugDelegateSP debug_delegate);
- virtual ~DebuggerThread();
-
- Status DebugLaunch(const ProcessLaunchInfo &launch_info);
- Status DebugAttach(lldb::pid_t pid, const ProcessAttachInfo &attach_info);
-
- HostProcess GetProcess() const { return m_process; }
- HostThread GetMainThread() const { return m_main_thread; }
- std::weak_ptr<ExceptionRecord> GetActiveException() {
- return m_active_exception;
- }
-
- Status StopDebugging(bool terminate);
-
- void ContinueAsyncException(ExceptionResult result);
-
-private:
- void FreeProcessHandles();
- void DebugLoop();
- ExceptionResult HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info,
- DWORD thread_id);
- DWORD HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info,
- DWORD thread_id);
- DWORD HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info,
- DWORD thread_id);
- DWORD HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info,
- DWORD thread_id);
- DWORD HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info,
- DWORD thread_id);
- DWORD HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id);
- DWORD HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info,
- DWORD thread_id);
- DWORD HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info, DWORD thread_id);
- DWORD HandleRipEvent(const RIP_INFO &info, DWORD thread_id);
-
- DebugDelegateSP m_debug_delegate;
-
- HostProcess m_process; // The process being debugged.
- HostThread m_main_thread; // The main thread of the inferior.
-
- // The image file of the process being debugged.
- HANDLE m_image_file = nullptr;
-
- // The current exception waiting to be handled
- ExceptionRecordSP m_active_exception;
-
- // A predicate which gets signalled when an exception is finished processing
- // and the debug loop can be continued.
- Predicate<ExceptionResult> m_exception_pred;
-
- // An event which gets signalled by the debugger thread when it exits the
- // debugger loop and is detached from the inferior.
- HANDLE m_debugging_ended_event = nullptr;
-
- // Signals the loop to detach from the process (specified by pid).
- std::atomic<DWORD> m_pid_to_detach;
-
- // Signals the debug loop to stop processing certain types of events that
- // block shutdown.
- std::atomic<bool> m_is_shutting_down;
-
- // Indicates we've detached from the inferior process and the debug loop can
- // exit.
- bool m_detached = false;
-
- static lldb::thread_result_t DebuggerThreadLaunchRoutine(void *data);
- lldb::thread_result_t
- DebuggerThreadLaunchRoutine(const ProcessLaunchInfo &launch_info);
- static lldb::thread_result_t DebuggerThreadAttachRoutine(void *data);
- lldb::thread_result_t
- DebuggerThreadAttachRoutine(lldb::pid_t pid,
- const ProcessAttachInfo &launch_info);
-};
-}
-#endif
diff --git a/source/Plugins/Process/Windows/Common/ExceptionRecord.h b/source/Plugins/Process/Windows/Common/ExceptionRecord.h
deleted file mode 100644
index 1eec85d52c264..0000000000000
--- a/source/Plugins/Process/Windows/Common/ExceptionRecord.h
+++ /dev/null
@@ -1,80 +0,0 @@
-//===-- ExceptionRecord.h ---------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_Plugins_Process_Windows_ExceptionRecord_H_
-#define liblldb_Plugins_Process_Windows_ExceptionRecord_H_
-
-#include "lldb/Host/windows/windows.h"
-#include "lldb/lldb-forward.h"
-#include <dbghelp.h>
-
-#include <memory>
-#include <vector>
-
-namespace lldb_private {
-
-//----------------------------------------------------------------------
-// ExceptionRecord
-//
-// ExceptionRecord defines an interface which allows implementors to receive
-// notification of events that happen in a debugged process.
-//----------------------------------------------------------------------
-class ExceptionRecord {
-public:
- ExceptionRecord(const EXCEPTION_RECORD &record, lldb::tid_t thread_id) {
- m_code = record.ExceptionCode;
- m_continuable = (record.ExceptionFlags == 0);
- if (record.ExceptionRecord)
- m_next_exception.reset(
- new ExceptionRecord(*record.ExceptionRecord, thread_id));
- m_exception_addr = reinterpret_cast<lldb::addr_t>(record.ExceptionAddress);
- m_thread_id = thread_id;
- m_arguments.assign(record.ExceptionInformation,
- record.ExceptionInformation + record.NumberParameters);
- }
-
- // MINIDUMP_EXCEPTIONs are almost identical to EXCEPTION_RECORDs.
- ExceptionRecord(const MINIDUMP_EXCEPTION &record, lldb::tid_t thread_id)
- : m_code(record.ExceptionCode), m_continuable(record.ExceptionFlags == 0),
- m_next_exception(nullptr),
- m_exception_addr(static_cast<lldb::addr_t>(record.ExceptionAddress)),
- m_thread_id(thread_id),
- m_arguments(record.ExceptionInformation,
- record.ExceptionInformation + record.NumberParameters) {
- // Set up link to nested exception.
- if (record.ExceptionRecord) {
- m_next_exception.reset(new ExceptionRecord(
- *reinterpret_cast<const MINIDUMP_EXCEPTION *>(record.ExceptionRecord),
- thread_id));
- }
- }
-
- virtual ~ExceptionRecord() {}
-
- DWORD
- GetExceptionCode() const { return m_code; }
- bool IsContinuable() const { return m_continuable; }
- const ExceptionRecord *GetNextException() const {
- return m_next_exception.get();
- }
- lldb::addr_t GetExceptionAddress() const { return m_exception_addr; }
-
- lldb::tid_t GetThreadID() const { return m_thread_id; }
-
-private:
- DWORD m_code;
- bool m_continuable;
- std::shared_ptr<ExceptionRecord> m_next_exception;
- lldb::addr_t m_exception_addr;
- lldb::tid_t m_thread_id;
- std::vector<ULONG_PTR> m_arguments;
-};
-}
-
-#endif
diff --git a/source/Plugins/Process/Windows/Common/ForwardDecl.h b/source/Plugins/Process/Windows/Common/ForwardDecl.h
deleted file mode 100644
index ce2af3ca4111a..0000000000000
--- a/source/Plugins/Process/Windows/Common/ForwardDecl.h
+++ /dev/null
@@ -1,42 +0,0 @@
-//===-- ForwardDecl.h -------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_Plugins_Process_Windows_ForwardDecl_H_
-#define liblldb_Plugins_Process_Windows_ForwardDecl_H_
-
-#include <memory>
-
-// ExceptionResult is returned by the debug delegate to specify how it processed
-// the exception.
-enum class ExceptionResult {
- BreakInDebugger, // Break in the debugger and give the user a chance to
- // interact with
- // the program before continuing.
- MaskException, // Eat the exception and don't let the application know it
- // occurred.
- SendToApplication // Send the exception to the application to be handled as if
- // there were
- // no debugger attached.
-};
-
-namespace lldb_private {
-
-class ProcessWindows;
-
-class IDebugDelegate;
-class DebuggerThread;
-class ExceptionRecord;
-
-typedef std::shared_ptr<IDebugDelegate> DebugDelegateSP;
-typedef std::shared_ptr<DebuggerThread> DebuggerThreadSP;
-typedef std::shared_ptr<ExceptionRecord> ExceptionRecordSP;
-typedef std::unique_ptr<ExceptionRecord> ExceptionRecordUP;
-}
-
-#endif
diff --git a/source/Plugins/Process/Windows/Common/IDebugDelegate.h b/source/Plugins/Process/Windows/Common/IDebugDelegate.h
deleted file mode 100644
index 73c285f1ecc79..0000000000000
--- a/source/Plugins/Process/Windows/Common/IDebugDelegate.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//===-- IDebugDelegate.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_Plugins_Process_Windows_IDebugDelegate_H_
-#define liblldb_Plugins_Process_Windows_IDebugDelegate_H_
-
-#include "ForwardDecl.h"
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-types.h"
-#include <string>
-
-namespace lldb_private {
-class Status;
-class HostThread;
-
-//----------------------------------------------------------------------
-// IDebugDelegate
-//
-// IDebugDelegate defines an interface which allows implementors to receive
-// notification of events that happen in a debugged process.
-//----------------------------------------------------------------------
-class IDebugDelegate {
-public:
- virtual ~IDebugDelegate() {}
-
- virtual void OnExitProcess(uint32_t exit_code) = 0;
- virtual void OnDebuggerConnected(lldb::addr_t image_base) = 0;
- virtual ExceptionResult OnDebugException(bool first_chance,
- const ExceptionRecord &record) = 0;
- virtual void OnCreateThread(const HostThread &thread) = 0;
- virtual void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) = 0;
- virtual void OnLoadDll(const ModuleSpec &module_spec,
- lldb::addr_t module_addr) = 0;
- virtual void OnUnloadDll(lldb::addr_t module_addr) = 0;
- virtual void OnDebugString(const std::string &string) = 0;
- virtual void OnDebuggerError(const Status &error, uint32_t type) = 0;
-};
-}
-
-#endif
diff --git a/source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp b/source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp
deleted file mode 100644
index 92aa7e2678b95..0000000000000
--- a/source/Plugins/Process/Windows/Common/LocalDebugDelegate.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-//===-- LocalDebugDelegate.cpp ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "LocalDebugDelegate.h"
-#include "ProcessWindows.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-LocalDebugDelegate::LocalDebugDelegate(ProcessWP process)
- : m_process(process) {}
-
-void LocalDebugDelegate::OnExitProcess(uint32_t exit_code) {
- if (ProcessWindowsSP process = GetProcessPointer())
- process->OnExitProcess(exit_code);
-}
-
-void LocalDebugDelegate::OnDebuggerConnected(lldb::addr_t image_base) {
- if (ProcessWindowsSP process = GetProcessPointer())
- process->OnDebuggerConnected(image_base);
-}
-
-ExceptionResult
-LocalDebugDelegate::OnDebugException(bool first_chance,
- const ExceptionRecord &record) {
- if (ProcessWindowsSP process = GetProcessPointer())
- return process->OnDebugException(first_chance, record);
- else
- return ExceptionResult::MaskException;
-}
-
-void LocalDebugDelegate::OnCreateThread(const HostThread &thread) {
- if (ProcessWindowsSP process = GetProcessPointer())
- process->OnCreateThread(thread);
-}
-
-void LocalDebugDelegate::OnExitThread(lldb::tid_t thread_id,
- uint32_t exit_code) {
- if (ProcessWindowsSP process = GetProcessPointer())
- process->OnExitThread(thread_id, exit_code);
-}
-
-void LocalDebugDelegate::OnLoadDll(const lldb_private::ModuleSpec &module_spec,
- lldb::addr_t module_addr) {
- if (ProcessWindowsSP process = GetProcessPointer())
- process->OnLoadDll(module_spec, module_addr);
-}
-
-void LocalDebugDelegate::OnUnloadDll(lldb::addr_t module_addr) {
- if (ProcessWindowsSP process = GetProcessPointer())
- process->OnUnloadDll(module_addr);
-}
-
-void LocalDebugDelegate::OnDebugString(const std::string &string) {
- if (ProcessWindowsSP process = GetProcessPointer())
- process->OnDebugString(string);
-}
-
-void LocalDebugDelegate::OnDebuggerError(const Status &error, uint32_t type) {
- if (ProcessWindowsSP process = GetProcessPointer())
- process->OnDebuggerError(error, type);
-}
-
-ProcessWindowsSP LocalDebugDelegate::GetProcessPointer() {
- ProcessSP process = m_process.lock();
- return std::static_pointer_cast<ProcessWindows>(process);
-}
diff --git a/source/Plugins/Process/Windows/Common/LocalDebugDelegate.h b/source/Plugins/Process/Windows/Common/LocalDebugDelegate.h
deleted file mode 100644
index 2cb479ccce8ab..0000000000000
--- a/source/Plugins/Process/Windows/Common/LocalDebugDelegate.h
+++ /dev/null
@@ -1,67 +0,0 @@
-//===-- LocalDebugDelegate.h ------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_Plugins_Process_Windows_LocalDebugDelegate_H_
-#define liblldb_Plugins_Process_Windows_LocalDebugDelegate_H_
-
-#include <memory>
-
-#include "IDebugDelegate.h"
-
-#include "lldb/lldb-forward.h"
-
-namespace lldb_private {
-
-class ProcessWindows;
-typedef std::shared_ptr<ProcessWindows> ProcessWindowsSP;
-
-//----------------------------------------------------------------------
-// LocalDebugDelegate
-//
-// LocalDebugDelegate creates a connection between a ProcessWindows and the
-// debug driver. This serves to decouple ProcessWindows from the debug
-// driver. It would be possible to get a similar decoupling by just having
-// ProcessWindows implement this interface directly. There are two reasons
-// why we don't do this:
-//
-// 1) In the future when we add support for local debugging through LLGS, and we
-// go through the Native*Protocol interface, it is likely we will need the
-// additional flexibility provided by this sort of adapter pattern.
-// 2) LLDB holds a shared_ptr to the ProcessWindows, and our driver thread
-// needs access to it as well. To avoid a race condition, we want to make
-// sure that we're also holding onto a shared_ptr.
-// lldb_private::Process supports enable_shared_from_this, but that gives us
-// a ProcessSP (which is exactly what we are trying to decouple from the
-// driver), so this adapter serves as a way to transparently hold the
-// ProcessSP while still keeping it decoupled from the driver.
-//----------------------------------------------------------------------
-class LocalDebugDelegate : public IDebugDelegate {
-public:
- explicit LocalDebugDelegate(lldb::ProcessWP process);
-
- void OnExitProcess(uint32_t exit_code) override;
- void OnDebuggerConnected(lldb::addr_t image_base) override;
- ExceptionResult OnDebugException(bool first_chance,
- const ExceptionRecord &record) override;
- void OnCreateThread(const HostThread &thread) override;
- void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;
- void OnLoadDll(const lldb_private::ModuleSpec &module_spec,
- lldb::addr_t module_addr) override;
- void OnUnloadDll(lldb::addr_t module_addr) override;
- void OnDebugString(const std::string &message) override;
- void OnDebuggerError(const Status &error, uint32_t type) override;
-
-private:
- ProcessWindowsSP GetProcessPointer();
-
- lldb::ProcessWP m_process;
-};
-}
-
-#endif
diff --git a/source/Plugins/Process/Windows/Common/NtStructures.h b/source/Plugins/Process/Windows/Common/NtStructures.h
deleted file mode 100644
index 6826b98c769e7..0000000000000
--- a/source/Plugins/Process/Windows/Common/NtStructures.h
+++ /dev/null
@@ -1,31 +0,0 @@
-//===-- NtStructures.h ------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_Plugins_Process_Windows_Common_NtStructures_h_
-#define liblldb_Plugins_Process_Windows_Common_NtStructures_h_
-
-#include "lldb/Host/windows/windows.h"
-
-// This describes the layout of a TEB (Thread Environment Block) for a 64-bit
-// process. It's adapted from the 32-bit TEB in winternl.h. Currently, we care
-// only about the position of the TlsSlots.
-struct TEB64 {
- ULONG64 Reserved1[12];
- ULONG64 ProcessEnvironmentBlock;
- ULONG64 Reserved2[399];
- BYTE Reserved3[1952];
- ULONG64 TlsSlots[64];
- BYTE Reserved4[8];
- ULONG64 Reserved5[26];
- ULONG64 ReservedForOle; // Windows 2000 only
- ULONG64 Reserved6[4];
- ULONG64 TlsExpansionSlots;
-};
-
-#endif
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
deleted file mode 100644
index 3fe5ab7804cba..0000000000000
--- a/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ /dev/null
@@ -1,1119 +0,0 @@
-//===-- ProcessWindows.cpp --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ProcessWindows.h"
-
-// Windows includes
-#include "lldb/Host/windows/windows.h"
-#include <psapi.h>
-
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Section.h"
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/HostNativeProcessBase.h"
-#include "lldb/Host/HostProcess.h"
-#include "lldb/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/windows.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Target/MemoryRegionInfo.h"
-#include "lldb/Target/StopInfo.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/State.h"
-
-#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/Threading.h"
-#include "llvm/Support/raw_ostream.h"
-
-#include "DebuggerThread.h"
-#include "ExceptionRecord.h"
-#include "ForwardDecl.h"
-#include "LocalDebugDelegate.h"
-#include "ProcessWindowsLog.h"
-#include "TargetThreadWindows.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-std::string GetProcessExecutableName(HANDLE process_handle) {
- std::vector<wchar_t> file_name;
- DWORD file_name_size = MAX_PATH; // first guess, not an absolute limit
- DWORD copied = 0;
- do {
- file_name_size *= 2;
- file_name.resize(file_name_size);
- copied = ::GetModuleFileNameExW(process_handle, NULL, file_name.data(),
- file_name_size);
- } while (copied >= file_name_size);
- file_name.resize(copied);
- std::string result;
- llvm::convertWideToUTF8(file_name.data(), result);
- return result;
-}
-
-std::string GetProcessExecutableName(DWORD pid) {
- std::string file_name;
- HANDLE process_handle =
- ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
- if (process_handle != NULL) {
- file_name = GetProcessExecutableName(process_handle);
- ::CloseHandle(process_handle);
- }
- return file_name;
-}
-
-DWORD ConvertLldbToWinApiProtect(uint32_t protect) {
- // We also can process a read / write permissions here, but if the debugger
- // will make later a write into the allocated memory, it will fail. To get
- // around it is possible inside DoWriteMemory to remember memory permissions,
- // allow write, write and restore permissions, but for now we process only
- // the executable permission.
- //
- // TODO: Process permissions other than executable
- if (protect & ePermissionsExecutable)
- return PAGE_EXECUTE_READWRITE;
-
- return PAGE_READWRITE;
-}
-
-} // anonymous namespace
-
-namespace lldb_private {
-
-// We store a pointer to this class in the ProcessWindows, so that we don't
-// expose Windows-specific types and implementation details from a public
-// header file.
-class ProcessWindowsData {
-public:
- ProcessWindowsData(bool stop_at_entry) : m_stop_at_entry(stop_at_entry) {
- m_initial_stop_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
- }
-
- ~ProcessWindowsData() { ::CloseHandle(m_initial_stop_event); }
-
- Status m_launch_error;
- DebuggerThreadSP m_debugger;
- StopInfoSP m_pending_stop_info;
- HANDLE m_initial_stop_event = nullptr;
- bool m_initial_stop_received = false;
- bool m_stop_at_entry;
- std::map<lldb::tid_t, HostThread> m_new_threads;
- std::set<lldb::tid_t> m_exited_threads;
-};
-
-ProcessSP ProcessWindows::CreateInstance(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const FileSpec *) {
- return ProcessSP(new ProcessWindows(target_sp, listener_sp));
-}
-
-void ProcessWindows::Initialize() {
- static llvm::once_flag g_once_flag;
-
- llvm::call_once(g_once_flag, []() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(), CreateInstance);
- });
-}
-
-void ProcessWindows::Terminate() {}
-
-lldb_private::ConstString ProcessWindows::GetPluginNameStatic() {
- static ConstString g_name("windows");
- return g_name;
-}
-
-const char *ProcessWindows::GetPluginDescriptionStatic() {
- return "Process plugin for Windows";
-}
-
-//------------------------------------------------------------------------------
-// Constructors and destructors.
-
-ProcessWindows::ProcessWindows(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp)
- : lldb_private::Process(target_sp, listener_sp) {}
-
-ProcessWindows::~ProcessWindows() {}
-
-size_t ProcessWindows::GetSTDOUT(char *buf, size_t buf_size, Status &error) {
- error.SetErrorString("GetSTDOUT unsupported on Windows");
- return 0;
-}
-
-size_t ProcessWindows::GetSTDERR(char *buf, size_t buf_size, Status &error) {
- error.SetErrorString("GetSTDERR unsupported on Windows");
- return 0;
-}
-
-size_t ProcessWindows::PutSTDIN(const char *buf, size_t buf_size,
- Status &error) {
- error.SetErrorString("PutSTDIN unsupported on Windows");
- return 0;
-}
-
-//------------------------------------------------------------------------------
-// ProcessInterface protocol.
-
-lldb_private::ConstString ProcessWindows::GetPluginName() {
- return GetPluginNameStatic();
-}
-
-uint32_t ProcessWindows::GetPluginVersion() { return 1; }
-
-Status ProcessWindows::EnableBreakpointSite(BreakpointSite *bp_site) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_BREAKPOINTS);
- LLDB_LOG(log, "bp_site = {0:x}, id={1}, addr={2:x}", bp_site,
- bp_site->GetID(), bp_site->GetLoadAddress());
-
- Status error = EnableSoftwareBreakpoint(bp_site);
- if (!error.Success())
- LLDB_LOG(log, "error: {0}", error);
- return error;
-}
-
-Status ProcessWindows::DisableBreakpointSite(BreakpointSite *bp_site) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_BREAKPOINTS);
- LLDB_LOG(log, "bp_site = {0:x}, id={1}, addr={2:x}", bp_site,
- bp_site->GetID(), bp_site->GetLoadAddress());
-
- Status error = DisableSoftwareBreakpoint(bp_site);
-
- if (!error.Success())
- LLDB_LOG(log, "error: {0}", error);
- return error;
-}
-
-Status ProcessWindows::DoDetach(bool keep_stopped) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- DebuggerThreadSP debugger_thread;
- StateType private_state;
- {
- // Acquire the lock only long enough to get the DebuggerThread.
- // StopDebugging() will trigger a call back into ProcessWindows which will
- // also acquire the lock. Thus we have to release the lock before calling
- // StopDebugging().
- llvm::sys::ScopedLock lock(m_mutex);
-
- private_state = GetPrivateState();
-
- if (!m_session_data) {
- LLDB_LOG(log, "state = {0}, but there is no active session.",
- private_state);
- return Status();
- }
-
- debugger_thread = m_session_data->m_debugger;
- }
-
- Status error;
- if (private_state != eStateExited && private_state != eStateDetached) {
- LLDB_LOG(log, "detaching from process {0} while state = {1}.",
- debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
- private_state);
- error = debugger_thread->StopDebugging(false);
- if (error.Success()) {
- SetPrivateState(eStateDetached);
- }
-
- // By the time StopDebugging returns, there is no more debugger thread, so
- // we can be assured that no other thread will race for the session data.
- m_session_data.reset();
- } else {
- LLDB_LOG(
- log,
- "error: process {0} in state = {1}, but cannot destroy in this state.",
- debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
- private_state);
- }
-
- return error;
-}
-
-Status ProcessWindows::DoLaunch(Module *exe_module,
- ProcessLaunchInfo &launch_info) {
- // Even though m_session_data is accessed here, it is before a debugger
- // thread has been kicked off. So there's no race conditions, and it
- // shouldn't be necessary to acquire the mutex.
-
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- Status result;
-
- FileSpec working_dir = launch_info.GetWorkingDirectory();
- namespace fs = llvm::sys::fs;
- if (working_dir) {
- FileSystem::Instance().Resolve(working_dir);
- if (!FileSystem::Instance().IsDirectory(working_dir)) {
- result.SetErrorStringWithFormat("No such file or directory: %s",
- working_dir.GetCString());
- return result;
- }
- }
-
- if (!launch_info.GetFlags().Test(eLaunchFlagDebug)) {
- StreamString stream;
- stream.Printf("ProcessWindows unable to launch '%s'. ProcessWindows can "
- "only be used for debug launches.",
- launch_info.GetExecutableFile().GetPath().c_str());
- std::string message = stream.GetString();
- result.SetErrorString(message.c_str());
-
- LLDB_LOG(log, "error: {0}", message);
- return result;
- }
-
- bool stop_at_entry = launch_info.GetFlags().Test(eLaunchFlagStopAtEntry);
- m_session_data.reset(new ProcessWindowsData(stop_at_entry));
-
- DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
- m_session_data->m_debugger.reset(new DebuggerThread(delegate));
- DebuggerThreadSP debugger = m_session_data->m_debugger;
-
- // Kick off the DebugLaunch asynchronously and wait for it to complete.
- result = debugger->DebugLaunch(launch_info);
- if (result.Fail()) {
- LLDB_LOG(log, "failed launching '{0}'. {1}",
- launch_info.GetExecutableFile().GetPath(), result);
- return result;
- }
-
- HostProcess process;
- Status error = WaitForDebuggerConnection(debugger, process);
- if (error.Fail()) {
- LLDB_LOG(log, "failed launching '{0}'. {1}",
- launch_info.GetExecutableFile().GetPath(), error);
- return error;
- }
-
- LLDB_LOG(log, "successfully launched '{0}'",
- launch_info.GetExecutableFile().GetPath());
-
- // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the
- // private state should already be set to eStateStopped as a result of
- // hitting the initial breakpoint. If it was not set, the breakpoint should
- // have already been resumed from and the private state should already be
- // eStateRunning.
- launch_info.SetProcessID(process.GetProcessId());
- SetID(process.GetProcessId());
-
- return result;
-}
-
-Status
-ProcessWindows::DoAttachToProcessWithID(lldb::pid_t pid,
- const ProcessAttachInfo &attach_info) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- m_session_data.reset(
- new ProcessWindowsData(!attach_info.GetContinueOnceAttached()));
-
- DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
- DebuggerThreadSP debugger(new DebuggerThread(delegate));
-
- m_session_data->m_debugger = debugger;
-
- DWORD process_id = static_cast<DWORD>(pid);
- Status error = debugger->DebugAttach(process_id, attach_info);
- if (error.Fail()) {
- LLDB_LOG(
- log,
- "encountered an error occurred initiating the asynchronous attach. {0}",
- error);
- return error;
- }
-
- HostProcess process;
- error = WaitForDebuggerConnection(debugger, process);
- if (error.Fail()) {
- LLDB_LOG(log,
- "encountered an error waiting for the debugger to connect. {0}",
- error);
- return error;
- }
-
- LLDB_LOG(log, "successfully attached to process with pid={0}", process_id);
-
- // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the
- // private state should already be set to eStateStopped as a result of
- // hitting the initial breakpoint. If it was not set, the breakpoint should
- // have already been resumed from and the private state should already be
- // eStateRunning.
- SetID(process.GetProcessId());
- return error;
-}
-
-Status ProcessWindows::DoResume() {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- llvm::sys::ScopedLock lock(m_mutex);
- Status error;
-
- StateType private_state = GetPrivateState();
- if (private_state == eStateStopped || private_state == eStateCrashed) {
- LLDB_LOG(log, "process {0} is in state {1}. Resuming...",
- m_session_data->m_debugger->GetProcess().GetProcessId(),
- GetPrivateState());
-
- ExceptionRecordSP active_exception =
- m_session_data->m_debugger->GetActiveException().lock();
- if (active_exception) {
- // Resume the process and continue processing debug events. Mask the
- // exception so that from the process's view, there is no indication that
- // anything happened.
- m_session_data->m_debugger->ContinueAsyncException(
- ExceptionResult::MaskException);
- }
-
- LLDB_LOG(log, "resuming {0} threads.", m_thread_list.GetSize());
-
- bool failed = false;
- for (uint32_t i = 0; i < m_thread_list.GetSize(); ++i) {
- auto thread = std::static_pointer_cast<TargetThreadWindows>(
- m_thread_list.GetThreadAtIndex(i));
- Status result = thread->DoResume();
- if (result.Fail()) {
- failed = true;
- LLDB_LOG(
- log,
- "Trying to resume thread at index {0}, but failed with error {1}.",
- i, result);
- }
- }
-
- if (failed) {
- error.SetErrorString("ProcessWindows::DoResume failed");
- return error;
- } else {
- SetPrivateState(eStateRunning);
- }
- } else {
- LLDB_LOG(log, "error: process {0} is in state {1}. Returning...",
- m_session_data->m_debugger->GetProcess().GetProcessId(),
- GetPrivateState());
- }
- return error;
-}
-
-Status ProcessWindows::DoDestroy() {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- DebuggerThreadSP debugger_thread;
- StateType private_state;
- {
- // Acquire this lock inside an inner scope, only long enough to get the
- // DebuggerThread. StopDebugging() will trigger a call back into
- // ProcessWindows which will acquire the lock again, so we need to not
- // deadlock.
- llvm::sys::ScopedLock lock(m_mutex);
-
- private_state = GetPrivateState();
-
- if (!m_session_data) {
- LLDB_LOG(log, "warning: state = {0}, but there is no active session.",
- private_state);
- return Status();
- }
-
- debugger_thread = m_session_data->m_debugger;
- }
-
- Status error;
- if (private_state != eStateExited && private_state != eStateDetached) {
- LLDB_LOG(log, "Shutting down process {0} while state = {1}.",
- debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
- private_state);
- error = debugger_thread->StopDebugging(true);
-
- // By the time StopDebugging returns, there is no more debugger thread, so
- // we can be assured that no other thread will race for the session data.
- m_session_data.reset();
- } else {
- LLDB_LOG(log, "cannot destroy process {0} while state = {1}",
- debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
- private_state);
- }
-
- return error;
-}
-
-Status ProcessWindows::DoHalt(bool &caused_stop) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- Status error;
- StateType state = GetPrivateState();
- if (state == eStateStopped)
- caused_stop = false;
- else {
- llvm::sys::ScopedLock lock(m_mutex);
- caused_stop = ::DebugBreakProcess(m_session_data->m_debugger->GetProcess()
- .GetNativeProcess()
- .GetSystemHandle());
- if (!caused_stop) {
- error.SetError(::GetLastError(), eErrorTypeWin32);
- LLDB_LOG(log, "DebugBreakProcess failed with error {0}", error);
- }
- }
- return error;
-}
-
-void ProcessWindows::DidLaunch() {
- ArchSpec arch_spec;
- DidAttach(arch_spec);
-}
-
-void ProcessWindows::DidAttach(ArchSpec &arch_spec) {
- llvm::sys::ScopedLock lock(m_mutex);
-
- // The initial stop won't broadcast the state change event, so account for
- // that here.
- if (m_session_data && GetPrivateState() == eStateStopped &&
- m_session_data->m_stop_at_entry)
- RefreshStateAfterStop();
-}
-
-void ProcessWindows::RefreshStateAfterStop() {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EXCEPTION);
- llvm::sys::ScopedLock lock(m_mutex);
-
- if (!m_session_data) {
- LLDB_LOG(log, "no active session. Returning...");
- return;
- }
-
- m_thread_list.RefreshStateAfterStop();
-
- std::weak_ptr<ExceptionRecord> exception_record =
- m_session_data->m_debugger->GetActiveException();
- ExceptionRecordSP active_exception = exception_record.lock();
- if (!active_exception) {
- LLDB_LOG(log,
- "there is no active exception in process {0}. Why is the "
- "process stopped?",
- m_session_data->m_debugger->GetProcess().GetProcessId());
- return;
- }
-
- StopInfoSP stop_info;
- m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID());
- ThreadSP stop_thread = m_thread_list.GetSelectedThread();
- if (!stop_thread)
- return;
-
- switch (active_exception->GetExceptionCode()) {
- case EXCEPTION_SINGLE_STEP: {
- RegisterContextSP register_context = stop_thread->GetRegisterContext();
- const uint64_t pc = register_context->GetPC();
- BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
- if (site && site->ValidForThisThread(stop_thread.get())) {
- LLDB_LOG(log,
- "Single-stepped onto a breakpoint in process {0} at "
- "address {1:x} with breakpoint site {2}",
- m_session_data->m_debugger->GetProcess().GetProcessId(), pc,
- site->GetID());
- stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*stop_thread,
- site->GetID());
- stop_thread->SetStopInfo(stop_info);
- } else {
- LLDB_LOG(log, "single stepping thread {0}", stop_thread->GetID());
- stop_info = StopInfo::CreateStopReasonToTrace(*stop_thread);
- stop_thread->SetStopInfo(stop_info);
- }
- return;
- }
-
- case EXCEPTION_BREAKPOINT: {
- RegisterContextSP register_context = stop_thread->GetRegisterContext();
-
- // The current EIP is AFTER the BP opcode, which is one byte.
- uint64_t pc = register_context->GetPC() - 1;
-
- BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
- if (site) {
- LLDB_LOG(log,
- "detected breakpoint in process {0} at address {1:x} with "
- "breakpoint site {2}",
- m_session_data->m_debugger->GetProcess().GetProcessId(), pc,
- site->GetID());
-
- if (site->ValidForThisThread(stop_thread.get())) {
- LLDB_LOG(log,
- "Breakpoint site {0} is valid for this thread ({1:x}), "
- "creating stop info.",
- site->GetID(), stop_thread->GetID());
-
- stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(
- *stop_thread, site->GetID());
- register_context->SetPC(pc);
- } else {
- LLDB_LOG(log,
- "Breakpoint site {0} is not valid for this thread, "
- "creating empty stop info.",
- site->GetID());
- }
- stop_thread->SetStopInfo(stop_info);
- return;
- } else {
- // The thread hit a hard-coded breakpoint like an `int 3` or
- // `__debugbreak()`.
- LLDB_LOG(log,
- "No breakpoint site matches for this thread. __debugbreak()? "
- "Creating stop info with the exception.");
- // FALLTHROUGH: We'll treat this as a generic exception record in the
- // default case.
- }
- }
-
- default: {
- std::string desc;
- llvm::raw_string_ostream desc_stream(desc);
- desc_stream << "Exception "
- << llvm::format_hex(active_exception->GetExceptionCode(), 8)
- << " encountered at address "
- << llvm::format_hex(active_exception->GetExceptionAddress(), 8);
- stop_info = StopInfo::CreateStopReasonWithException(
- *stop_thread, desc_stream.str().c_str());
- stop_thread->SetStopInfo(stop_info);
- LLDB_LOG(log, "{0}", desc_stream.str());
- return;
- }
- }
-}
-
-bool ProcessWindows::CanDebug(lldb::TargetSP target_sp,
- bool plugin_specified_by_name) {
- if (plugin_specified_by_name)
- return true;
-
- // For now we are just making sure the file exists for a given module
- ModuleSP exe_module_sp(target_sp->GetExecutableModule());
- if (exe_module_sp.get())
- return FileSystem::Instance().Exists(exe_module_sp->GetFileSpec());
- // However, if there is no executable module, we return true since we might
- // be preparing to attach.
- return true;
-}
-
-bool ProcessWindows::UpdateThreadList(ThreadList &old_thread_list,
- ThreadList &new_thread_list) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_THREAD);
- // Add all the threads that were previously running and for which we did not
- // detect a thread exited event.
- int new_size = 0;
- int continued_threads = 0;
- int exited_threads = 0;
- int new_threads = 0;
-
- for (ThreadSP old_thread : old_thread_list.Threads()) {
- lldb::tid_t old_thread_id = old_thread->GetID();
- auto exited_thread_iter =
- m_session_data->m_exited_threads.find(old_thread_id);
- if (exited_thread_iter == m_session_data->m_exited_threads.end()) {
- new_thread_list.AddThread(old_thread);
- ++new_size;
- ++continued_threads;
- LLDB_LOGV(log, "Thread {0} was running and is still running.",
- old_thread_id);
- } else {
- LLDB_LOGV(log, "Thread {0} was running and has exited.", old_thread_id);
- ++exited_threads;
- }
- }
-
- // Also add all the threads that are new since the last time we broke into
- // the debugger.
- for (const auto &thread_info : m_session_data->m_new_threads) {
- ThreadSP thread(new TargetThreadWindows(*this, thread_info.second));
- thread->SetID(thread_info.first);
- new_thread_list.AddThread(thread);
- ++new_size;
- ++new_threads;
- LLDB_LOGV(log, "Thread {0} is new since last update.", thread_info.first);
- }
-
- LLDB_LOG(log, "{0} new threads, {1} old threads, {2} exited threads.",
- new_threads, continued_threads, exited_threads);
-
- m_session_data->m_new_threads.clear();
- m_session_data->m_exited_threads.clear();
-
- return new_size > 0;
-}
-
-bool ProcessWindows::IsAlive() {
- StateType state = GetPrivateState();
- switch (state) {
- case eStateCrashed:
- case eStateDetached:
- case eStateUnloaded:
- case eStateExited:
- case eStateInvalid:
- return false;
- default:
- return true;
- }
-}
-
-size_t ProcessWindows::DoReadMemory(lldb::addr_t vm_addr, void *buf,
- size_t size, Status &error) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
- llvm::sys::ScopedLock lock(m_mutex);
-
- if (!m_session_data)
- return 0;
-
- LLDB_LOG(log, "attempting to read {0} bytes from address {1:x}", size,
- vm_addr);
-
- HostProcess process = m_session_data->m_debugger->GetProcess();
- void *addr = reinterpret_cast<void *>(vm_addr);
- SIZE_T bytes_read = 0;
- if (!ReadProcessMemory(process.GetNativeProcess().GetSystemHandle(), addr,
- buf, size, &bytes_read)) {
- // Reading from the process can fail for a number of reasons - set the
- // error code and make sure that the number of bytes read is set back to 0
- // because in some scenarios the value of bytes_read returned from the API
- // is garbage.
- error.SetError(GetLastError(), eErrorTypeWin32);
- LLDB_LOG(log, "reading failed with error: {0}", error);
- bytes_read = 0;
- }
- return bytes_read;
-}
-
-size_t ProcessWindows::DoWriteMemory(lldb::addr_t vm_addr, const void *buf,
- size_t size, Status &error) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
- llvm::sys::ScopedLock lock(m_mutex);
- LLDB_LOG(log, "attempting to write {0} bytes into address {1:x}", size,
- vm_addr);
-
- if (!m_session_data) {
- LLDB_LOG(log, "cannot write, there is no active debugger connection.");
- return 0;
- }
-
- HostProcess process = m_session_data->m_debugger->GetProcess();
- void *addr = reinterpret_cast<void *>(vm_addr);
- SIZE_T bytes_written = 0;
- lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
- if (WriteProcessMemory(handle, addr, buf, size, &bytes_written))
- FlushInstructionCache(handle, addr, bytes_written);
- else {
- error.SetError(GetLastError(), eErrorTypeWin32);
- LLDB_LOG(log, "writing failed with error: {0}", error);
- }
- return bytes_written;
-}
-
-lldb::addr_t ProcessWindows::DoAllocateMemory(size_t size, uint32_t permissions,
- Status &error) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
- llvm::sys::ScopedLock lock(m_mutex);
- LLDB_LOG(log, "attempting to allocate {0} bytes with permissions {1}", size,
- permissions);
-
- if (!m_session_data) {
- LLDB_LOG(log, "cannot allocate, there is no active debugger connection.");
- error.SetErrorString(
- "cannot allocate, there is no active debugger connection");
- return LLDB_INVALID_ADDRESS;
- }
-
- HostProcess process = m_session_data->m_debugger->GetProcess();
- lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
- auto protect = ConvertLldbToWinApiProtect(permissions);
- auto result = VirtualAllocEx(handle, nullptr, size, MEM_COMMIT, protect);
- if (!result) {
- error.SetError(GetLastError(), eErrorTypeWin32);
- LLDB_LOG(log, "allocating failed with error: {0}", error);
- return LLDB_INVALID_ADDRESS;
- }
-
- return reinterpret_cast<addr_t>(result);
-}
-
-Status ProcessWindows::DoDeallocateMemory(lldb::addr_t ptr) {
- Status result;
-
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
- llvm::sys::ScopedLock lock(m_mutex);
- LLDB_LOG(log, "attempting to deallocate bytes at address {0}", ptr);
-
- if (!m_session_data) {
- LLDB_LOG(log, "cannot deallocate, there is no active debugger connection.");
- result.SetErrorString(
- "cannot deallocate, there is no active debugger connection");
- return result;
- }
-
- HostProcess process = m_session_data->m_debugger->GetProcess();
- lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
- if (!VirtualFreeEx(handle, reinterpret_cast<LPVOID>(ptr), 0, MEM_RELEASE)) {
- result.SetError(GetLastError(), eErrorTypeWin32);
- LLDB_LOG(log, "deallocating failed with error: {0}", result);
- return result;
- }
-
- return result;
-}
-
-Status ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr,
- MemoryRegionInfo &info) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
- Status error;
- llvm::sys::ScopedLock lock(m_mutex);
- info.Clear();
-
- if (!m_session_data) {
- error.SetErrorString(
- "GetMemoryRegionInfo called with no debugging session.");
- LLDB_LOG(log, "error: {0}", error);
- return error;
- }
- HostProcess process = m_session_data->m_debugger->GetProcess();
- lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
- if (handle == nullptr || handle == LLDB_INVALID_PROCESS) {
- error.SetErrorString(
- "GetMemoryRegionInfo called with an invalid target process.");
- LLDB_LOG(log, "error: {0}", error);
- return error;
- }
-
- LLDB_LOG(log, "getting info for address {0:x}", vm_addr);
-
- void *addr = reinterpret_cast<void *>(vm_addr);
- MEMORY_BASIC_INFORMATION mem_info = {};
- SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info));
- if (result == 0) {
- if (::GetLastError() == ERROR_INVALID_PARAMETER) {
- // ERROR_INVALID_PARAMETER is returned if VirtualQueryEx is called with
- // an address past the highest accessible address. We should return a
- // range from the vm_addr to LLDB_INVALID_ADDRESS
- info.GetRange().SetRangeBase(vm_addr);
- info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
- info.SetReadable(MemoryRegionInfo::eNo);
- info.SetExecutable(MemoryRegionInfo::eNo);
- info.SetWritable(MemoryRegionInfo::eNo);
- info.SetMapped(MemoryRegionInfo::eNo);
- return error;
- } else {
- error.SetError(::GetLastError(), eErrorTypeWin32);
- LLDB_LOG(log,
- "VirtualQueryEx returned error {0} while getting memory "
- "region info for address {1:x}",
- error, vm_addr);
- return error;
- }
- }
-
- // Protect bits are only valid for MEM_COMMIT regions.
- if (mem_info.State == MEM_COMMIT) {
- const bool readable = IsPageReadable(mem_info.Protect);
- const bool executable = IsPageExecutable(mem_info.Protect);
- const bool writable = IsPageWritable(mem_info.Protect);
- info.SetReadable(readable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- info.SetExecutable(executable ? MemoryRegionInfo::eYes
- : MemoryRegionInfo::eNo);
- info.SetWritable(writable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
- } else {
- info.SetReadable(MemoryRegionInfo::eNo);
- info.SetExecutable(MemoryRegionInfo::eNo);
- info.SetWritable(MemoryRegionInfo::eNo);
- }
-
- // AllocationBase is defined for MEM_COMMIT and MEM_RESERVE but not MEM_FREE.
- if (mem_info.State != MEM_FREE) {
- info.GetRange().SetRangeBase(
- reinterpret_cast<addr_t>(mem_info.AllocationBase));
- info.GetRange().SetRangeEnd(reinterpret_cast<addr_t>(mem_info.BaseAddress) +
- mem_info.RegionSize);
- info.SetMapped(MemoryRegionInfo::eYes);
- } else {
- // In the unmapped case we need to return the distance to the next block of
- // memory. VirtualQueryEx nearly does that except that it gives the
- // distance from the start of the page containing vm_addr.
- SYSTEM_INFO data;
- GetSystemInfo(&data);
- DWORD page_offset = vm_addr % data.dwPageSize;
- info.GetRange().SetRangeBase(vm_addr);
- info.GetRange().SetByteSize(mem_info.RegionSize - page_offset);
- info.SetMapped(MemoryRegionInfo::eNo);
- }
-
- error.SetError(::GetLastError(), eErrorTypeWin32);
- LLDB_LOGV(log,
- "Memory region info for address {0}: readable={1}, "
- "executable={2}, writable={3}",
- vm_addr, info.GetReadable(), info.GetExecutable(),
- info.GetWritable());
- return error;
-}
-
-lldb::addr_t ProcessWindows::GetImageInfoAddress() {
- Target &target = GetTarget();
- ObjectFile *obj_file = target.GetExecutableModule()->GetObjectFile();
- Address addr = obj_file->GetImageInfoAddress(&target);
- if (addr.IsValid())
- return addr.GetLoadAddress(&target);
- else
- return LLDB_INVALID_ADDRESS;
-}
-
-void ProcessWindows::OnExitProcess(uint32_t exit_code) {
- // No need to acquire the lock since m_session_data isn't accessed.
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- LLDB_LOG(log, "Process {0} exited with code {1}", GetID(), exit_code);
-
- TargetSP target = CalculateTarget();
- if (target) {
- ModuleSP executable_module = target->GetExecutableModule();
- ModuleList unloaded_modules;
- unloaded_modules.Append(executable_module);
- target->ModulesDidUnload(unloaded_modules, true);
- }
-
- SetProcessExitStatus(GetID(), true, 0, exit_code);
- SetPrivateState(eStateExited);
-
- // If the process exits before any initial stop then notify the debugger
- // of the error otherwise WaitForDebuggerConnection() will be blocked.
- // An example of this issue is when a process fails to load a dependent DLL.
- if (m_session_data && !m_session_data->m_initial_stop_received) {
- Status error(exit_code, eErrorTypeWin32);
- OnDebuggerError(error, 0);
- }
-}
-
-void ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) {
- DebuggerThreadSP debugger = m_session_data->m_debugger;
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
- LLDB_LOG(log, "Debugger connected to process {0}. Image base = {1:x}",
- debugger->GetProcess().GetProcessId(), image_base);
-
- ModuleSP module = GetTarget().GetExecutableModule();
- if (!module) {
- // During attach, we won't have the executable module, so find it now.
- const DWORD pid = debugger->GetProcess().GetProcessId();
- const std::string file_name = GetProcessExecutableName(pid);
- if (file_name.empty()) {
- return;
- }
-
- FileSpec executable_file(file_name);
- FileSystem::Instance().Resolve(executable_file);
- ModuleSpec module_spec(executable_file);
- Status error;
- module = GetTarget().GetSharedModule(module_spec, &error);
- if (!module) {
- return;
- }
-
- GetTarget().SetExecutableModule(module, eLoadDependentsNo);
- }
-
- bool load_addr_changed;
- module->SetLoadAddress(GetTarget(), image_base, false, load_addr_changed);
-
- ModuleList loaded_modules;
- loaded_modules.Append(module);
- GetTarget().ModulesDidLoad(loaded_modules);
-
- // Add the main executable module to the list of pending module loads. We
- // can't call GetTarget().ModulesDidLoad() here because we still haven't
- // returned from DoLaunch() / DoAttach() yet so the target may not have set
- // the process instance to `this` yet.
- llvm::sys::ScopedLock lock(m_mutex);
- const HostThreadWindows &wmain_thread =
- debugger->GetMainThread().GetNativeThread();
- m_session_data->m_new_threads[wmain_thread.GetThreadId()] =
- debugger->GetMainThread();
-}
-
-ExceptionResult
-ProcessWindows::OnDebugException(bool first_chance,
- const ExceptionRecord &record) {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EXCEPTION);
- llvm::sys::ScopedLock lock(m_mutex);
-
- // FIXME: Without this check, occasionally when running the test suite there
- // is
- // an issue where m_session_data can be null. It's not clear how this could
- // happen but it only surfaces while running the test suite. In order to
- // properly diagnose this, we probably need to first figure allow the test
- // suite to print out full lldb logs, and then add logging to the process
- // plugin.
- if (!m_session_data) {
- LLDB_LOG(log,
- "Debugger thread reported exception {0:x} at address {1:x}, "
- "but there is no session.",
- record.GetExceptionCode(), record.GetExceptionAddress());
- return ExceptionResult::SendToApplication;
- }
-
- if (!first_chance) {
- // Not any second chance exception is an application crash by definition.
- // It may be an expression evaluation crash.
- SetPrivateState(eStateStopped);
- }
-
- ExceptionResult result = ExceptionResult::SendToApplication;
- switch (record.GetExceptionCode()) {
- case EXCEPTION_BREAKPOINT:
- // Handle breakpoints at the first chance.
- result = ExceptionResult::BreakInDebugger;
-
- if (!m_session_data->m_initial_stop_received) {
- LLDB_LOG(
- log,
- "Hit loader breakpoint at address {0:x}, setting initial stop event.",
- record.GetExceptionAddress());
- m_session_data->m_initial_stop_received = true;
- ::SetEvent(m_session_data->m_initial_stop_event);
- } else {
- LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.",
- record.GetExceptionAddress());
- }
- SetPrivateState(eStateStopped);
- break;
- case EXCEPTION_SINGLE_STEP:
- result = ExceptionResult::BreakInDebugger;
- SetPrivateState(eStateStopped);
- break;
- default:
- LLDB_LOG(log,
- "Debugger thread reported exception {0:x} at address {1:x} "
- "(first_chance={2})",
- record.GetExceptionCode(), record.GetExceptionAddress(),
- first_chance);
- // For non-breakpoints, give the application a chance to handle the
- // exception first.
- if (first_chance)
- result = ExceptionResult::SendToApplication;
- else
- result = ExceptionResult::BreakInDebugger;
- }
-
- return result;
-}
-
-void ProcessWindows::OnCreateThread(const HostThread &new_thread) {
- llvm::sys::ScopedLock lock(m_mutex);
- const HostThreadWindows &wnew_thread = new_thread.GetNativeThread();
- m_session_data->m_new_threads[wnew_thread.GetThreadId()] = new_thread;
-}
-
-void ProcessWindows::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) {
- llvm::sys::ScopedLock lock(m_mutex);
-
- // On a forced termination, we may get exit thread events after the session
- // data has been cleaned up.
- if (!m_session_data)
- return;
-
- // A thread may have started and exited before the debugger stopped allowing a
- // refresh.
- // Just remove it from the new threads list in that case.
- auto iter = m_session_data->m_new_threads.find(thread_id);
- if (iter != m_session_data->m_new_threads.end())
- m_session_data->m_new_threads.erase(iter);
- else
- m_session_data->m_exited_threads.insert(thread_id);
-}
-
-void ProcessWindows::OnLoadDll(const ModuleSpec &module_spec,
- lldb::addr_t module_addr) {
- // Confusingly, there is no Target::AddSharedModule. Instead, calling
- // GetSharedModule() with a new module will add it to the module list and
- // return a corresponding ModuleSP.
- Status error;
- ModuleSP module = GetTarget().GetSharedModule(module_spec, &error);
- bool load_addr_changed = false;
- module->SetLoadAddress(GetTarget(), module_addr, false, load_addr_changed);
-
- ModuleList loaded_modules;
- loaded_modules.Append(module);
- GetTarget().ModulesDidLoad(loaded_modules);
-}
-
-void ProcessWindows::OnUnloadDll(lldb::addr_t module_addr) {
- Address resolved_addr;
- if (GetTarget().ResolveLoadAddress(module_addr, resolved_addr)) {
- ModuleSP module = resolved_addr.GetModule();
- if (module) {
- ModuleList unloaded_modules;
- unloaded_modules.Append(module);
- GetTarget().ModulesDidUnload(unloaded_modules, false);
- }
- }
-}
-
-void ProcessWindows::OnDebugString(const std::string &string) {}
-
-void ProcessWindows::OnDebuggerError(const Status &error, uint32_t type) {
- llvm::sys::ScopedLock lock(m_mutex);
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
-
- if (m_session_data->m_initial_stop_received) {
- // This happened while debugging. Do we shutdown the debugging session,
- // try to continue, or do something else?
- LLDB_LOG(log,
- "Error {0} occurred during debugging. Unexpected behavior "
- "may result. {1}",
- error.GetError(), error);
- } else {
- // If we haven't actually launched the process yet, this was an error
- // launching the process. Set the internal error and signal the initial
- // stop event so that the DoLaunch method wakes up and returns a failure.
- m_session_data->m_launch_error = error;
- ::SetEvent(m_session_data->m_initial_stop_event);
- LLDB_LOG(
- log,
- "Error {0} occurred launching the process before the initial stop. {1}",
- error.GetError(), error);
- return;
- }
-}
-
-Status ProcessWindows::WaitForDebuggerConnection(DebuggerThreadSP debugger,
- HostProcess &process) {
- Status result;
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS |
- WINDOWS_LOG_BREAKPOINTS);
- LLDB_LOG(log, "Waiting for loader breakpoint.");
-
- // Block this function until we receive the initial stop from the process.
- if (::WaitForSingleObject(m_session_data->m_initial_stop_event, INFINITE) ==
- WAIT_OBJECT_0) {
- LLDB_LOG(log, "hit loader breakpoint, returning.");
-
- process = debugger->GetProcess();
- return m_session_data->m_launch_error;
- } else
- return Status(::GetLastError(), eErrorTypeWin32);
-}
-
-// The Windows page protection bits are NOT independent masks that can be
-// bitwise-ORed together. For example, PAGE_EXECUTE_READ is not (PAGE_EXECUTE
-// | PAGE_READ). To test for an access type, it's necessary to test for any of
-// the bits that provide that access type.
-bool ProcessWindows::IsPageReadable(uint32_t protect) {
- return (protect & PAGE_NOACCESS) == 0;
-}
-
-bool ProcessWindows::IsPageWritable(uint32_t protect) {
- return (protect & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY |
- PAGE_READWRITE | PAGE_WRITECOPY)) != 0;
-}
-
-bool ProcessWindows::IsPageExecutable(uint32_t protect) {
- return (protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE |
- PAGE_EXECUTE_WRITECOPY)) != 0;
-}
-
-} // namespace lldb_private
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindows.h b/source/Plugins/Process/Windows/Common/ProcessWindows.h
deleted file mode 100644
index 00e384f584080..0000000000000
--- a/source/Plugins/Process/Windows/Common/ProcessWindows.h
+++ /dev/null
@@ -1,121 +0,0 @@
-//===-- ProcessWindows.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_Plugins_Process_Windows_Common_ProcessWindows_H_
-#define liblldb_Plugins_Process_Windows_Common_ProcessWindows_H_
-
-#include "lldb/Target/Process.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/lldb-forward.h"
-
-#include "llvm/Support/Mutex.h"
-
-#include "IDebugDelegate.h"
-
-namespace lldb_private {
-
-class HostProcess;
-class ProcessWindowsData;
-
-class ProcessWindows : public Process, public IDebugDelegate {
-public:
- //------------------------------------------------------------------
- // Static functions.
- //------------------------------------------------------------------
- static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp,
- lldb::ListenerSP listener_sp,
- const FileSpec *);
-
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetPluginDescriptionStatic();
-
- //------------------------------------------------------------------
- // Constructors and destructors
- //------------------------------------------------------------------
- ProcessWindows(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
-
- ~ProcessWindows();
-
- size_t GetSTDOUT(char *buf, size_t buf_size, Status &error) override;
- size_t GetSTDERR(char *buf, size_t buf_size, Status &error) override;
- size_t PutSTDIN(const char *buf, size_t buf_size, Status &error) override;
-
- // lldb_private::Process overrides
- ConstString GetPluginName() override;
- uint32_t GetPluginVersion() override;
-
- Status EnableBreakpointSite(BreakpointSite *bp_site) override;
- Status DisableBreakpointSite(BreakpointSite *bp_site) override;
-
- Status DoDetach(bool keep_stopped) override;
- Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override;
- Status DoAttachToProcessWithID(
- lldb::pid_t pid,
- const lldb_private::ProcessAttachInfo &attach_info) override;
- Status DoResume() override;
- Status DoDestroy() override;
- Status DoHalt(bool &caused_stop) override;
-
- void DidLaunch() override;
- void DidAttach(lldb_private::ArchSpec &arch_spec) override;
-
- void RefreshStateAfterStop() override;
-
- bool CanDebug(lldb::TargetSP target_sp,
- bool plugin_specified_by_name) override;
- bool DestroyRequiresHalt() override { return false; }
- bool UpdateThreadList(ThreadList &old_thread_list,
- ThreadList &new_thread_list) override;
- bool IsAlive() override;
-
- size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
- Status &error) override;
- size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
- Status &error) override;
- lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
- Status &error) override;
- Status DoDeallocateMemory(lldb::addr_t ptr) override;
- Status GetMemoryRegionInfo(lldb::addr_t vm_addr,
- MemoryRegionInfo &info) override;
-
- lldb::addr_t GetImageInfoAddress() override;
-
- // IDebugDelegate overrides.
- void OnExitProcess(uint32_t exit_code) override;
- void OnDebuggerConnected(lldb::addr_t image_base) override;
- ExceptionResult OnDebugException(bool first_chance,
- const ExceptionRecord &record) override;
- void OnCreateThread(const HostThread &thread) override;
- void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override;
- void OnLoadDll(const ModuleSpec &module_spec,
- lldb::addr_t module_addr) override;
- void OnUnloadDll(lldb::addr_t module_addr) override;
- void OnDebugString(const std::string &string) override;
- void OnDebuggerError(const Status &error, uint32_t type) override;
-
-private:
- Status WaitForDebuggerConnection(DebuggerThreadSP debugger,
- HostProcess &process);
-
- // These decode the page protection bits.
- static bool IsPageReadable(uint32_t protect);
- static bool IsPageWritable(uint32_t protect);
- static bool IsPageExecutable(uint32_t protect);
-
- llvm::sys::Mutex m_mutex;
- std::unique_ptr<ProcessWindowsData> m_session_data;
-};
-}
-
-#endif // liblldb_Plugins_Process_Windows_Common_ProcessWindows_H_
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp b/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp
deleted file mode 100644
index 386e9a5816c5f..0000000000000
--- a/source/Plugins/Process/Windows/Common/ProcessWindowsLog.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-//===-- ProcessWindowsLog.cpp -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ProcessWindowsLog.h"
-
-using namespace lldb_private;
-
-static constexpr Log::Category g_categories[] = {
- {{"break"}, {"log breakpoints"}, WINDOWS_LOG_BREAKPOINTS},
- {{"event"}, {"log low level debugger events"}, WINDOWS_LOG_EVENT},
- {{"exception"}, {"log exception information"}, WINDOWS_LOG_EXCEPTION},
- {{"memory"}, {"log memory reads and writes"}, WINDOWS_LOG_MEMORY},
- {{"process"}, {"log process events and activities"}, WINDOWS_LOG_PROCESS},
- {{"registers"}, {"log register read/writes"}, WINDOWS_LOG_REGISTERS},
- {{"step"}, {"log step related activities"}, WINDOWS_LOG_STEP},
- {{"thread"}, {"log thread events and activities"}, WINDOWS_LOG_THREAD},
-};
-
-Log::Channel ProcessWindowsLog::g_channel(g_categories, WINDOWS_LOG_PROCESS);
-
-void ProcessWindowsLog::Initialize() {
- static llvm::once_flag g_once_flag;
- llvm::call_once(g_once_flag, []() { Log::Register("windows", g_channel); });
-}
-
-void ProcessWindowsLog::Terminate() {}
-
-
-
-
-
-
-
-
-
diff --git a/source/Plugins/Process/Windows/Common/ProcessWindowsLog.h b/source/Plugins/Process/Windows/Common/ProcessWindowsLog.h
deleted file mode 100644
index b7f59c7081431..0000000000000
--- a/source/Plugins/Process/Windows/Common/ProcessWindowsLog.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===-- ProcessWindowsLog.h -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ProcessWindowsLog_h_
-#define liblldb_ProcessWindowsLog_h_
-
-#include "lldb/Utility/Log.h"
-
-#define WINDOWS_LOG_PROCESS (1u << 1) // Log process operations
-#define WINDOWS_LOG_EXCEPTION (1u << 1) // Log exceptions
-#define WINDOWS_LOG_THREAD (1u << 2) // Log thread operations
-#define WINDOWS_LOG_MEMORY (1u << 3) // Log memory reads/writes calls
-#define WINDOWS_LOG_BREAKPOINTS (1u << 4) // Log breakpoint operations
-#define WINDOWS_LOG_STEP (1u << 5) // Log step operations
-#define WINDOWS_LOG_REGISTERS (1u << 6) // Log register operations
-#define WINDOWS_LOG_EVENT (1u << 7) // Low level debug events
-
-namespace lldb_private {
-class ProcessWindowsLog {
- static Log::Channel g_channel;
-
-public:
- static void Initialize();
- static void Terminate();
-
- static Log *GetLogIfAny(uint32_t mask) { return g_channel.GetLogIfAny(mask); }
-};
-}
-
-#endif // liblldb_ProcessWindowsLog_h_
diff --git a/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp b/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp
deleted file mode 100644
index 90d43b2cf8284..0000000000000
--- a/source/Plugins/Process/Windows/Common/RegisterContextWindows.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-//===-- RegisterContextWindows.cpp ------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/windows.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/lldb-private-types.h"
-
-#include "ProcessWindowsLog.h"
-#include "RegisterContextWindows.h"
-#include "TargetThreadWindows.h"
-
-#include "llvm/ADT/STLExtras.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-const DWORD kWinContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
-
-//------------------------------------------------------------------
-// Constructors and Destructors
-//------------------------------------------------------------------
-RegisterContextWindows::RegisterContextWindows(Thread &thread,
- uint32_t concrete_frame_idx)
- : RegisterContext(thread, concrete_frame_idx), m_context(),
- m_context_stale(true) {}
-
-RegisterContextWindows::~RegisterContextWindows() {}
-
-void RegisterContextWindows::InvalidateAllRegisters() {
- m_context_stale = true;
-}
-
-bool RegisterContextWindows::ReadAllRegisterValues(
- lldb::DataBufferSP &data_sp) {
-
- if (!CacheAllRegisterValues())
- return false;
-
- data_sp.reset(new DataBufferHeap(sizeof(CONTEXT), 0));
- memcpy(data_sp->GetBytes(), &m_context, sizeof(m_context));
-
- return true;
-}
-
-bool RegisterContextWindows::WriteAllRegisterValues(
- const lldb::DataBufferSP &data_sp) {
- assert(data_sp->GetByteSize() >= sizeof(m_context));
- memcpy(&m_context, data_sp->GetBytes(), sizeof(m_context));
-
- TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
- if (!::SetThreadContext(
- wthread.GetHostThread().GetNativeThread().GetSystemHandle(),
- &m_context))
- return false;
-
- return true;
-}
-
-uint32_t RegisterContextWindows::ConvertRegisterKindToRegisterNumber(
- lldb::RegisterKind kind, uint32_t num) {
- const uint32_t num_regs = GetRegisterCount();
-
- assert(kind < kNumRegisterKinds);
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
-
- if (reg_info->kinds[kind] == num)
- return reg_idx;
- }
-
- return LLDB_INVALID_REGNUM;
-}
-
-//------------------------------------------------------------------
-// Subclasses can these functions if desired
-//------------------------------------------------------------------
-uint32_t RegisterContextWindows::NumSupportedHardwareBreakpoints() {
- // Support for hardware breakpoints not yet implemented.
- return 0;
-}
-
-uint32_t RegisterContextWindows::SetHardwareBreakpoint(lldb::addr_t addr,
- size_t size) {
- return 0;
-}
-
-bool RegisterContextWindows::ClearHardwareBreakpoint(uint32_t hw_idx) {
- return false;
-}
-
-uint32_t RegisterContextWindows::NumSupportedHardwareWatchpoints() {
- // Support for hardware watchpoints not yet implemented.
- return 0;
-}
-
-uint32_t RegisterContextWindows::SetHardwareWatchpoint(lldb::addr_t addr,
- size_t size, bool read,
- bool write) {
- return 0;
-}
-
-bool RegisterContextWindows::ClearHardwareWatchpoint(uint32_t hw_index) {
- return false;
-}
-
-bool RegisterContextWindows::HardwareSingleStep(bool enable) { return false; }
-
-bool RegisterContextWindows::CacheAllRegisterValues() {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_REGISTERS);
- if (!m_context_stale)
- return true;
-
- TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
- memset(&m_context, 0, sizeof(m_context));
- m_context.ContextFlags = kWinContextFlags;
- if (!::GetThreadContext(
- wthread.GetHostThread().GetNativeThread().GetSystemHandle(),
- &m_context)) {
- LLDB_LOG(
- log,
- "GetThreadContext failed with error {0} while caching register values.",
- ::GetLastError());
- return false;
- }
- LLDB_LOG(log, "successfully updated the register values.");
- m_context_stale = false;
- return true;
-}
diff --git a/source/Plugins/Process/Windows/Common/RegisterContextWindows.h b/source/Plugins/Process/Windows/Common/RegisterContextWindows.h
deleted file mode 100644
index bd09295c2f238..0000000000000
--- a/source/Plugins/Process/Windows/Common/RegisterContextWindows.h
+++ /dev/null
@@ -1,67 +0,0 @@
-//===-- RegisterContextWindows.h --------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextWindows_H_
-#define liblldb_RegisterContextWindows_H_
-
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/lldb-forward.h"
-
-namespace lldb_private {
-
-class Thread;
-
-class RegisterContextWindows : public lldb_private::RegisterContext {
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RegisterContextWindows(Thread &thread, uint32_t concrete_frame_idx);
-
- virtual ~RegisterContextWindows();
-
- //------------------------------------------------------------------
- // Subclasses must override these functions
- //------------------------------------------------------------------
- void InvalidateAllRegisters() override;
-
- bool ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
-
- bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
-
- uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
- uint32_t num) override;
-
- //------------------------------------------------------------------
- // Subclasses can override these functions if desired
- //------------------------------------------------------------------
- uint32_t NumSupportedHardwareBreakpoints() override;
-
- uint32_t SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override;
-
- bool ClearHardwareBreakpoint(uint32_t hw_idx) override;
-
- uint32_t NumSupportedHardwareWatchpoints() override;
-
- uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read,
- bool write) override;
-
- bool ClearHardwareWatchpoint(uint32_t hw_index) override;
-
- bool HardwareSingleStep(bool enable) override;
-
-protected:
- virtual bool CacheAllRegisterValues();
-
- CONTEXT m_context;
- bool m_context_stale;
-};
-}
-
-#endif // #ifndef liblldb_RegisterContextWindows_H_
diff --git a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp b/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
deleted file mode 100644
index b121dc7bf15ea..0000000000000
--- a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-//===-- TargetThreadWindows.cpp----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Host/HostNativeThreadBase.h"
-#include "lldb/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/windows.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Logging.h"
-#include "lldb/Utility/State.h"
-
-#include "Plugins/Process/Utility/UnwindLLDB.h"
-#include "ProcessWindows.h"
-#include "ProcessWindowsLog.h"
-#include "TargetThreadWindows.h"
-
-#if defined(_WIN64)
-#include "x64/RegisterContextWindows_x64.h"
-#else
-#include "x86/RegisterContextWindows_x86.h"
-#endif
-
-using namespace lldb;
-using namespace lldb_private;
-
-TargetThreadWindows::TargetThreadWindows(ProcessWindows &process,
- const HostThread &thread)
- : Thread(process, thread.GetNativeThread().GetThreadId()),
- m_thread_reg_ctx_sp(), m_host_thread(thread) {}
-
-TargetThreadWindows::~TargetThreadWindows() { DestroyThread(); }
-
-void TargetThreadWindows::RefreshStateAfterStop() {
- ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
- SetState(eStateStopped);
- GetRegisterContext()->InvalidateIfNeeded(false);
-}
-
-void TargetThreadWindows::WillResume(lldb::StateType resume_state) {}
-
-void TargetThreadWindows::DidStop() {}
-
-RegisterContextSP TargetThreadWindows::GetRegisterContext() {
- if (!m_reg_context_sp)
- m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
-
- return m_reg_context_sp;
-}
-
-RegisterContextSP
-TargetThreadWindows::CreateRegisterContextForFrame(StackFrame *frame) {
- RegisterContextSP reg_ctx_sp;
- uint32_t concrete_frame_idx = 0;
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
-
- if (frame)
- concrete_frame_idx = frame->GetConcreteFrameIndex();
-
- if (concrete_frame_idx == 0) {
- if (!m_thread_reg_ctx_sp) {
- ArchSpec arch = HostInfo::GetArchitecture();
- switch (arch.GetMachine()) {
- case llvm::Triple::x86:
-#if defined(_WIN64)
- // FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64
- LLDB_LOG(log, "This is a Wow64 process, we should create a "
- "RegisterContextWindows_Wow64, but we don't.");
-#else
- m_thread_reg_ctx_sp.reset(
- new RegisterContextWindows_x86(*this, concrete_frame_idx));
-#endif
- break;
- case llvm::Triple::x86_64:
-#if defined(_WIN64)
- m_thread_reg_ctx_sp.reset(
- new RegisterContextWindows_x64(*this, concrete_frame_idx));
-#else
- LLDB_LOG(log, "LLDB is 32-bit, but the target process is 64-bit.");
-#endif
- default:
- break;
- }
- }
- reg_ctx_sp = m_thread_reg_ctx_sp;
- } else {
- Unwind *unwinder = GetUnwinder();
- if (unwinder != nullptr)
- reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
- }
-
- return reg_ctx_sp;
-}
-
-bool TargetThreadWindows::CalculateStopInfo() {
- SetStopInfo(m_stop_info_sp);
- return true;
-}
-
-Unwind *TargetThreadWindows::GetUnwinder() {
- // FIXME: Implement an unwinder based on the Windows unwinder exposed through
- // DIA SDK.
- if (!m_unwinder_ap)
- m_unwinder_ap.reset(new UnwindLLDB(*this));
- return m_unwinder_ap.get();
-}
-
-Status TargetThreadWindows::DoResume() {
- StateType resume_state = GetTemporaryResumeState();
- StateType current_state = GetState();
- if (resume_state == current_state)
- return Status();
-
- if (resume_state == eStateStepping) {
- uint32_t flags_index =
- GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
- eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
- uint64_t flags_value =
- GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
- flags_value |= 0x100; // Set the trap flag on the CPU
- GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
- }
-
- if (resume_state == eStateStepping || resume_state == eStateRunning) {
- DWORD previous_suspend_count = 0;
- HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
- do {
- // ResumeThread returns -1 on error, or the thread's *previous* suspend
- // count on success. This means that the return value is 1 when the thread
- // was restarted. Note that DWORD is an unsigned int, so we need to
- // explicitly compare with -1.
- previous_suspend_count = ::ResumeThread(thread_handle);
-
- if (previous_suspend_count == (DWORD)-1)
- return Status(::GetLastError(), eErrorTypeWin32);
-
- } while (previous_suspend_count > 1);
- }
-
- return Status();
-}
diff --git a/source/Plugins/Process/Windows/Common/TargetThreadWindows.h b/source/Plugins/Process/Windows/Common/TargetThreadWindows.h
deleted file mode 100644
index 952c0f55b57f3..0000000000000
--- a/source/Plugins/Process/Windows/Common/TargetThreadWindows.h
+++ /dev/null
@@ -1,50 +0,0 @@
-//===-- TargetThreadWindows.h -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_Plugins_Process_Windows_TargetThreadWindows_H_
-#define liblldb_Plugins_Process_Windows_TargetThreadWindows_H_
-
-//#include "ForwardDecl.h"
-#include "lldb/Host/HostThread.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/lldb-forward.h"
-
-#include "RegisterContextWindows.h"
-
-namespace lldb_private {
-class ProcessWindows;
-class HostThread;
-class StackFrame;
-
-class TargetThreadWindows : public lldb_private::Thread {
-public:
- TargetThreadWindows(ProcessWindows &process, const HostThread &thread);
- virtual ~TargetThreadWindows();
-
- // lldb_private::Thread overrides
- void RefreshStateAfterStop() override;
- void WillResume(lldb::StateType resume_state) override;
- void DidStop() override;
- lldb::RegisterContextSP GetRegisterContext() override;
- lldb::RegisterContextSP
- CreateRegisterContextForFrame(StackFrame *frame) override;
- bool CalculateStopInfo() override;
- Unwind *GetUnwinder() override;
-
- Status DoResume();
-
- HostThread GetHostThread() const { return m_host_thread; }
-
-private:
- lldb::RegisterContextSP m_thread_reg_ctx_sp;
- HostThread m_host_thread;
-};
-} // namespace lldb_private
-
-#endif
diff --git a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
deleted file mode 100644
index 584136a6e5bb4..0000000000000
--- a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.cpp
+++ /dev/null
@@ -1,341 +0,0 @@
-//===-- RegisterContextWindows_x64.cpp --------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/windows.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/lldb-private-types.h"
-
-#include "RegisterContextWindows_x64.h"
-#include "Plugins/Process/Utility/RegisterContext_x86.h"
-#include "TargetThreadWindows.h"
-#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
-
-#include "llvm/ADT/STLExtras.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-#define DEFINE_GPR(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatHexUppercase
-#define DEFINE_GPR_BIN(reg, alt) #reg, alt, 8, 0, eEncodingUint, eFormatBinary
-
-namespace {
-
-// This enum defines the layout of the global RegisterInfo array. This is
-// necessary because lldb register sets are defined in terms of indices into
-// the register array. As such, the order of RegisterInfos defined in global
-// registers array must match the order defined here. When defining the
-// register set layouts, these values can appear in an arbitrary order, and
-// that determines the order that register values are displayed in a dump.
-enum RegisterIndex {
- eRegisterIndexRax,
- eRegisterIndexRbx,
- eRegisterIndexRcx,
- eRegisterIndexRdx,
- eRegisterIndexRdi,
- eRegisterIndexRsi,
- eRegisterIndexRbp,
- eRegisterIndexRsp,
- eRegisterIndexR8,
- eRegisterIndexR9,
- eRegisterIndexR10,
- eRegisterIndexR11,
- eRegisterIndexR12,
- eRegisterIndexR13,
- eRegisterIndexR14,
- eRegisterIndexR15,
- eRegisterIndexRip,
- eRegisterIndexRflags
-};
-
-// Array of all register information supported by Windows x86
-RegisterInfo g_register_infos[] = {
- // Macro auto defines most stuff eh_frame DWARF
- // GENERIC
- // GDB LLDB VALUE REGS INVALIDATE REGS
- // ================================ =========================
- // ====================== =========================
- // =================== ================= ========== ===============
- {DEFINE_GPR(rax, nullptr),
- {dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, lldb_rax_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(rbx, nullptr),
- {dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, lldb_rbx_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(rcx, nullptr),
- {dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG1,
- LLDB_INVALID_REGNUM, lldb_rcx_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(rdx, nullptr),
- {dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG2,
- LLDB_INVALID_REGNUM, lldb_rdx_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(rdi, nullptr),
- {dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, lldb_rdi_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(rsi, nullptr),
- {dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, lldb_rsi_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(rbp, "fp"),
- {dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP,
- LLDB_INVALID_REGNUM, lldb_rbp_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(rsp, "sp"),
- {dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP,
- LLDB_INVALID_REGNUM, lldb_rsp_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(r8, nullptr),
- {dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG3,
- LLDB_INVALID_REGNUM, lldb_r8_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(r9, nullptr),
- {dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG4,
- LLDB_INVALID_REGNUM, lldb_r9_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(r10, nullptr),
- {dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_REGNUM_GENERIC_ARG5,
- LLDB_INVALID_REGNUM, lldb_r10_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(r11, nullptr),
- {dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_REGNUM_GENERIC_ARG6,
- LLDB_INVALID_REGNUM, lldb_r11_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(r12, nullptr),
- {dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, lldb_r12_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(r13, nullptr),
- {dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, lldb_r13_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(r14, nullptr),
- {dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, lldb_r14_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(r15, nullptr),
- {dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, lldb_r15_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR(rip, "pc"),
- {dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC,
- LLDB_INVALID_REGNUM, lldb_rip_x86_64},
- nullptr,
- nullptr},
- {DEFINE_GPR_BIN(eflags, "flags"),
- {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
- LLDB_INVALID_REGNUM, lldb_rflags_x86_64},
- nullptr,
- nullptr},
-};
-
-static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
-
-// Array of lldb register numbers used to define the set of all General Purpose
-// Registers
-uint32_t g_gpr_reg_indices[] = {
- eRegisterIndexRax, eRegisterIndexRbx, eRegisterIndexRcx,
- eRegisterIndexRdx, eRegisterIndexRdi, eRegisterIndexRsi,
- eRegisterIndexRbp, eRegisterIndexRsp, eRegisterIndexR8,
- eRegisterIndexR9, eRegisterIndexR10, eRegisterIndexR11,
- eRegisterIndexR12, eRegisterIndexR13, eRegisterIndexR14,
- eRegisterIndexR15, eRegisterIndexRip, eRegisterIndexRflags};
-
-RegisterSet g_register_sets[] = {
- {"General Purpose Registers", "gpr",
- llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices},
-};
-}
-
-//------------------------------------------------------------------
-// Constructors and Destructors
-//------------------------------------------------------------------
-RegisterContextWindows_x64::RegisterContextWindows_x64(
- Thread &thread, uint32_t concrete_frame_idx)
- : RegisterContextWindows(thread, concrete_frame_idx) {}
-
-RegisterContextWindows_x64::~RegisterContextWindows_x64() {}
-
-size_t RegisterContextWindows_x64::GetRegisterCount() {
- return llvm::array_lengthof(g_register_infos);
-}
-
-const RegisterInfo *
-RegisterContextWindows_x64::GetRegisterInfoAtIndex(size_t reg) {
- if (reg < k_num_register_infos)
- return &g_register_infos[reg];
- return NULL;
-}
-
-size_t RegisterContextWindows_x64::GetRegisterSetCount() {
- return llvm::array_lengthof(g_register_sets);
-}
-
-const RegisterSet *RegisterContextWindows_x64::GetRegisterSet(size_t reg_set) {
- return &g_register_sets[reg_set];
-}
-
-bool RegisterContextWindows_x64::ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) {
- if (!CacheAllRegisterValues())
- return false;
-
- if (reg_info == nullptr)
- return false;
-
- switch (reg_info->kinds[eRegisterKindLLDB]) {
- case lldb_rax_x86_64:
- reg_value.SetUInt64(m_context.Rax);
- break;
- case lldb_rbx_x86_64:
- reg_value.SetUInt64(m_context.Rbx);
- break;
- case lldb_rcx_x86_64:
- reg_value.SetUInt64(m_context.Rcx);
- break;
- case lldb_rdx_x86_64:
- reg_value.SetUInt64(m_context.Rdx);
- break;
- case lldb_rdi_x86_64:
- reg_value.SetUInt64(m_context.Rdi);
- break;
- case lldb_rsi_x86_64:
- reg_value.SetUInt64(m_context.Rsi);
- break;
- case lldb_r8_x86_64:
- reg_value.SetUInt64(m_context.R8);
- break;
- case lldb_r9_x86_64:
- reg_value.SetUInt64(m_context.R9);
- break;
- case lldb_r10_x86_64:
- reg_value.SetUInt64(m_context.R10);
- break;
- case lldb_r11_x86_64:
- reg_value.SetUInt64(m_context.R11);
- break;
- case lldb_r12_x86_64:
- reg_value.SetUInt64(m_context.R12);
- break;
- case lldb_r13_x86_64:
- reg_value.SetUInt64(m_context.R13);
- break;
- case lldb_r14_x86_64:
- reg_value.SetUInt64(m_context.R14);
- break;
- case lldb_r15_x86_64:
- reg_value.SetUInt64(m_context.R15);
- break;
- case lldb_rbp_x86_64:
- reg_value.SetUInt64(m_context.Rbp);
- break;
- case lldb_rsp_x86_64:
- reg_value.SetUInt64(m_context.Rsp);
- break;
- case lldb_rip_x86_64:
- reg_value.SetUInt64(m_context.Rip);
- break;
- case lldb_rflags_x86_64:
- reg_value.SetUInt64(m_context.EFlags);
- break;
- }
- return true;
-}
-
-bool RegisterContextWindows_x64::WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &reg_value) {
- // Since we cannot only write a single register value to the inferior, we
- // need to make sure our cached copy of the register values are fresh.
- // Otherwise when writing EAX, for example, we may also overwrite some other
- // register with a stale value.
- if (!CacheAllRegisterValues())
- return false;
-
- switch (reg_info->kinds[eRegisterKindLLDB]) {
- case lldb_rax_x86_64:
- m_context.Rax = reg_value.GetAsUInt64();
- break;
- case lldb_rbx_x86_64:
- m_context.Rbx = reg_value.GetAsUInt64();
- break;
- case lldb_rcx_x86_64:
- m_context.Rcx = reg_value.GetAsUInt64();
- break;
- case lldb_rdx_x86_64:
- m_context.Rdx = reg_value.GetAsUInt64();
- break;
- case lldb_rdi_x86_64:
- m_context.Rdi = reg_value.GetAsUInt64();
- break;
- case lldb_rsi_x86_64:
- m_context.Rsi = reg_value.GetAsUInt64();
- break;
- case lldb_r8_x86_64:
- m_context.R8 = reg_value.GetAsUInt64();
- break;
- case lldb_r9_x86_64:
- m_context.R9 = reg_value.GetAsUInt64();
- break;
- case lldb_r10_x86_64:
- m_context.R10 = reg_value.GetAsUInt64();
- break;
- case lldb_r11_x86_64:
- m_context.R11 = reg_value.GetAsUInt64();
- break;
- case lldb_r12_x86_64:
- m_context.R12 = reg_value.GetAsUInt64();
- break;
- case lldb_r13_x86_64:
- m_context.R13 = reg_value.GetAsUInt64();
- break;
- case lldb_r14_x86_64:
- m_context.R14 = reg_value.GetAsUInt64();
- break;
- case lldb_r15_x86_64:
- m_context.R15 = reg_value.GetAsUInt64();
- break;
- case lldb_rbp_x86_64:
- m_context.Rbp = reg_value.GetAsUInt64();
- break;
- case lldb_rsp_x86_64:
- m_context.Rsp = reg_value.GetAsUInt64();
- break;
- case lldb_rip_x86_64:
- m_context.Rip = reg_value.GetAsUInt64();
- break;
- case lldb_rflags_x86_64:
- m_context.EFlags = reg_value.GetAsUInt64();
- break;
- }
-
- // Physically update the registers in the target process.
- TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
- return ::SetThreadContext(
- wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
-}
diff --git a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h b/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h
deleted file mode 100644
index 62cedc8fbab04..0000000000000
--- a/source/Plugins/Process/Windows/Common/x64/RegisterContextWindows_x64.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//===-- RegisterContextWindows_x64.h ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextWindows_x64_H_
-#define liblldb_RegisterContextWindows_x64_H_
-
-#include "RegisterContextWindows.h"
-#include "lldb/lldb-forward.h"
-
-namespace lldb_private {
-
-class Thread;
-
-class RegisterContextWindows_x64 : public RegisterContextWindows {
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RegisterContextWindows_x64(Thread &thread, uint32_t concrete_frame_idx);
-
- virtual ~RegisterContextWindows_x64();
-
- //------------------------------------------------------------------
- // Subclasses must override these functions
- //------------------------------------------------------------------
- size_t GetRegisterCount() override;
-
- const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
-
- size_t GetRegisterSetCount() override;
-
- const RegisterSet *GetRegisterSet(size_t reg_set) override;
-
- bool ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) override;
-
- bool WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &reg_value) override;
-};
-}
-
-#endif // #ifndef liblldb_RegisterContextWindows_x64_H_
diff --git a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
deleted file mode 100644
index e012f9105f31a..0000000000000
--- a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.cpp
+++ /dev/null
@@ -1,287 +0,0 @@
-//===-- RegisterContextWindows_x86.cpp --------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/windows.h"
-#include "lldb/Utility/RegisterValue.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/lldb-private-types.h"
-
-#include "ProcessWindowsLog.h"
-#include "RegisterContextWindows_x86.h"
-#include "Plugins/Process/Utility/RegisterContext_x86.h"
-#include "TargetThreadWindows.h"
-#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
-
-#include "llvm/ADT/STLExtras.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-#define DEFINE_GPR(reg, alt) #reg, alt, 4, 0, eEncodingUint, eFormatHexUppercase
-#define DEFINE_GPR_BIN(reg, alt) #reg, alt, 4, 0, eEncodingUint, eFormatBinary
-
-namespace {
-
-// This enum defines the layout of the global RegisterInfo array. This is
-// necessary because lldb register sets are defined in terms of indices into
-// the register array. As such, the order of RegisterInfos defined in global
-// registers array must match the order defined here. When defining the
-// register set layouts, these values can appear in an arbitrary order, and
-// that determines the order that register values are displayed in a dump.
-enum RegisterIndex {
- eRegisterIndexEax,
- eRegisterIndexEbx,
- eRegisterIndexEcx,
- eRegisterIndexEdx,
- eRegisterIndexEdi,
- eRegisterIndexEsi,
- eRegisterIndexEbp,
- eRegisterIndexEsp,
- eRegisterIndexEip,
- eRegisterIndexEflags
-};
-
-// Array of all register information supported by Windows x86
-RegisterInfo g_register_infos[] = {
- // Macro auto defines most stuff eh_frame DWARF
- // GENERIC GDB LLDB
- // VALUE REGS INVALIDATE REGS
- // ============================== =======================
- // =================== ========================= ===================
- // ================= ========== ===============
- {DEFINE_GPR(eax, nullptr),
- {ehframe_eax_i386, dwarf_eax_i386, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, lldb_eax_i386},
- nullptr,
- nullptr,
- nullptr,
- 0u},
- {DEFINE_GPR(ebx, nullptr),
- {ehframe_ebx_i386, dwarf_ebx_i386, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, lldb_ebx_i386},
- nullptr,
- nullptr,
- nullptr,
- 0u},
- {DEFINE_GPR(ecx, nullptr),
- {ehframe_ecx_i386, dwarf_ecx_i386, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, lldb_ecx_i386},
- nullptr,
- nullptr,
- nullptr,
- 0u},
- {DEFINE_GPR(edx, nullptr),
- {ehframe_edx_i386, dwarf_edx_i386, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, lldb_edx_i386},
- nullptr,
- nullptr,
- nullptr,
- 0u},
- {DEFINE_GPR(edi, nullptr),
- {ehframe_edi_i386, dwarf_edi_i386, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, lldb_edi_i386},
- nullptr,
- nullptr,
- nullptr,
- 0u},
- {DEFINE_GPR(esi, nullptr),
- {ehframe_esi_i386, dwarf_esi_i386, LLDB_INVALID_REGNUM,
- LLDB_INVALID_REGNUM, lldb_esi_i386},
- nullptr,
- nullptr,
- nullptr,
- 0u},
- {DEFINE_GPR(ebp, "fp"),
- {ehframe_ebp_i386, dwarf_ebp_i386, LLDB_REGNUM_GENERIC_FP,
- LLDB_INVALID_REGNUM, lldb_ebp_i386},
- nullptr,
- nullptr,
- nullptr,
- 0u},
- {DEFINE_GPR(esp, "sp"),
- {ehframe_esp_i386, dwarf_esp_i386, LLDB_REGNUM_GENERIC_SP,
- LLDB_INVALID_REGNUM, lldb_esp_i386},
- nullptr,
- nullptr,
- nullptr,
- 0u},
- {DEFINE_GPR(eip, "pc"),
- {ehframe_eip_i386, dwarf_eip_i386, LLDB_REGNUM_GENERIC_PC,
- LLDB_INVALID_REGNUM, lldb_eip_i386},
- nullptr,
- nullptr,
- nullptr,
- 0u},
- {DEFINE_GPR_BIN(eflags, "flags"),
- {ehframe_eflags_i386, dwarf_eflags_i386, LLDB_REGNUM_GENERIC_FLAGS,
- LLDB_INVALID_REGNUM, lldb_eflags_i386},
- nullptr,
- nullptr,
- nullptr,
- 0u},
-};
-static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
-
-// Array of lldb register numbers used to define the set of all General Purpose
-// Registers
-uint32_t g_gpr_reg_indices[] = {eRegisterIndexEax, eRegisterIndexEbx,
- eRegisterIndexEcx, eRegisterIndexEdx,
- eRegisterIndexEdi, eRegisterIndexEsi,
- eRegisterIndexEbp, eRegisterIndexEsp,
- eRegisterIndexEip, eRegisterIndexEflags};
-
-RegisterSet g_register_sets[] = {
- {"General Purpose Registers", "gpr",
- llvm::array_lengthof(g_gpr_reg_indices), g_gpr_reg_indices},
-};
-}
-
-//------------------------------------------------------------------
-// Constructors and Destructors
-//------------------------------------------------------------------
-RegisterContextWindows_x86::RegisterContextWindows_x86(
- Thread &thread, uint32_t concrete_frame_idx)
- : RegisterContextWindows(thread, concrete_frame_idx) {}
-
-RegisterContextWindows_x86::~RegisterContextWindows_x86() {}
-
-size_t RegisterContextWindows_x86::GetRegisterCount() {
- return llvm::array_lengthof(g_register_infos);
-}
-
-const RegisterInfo *
-RegisterContextWindows_x86::GetRegisterInfoAtIndex(size_t reg) {
- if (reg < k_num_register_infos)
- return &g_register_infos[reg];
- return NULL;
-}
-
-size_t RegisterContextWindows_x86::GetRegisterSetCount() {
- return llvm::array_lengthof(g_register_sets);
-}
-
-const RegisterSet *RegisterContextWindows_x86::GetRegisterSet(size_t reg_set) {
- return &g_register_sets[reg_set];
-}
-
-bool RegisterContextWindows_x86::ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) {
- if (!CacheAllRegisterValues())
- return false;
-
- if (reg_info == nullptr)
- return false;
-
- uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- switch (reg) {
- case lldb_eax_i386:
- return ReadRegisterHelper(CONTEXT_INTEGER, "EAX", m_context.Eax, reg_value);
- case lldb_ebx_i386:
- return ReadRegisterHelper(CONTEXT_INTEGER, "EBX", m_context.Ebx, reg_value);
- case lldb_ecx_i386:
- return ReadRegisterHelper(CONTEXT_INTEGER, "ECX", m_context.Ecx, reg_value);
- case lldb_edx_i386:
- return ReadRegisterHelper(CONTEXT_INTEGER, "EDX", m_context.Edx, reg_value);
- case lldb_edi_i386:
- return ReadRegisterHelper(CONTEXT_INTEGER, "EDI", m_context.Edi, reg_value);
- case lldb_esi_i386:
- return ReadRegisterHelper(CONTEXT_INTEGER, "ESI", m_context.Esi, reg_value);
- case lldb_ebp_i386:
- return ReadRegisterHelper(CONTEXT_CONTROL, "EBP", m_context.Ebp, reg_value);
- case lldb_esp_i386:
- return ReadRegisterHelper(CONTEXT_CONTROL, "ESP", m_context.Esp, reg_value);
- case lldb_eip_i386:
- return ReadRegisterHelper(CONTEXT_CONTROL, "EIP", m_context.Eip, reg_value);
- case lldb_eflags_i386:
- return ReadRegisterHelper(CONTEXT_CONTROL, "EFLAGS", m_context.EFlags,
- reg_value);
- default:
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_REGISTERS);
- LLDB_LOG(log, "Requested unknown register {0}", reg);
- break;
- }
- return false;
-}
-
-bool RegisterContextWindows_x86::WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &reg_value) {
- // Since we cannot only write a single register value to the inferior, we
- // need to make sure our cached copy of the register values are fresh.
- // Otherwise when writing EAX, for example, we may also overwrite some other
- // register with a stale value.
- if (!CacheAllRegisterValues())
- return false;
-
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_REGISTERS);
- uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- switch (reg) {
- case lldb_eax_i386:
- LLDB_LOG(log, "Write value {0:x} to EAX", reg_value.GetAsUInt32());
- m_context.Eax = reg_value.GetAsUInt32();
- break;
- case lldb_ebx_i386:
- LLDB_LOG(log, "Write value {0:x} to EBX", reg_value.GetAsUInt32());
- m_context.Ebx = reg_value.GetAsUInt32();
- break;
- case lldb_ecx_i386:
- LLDB_LOG(log, "Write value {0:x} to ECX", reg_value.GetAsUInt32());
- m_context.Ecx = reg_value.GetAsUInt32();
- break;
- case lldb_edx_i386:
- LLDB_LOG(log, "Write value {0:x} to EDX", reg_value.GetAsUInt32());
- m_context.Edx = reg_value.GetAsUInt32();
- break;
- case lldb_edi_i386:
- LLDB_LOG(log, "Write value {0:x} to EDI", reg_value.GetAsUInt32());
- m_context.Edi = reg_value.GetAsUInt32();
- break;
- case lldb_esi_i386:
- LLDB_LOG(log, "Write value {0:x} to ESI", reg_value.GetAsUInt32());
- m_context.Esi = reg_value.GetAsUInt32();
- break;
- case lldb_ebp_i386:
- LLDB_LOG(log, "Write value {0:x} to EBP", reg_value.GetAsUInt32());
- m_context.Ebp = reg_value.GetAsUInt32();
- break;
- case lldb_esp_i386:
- LLDB_LOG(log, "Write value {0:x} to ESP", reg_value.GetAsUInt32());
- m_context.Esp = reg_value.GetAsUInt32();
- break;
- case lldb_eip_i386:
- LLDB_LOG(log, "Write value {0:x} to EIP", reg_value.GetAsUInt32());
- m_context.Eip = reg_value.GetAsUInt32();
- break;
- case lldb_eflags_i386:
- LLDB_LOG(log, "Write value {0:x} to EFLAGS", reg_value.GetAsUInt32());
- m_context.EFlags = reg_value.GetAsUInt32();
- break;
- default:
- LLDB_LOG(log, "Write value {0:x} to unknown register {1}",
- reg_value.GetAsUInt32(), reg);
- }
-
- // Physically update the registers in the target process.
- TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
- return ::SetThreadContext(
- wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
-}
-
-bool RegisterContextWindows_x86::ReadRegisterHelper(
- DWORD flags_required, const char *reg_name, DWORD value,
- RegisterValue &reg_value) const {
- Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_REGISTERS);
- if ((m_context.ContextFlags & flags_required) != flags_required) {
- LLDB_LOG(log, "Thread context doesn't have {0}", reg_name);
- return false;
- }
- LLDB_LOG(log, "Read value {0:x} from {1}", value, reg_name);
- reg_value.SetUInt32(value);
- return true;
-}
diff --git a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h b/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h
deleted file mode 100644
index aae645fdb5a3e..0000000000000
--- a/source/Plugins/Process/Windows/Common/x86/RegisterContextWindows_x86.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//===-- RegisterContextWindows_x86.h ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterContextWindows_x86_H_
-#define liblldb_RegisterContextWindows_x86_H_
-
-#include "RegisterContextWindows.h"
-#include "lldb/lldb-forward.h"
-
-namespace lldb_private {
-
-class Thread;
-
-class RegisterContextWindows_x86 : public RegisterContextWindows {
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- RegisterContextWindows_x86(Thread &thread, uint32_t concrete_frame_idx);
-
- virtual ~RegisterContextWindows_x86();
-
- //------------------------------------------------------------------
- // Subclasses must override these functions
- //------------------------------------------------------------------
- size_t GetRegisterCount() override;
-
- const RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
-
- size_t GetRegisterSetCount() override;
-
- const RegisterSet *GetRegisterSet(size_t reg_set) override;
-
- bool ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &reg_value) override;
-
- bool WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &reg_value) override;
-
-private:
- bool ReadRegisterHelper(DWORD flags_required, const char *reg_name,
- DWORD value, RegisterValue &reg_value) const;
-};
-}
-
-#endif // #ifndef liblldb_RegisterContextWindows_x86_H_
diff --git a/source/Plugins/Process/elf-core/CMakeLists.txt b/source/Plugins/Process/elf-core/CMakeLists.txt
deleted file mode 100644
index 9b6739824c066..0000000000000
--- a/source/Plugins/Process/elf-core/CMakeLists.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-add_lldb_library(lldbPluginProcessElfCore PLUGIN
- ProcessElfCore.cpp
- ThreadElfCore.cpp
- RegisterContextPOSIXCore_arm.cpp
- RegisterContextPOSIXCore_arm64.cpp
- RegisterContextPOSIXCore_mips64.cpp
- RegisterContextPOSIXCore_powerpc.cpp
- RegisterContextPOSIXCore_ppc64le.cpp
- RegisterContextPOSIXCore_s390x.cpp
- RegisterContextPOSIXCore_x86_64.cpp
- RegisterUtilities.cpp
-
- LINK_LIBS
- lldbCore
- lldbTarget
- lldbPluginDynamicLoaderPosixDYLD
- lldbPluginObjectFileELF
- lldbPluginProcessUtility
- LINK_COMPONENTS
- BinaryFormat
- Support
- )
diff --git a/source/Plugins/Process/gdb-remote/CMakeLists.txt b/source/Plugins/Process/gdb-remote/CMakeLists.txt
deleted file mode 100644
index 4eb5291d54d5a..0000000000000
--- a/source/Plugins/Process/gdb-remote/CMakeLists.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
- include_directories(${LIBXML2_INCLUDE_DIR})
-endif()
-
-set(LLDB_PLUGINS
- lldbPluginProcessUtility
- lldbPluginPlatformMacOSX
-)
-
-if(HAVE_LIBCOMPRESSION)
- set(LIBCOMPRESSION compression)
-endif()
-
-add_lldb_library(lldbPluginProcessGDBRemote PLUGIN
- GDBRemoteClientBase.cpp
- GDBRemoteCommunication.cpp
- GDBRemoteCommunicationClient.cpp
- GDBRemoteCommunicationHistory.cpp
- GDBRemoteCommunicationReplayServer.cpp
- GDBRemoteCommunicationServer.cpp
- GDBRemoteCommunicationServerCommon.cpp
- GDBRemoteCommunicationServerLLGS.cpp
- GDBRemoteCommunicationServerPlatform.cpp
- GDBRemoteRegisterContext.cpp
- ProcessGDBRemote.cpp
- ProcessGDBRemoteLog.cpp
- ThreadGDBRemote.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbDataFormatters
- lldbHost
- lldbInterpreter
- lldbSymbol
- lldbTarget
- lldbUtility
- ${LLDB_PLUGINS}
- ${LIBCOMPRESSION}
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Process/mach-core/CMakeLists.txt b/source/Plugins/Process/mach-core/CMakeLists.txt
deleted file mode 100644
index e79cd82c92a67..0000000000000
--- a/source/Plugins/Process/mach-core/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-add_lldb_library(lldbPluginProcessMachCore PLUGIN
- ProcessMachCore.cpp
- ThreadMachCore.cpp
-
- LINK_LIBS
- lldbBreakpoint
- lldbCore
- lldbHost
- lldbSymbol
- lldbTarget
- lldbUtility
- lldbPluginDynamicLoaderDarwinKernel
- lldbPluginDynamicLoaderMacOSXDYLD
- lldbPluginObjectFileMachO
- LINK_COMPONENTS
- Support
- )
diff --git a/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/source/Plugins/Process/mach-core/ProcessMachCore.cpp
deleted file mode 100644
index 08b9f08a47f67..0000000000000
--- a/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ /dev/null
@@ -1,635 +0,0 @@
-//===-- ProcessMachCore.cpp ------------------------------------------*- C++
-//-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include <errno.h>
-#include <stdlib.h>
-
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/Threading.h"
-#include <mutex>
-
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Section.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/MemoryRegionInfo.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Utility/DataBuffer.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/State.h"
-
-#include "ProcessMachCore.h"
-#include "Plugins/Process/Utility/StopInfoMachException.h"
-#include "ThreadMachCore.h"
-
-// Needed for the plug-in names for the dynamic loaders.
-#include "lldb/Host/SafeMachO.h"
-
-#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
-#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
-#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-ConstString ProcessMachCore::GetPluginNameStatic() {
- static ConstString g_name("mach-o-core");
- return g_name;
-}
-
-const char *ProcessMachCore::GetPluginDescriptionStatic() {
- return "Mach-O core file debugging plug-in.";
-}
-
-void ProcessMachCore::Terminate() {
- PluginManager::UnregisterPlugin(ProcessMachCore::CreateInstance);
-}
-
-lldb::ProcessSP ProcessMachCore::CreateInstance(lldb::TargetSP target_sp,
- ListenerSP listener_sp,
- const FileSpec *crash_file) {
- lldb::ProcessSP process_sp;
- if (crash_file) {
- const size_t header_size = sizeof(llvm::MachO::mach_header);
- auto data_sp = FileSystem::Instance().CreateDataBuffer(
- crash_file->GetPath(), header_size, 0);
- if (data_sp && data_sp->GetByteSize() == header_size) {
- DataExtractor data(data_sp, lldb::eByteOrderLittle, 4);
-
- lldb::offset_t data_offset = 0;
- llvm::MachO::mach_header mach_header;
- if (ObjectFileMachO::ParseHeader(data, &data_offset, mach_header)) {
- if (mach_header.filetype == llvm::MachO::MH_CORE)
- process_sp.reset(
- new ProcessMachCore(target_sp, listener_sp, *crash_file));
- }
- }
- }
- return process_sp;
-}
-
-bool ProcessMachCore::CanDebug(lldb::TargetSP target_sp,
- bool plugin_specified_by_name) {
- if (plugin_specified_by_name)
- return true;
-
- // For now we are just making sure the file exists for a given module
- if (!m_core_module_sp && FileSystem::Instance().Exists(m_core_file)) {
- // Don't add the Target's architecture to the ModuleSpec - we may be
- // working with a core file that doesn't have the correct cpusubtype in the
- // header but we should still try to use it -
- // ModuleSpecList::FindMatchingModuleSpec enforces a strict arch mach.
- ModuleSpec core_module_spec(m_core_file);
- Status error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp,
- NULL, NULL, NULL));
-
- if (m_core_module_sp) {
- ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
- if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile)
- return true;
- }
- }
- return false;
-}
-
-//----------------------------------------------------------------------
-// ProcessMachCore constructor
-//----------------------------------------------------------------------
-ProcessMachCore::ProcessMachCore(lldb::TargetSP target_sp,
- ListenerSP listener_sp,
- const FileSpec &core_file)
- : Process(target_sp, listener_sp), m_core_aranges(), m_core_range_infos(),
- m_core_module_sp(), m_core_file(core_file),
- m_dyld_addr(LLDB_INVALID_ADDRESS),
- m_mach_kernel_addr(LLDB_INVALID_ADDRESS), m_dyld_plugin_name() {}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-ProcessMachCore::~ProcessMachCore() {
- Clear();
- // We need to call finalize on the process before destroying ourselves to
- // make sure all of the broadcaster cleanup goes as planned. If we destruct
- // this class, then Process::~Process() might have problems trying to fully
- // destroy the broadcaster.
- Finalize();
-}
-
-//----------------------------------------------------------------------
-// PluginInterface
-//----------------------------------------------------------------------
-ConstString ProcessMachCore::GetPluginName() { return GetPluginNameStatic(); }
-
-uint32_t ProcessMachCore::GetPluginVersion() { return 1; }
-
-bool ProcessMachCore::GetDynamicLoaderAddress(lldb::addr_t addr) {
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER |
- LIBLLDB_LOG_PROCESS));
- llvm::MachO::mach_header header;
- Status error;
- if (DoReadMemory(addr, &header, sizeof(header), error) != sizeof(header))
- return false;
- if (header.magic == llvm::MachO::MH_CIGAM ||
- header.magic == llvm::MachO::MH_CIGAM_64) {
- header.magic = llvm::ByteSwap_32(header.magic);
- header.cputype = llvm::ByteSwap_32(header.cputype);
- header.cpusubtype = llvm::ByteSwap_32(header.cpusubtype);
- header.filetype = llvm::ByteSwap_32(header.filetype);
- header.ncmds = llvm::ByteSwap_32(header.ncmds);
- header.sizeofcmds = llvm::ByteSwap_32(header.sizeofcmds);
- header.flags = llvm::ByteSwap_32(header.flags);
- }
-
- // TODO: swap header if needed...
- // printf("0x%16.16" PRIx64 ": magic = 0x%8.8x, file_type= %u\n", vaddr,
- // header.magic, header.filetype);
- if (header.magic == llvm::MachO::MH_MAGIC ||
- header.magic == llvm::MachO::MH_MAGIC_64) {
- // Check MH_EXECUTABLE to see if we can find the mach image that contains
- // the shared library list. The dynamic loader (dyld) is what contains the
- // list for user applications, and the mach kernel contains a global that
- // has the list of kexts to load
- switch (header.filetype) {
- case llvm::MachO::MH_DYLINKER:
- // printf("0x%16.16" PRIx64 ": file_type = MH_DYLINKER\n", vaddr);
- // Address of dyld "struct mach_header" in the core file
- if (log)
- log->Printf("ProcessMachCore::GetDynamicLoaderAddress found a user "
- "process dyld binary image at 0x%" PRIx64,
- addr);
- m_dyld_addr = addr;
- return true;
-
- case llvm::MachO::MH_EXECUTE:
- // printf("0x%16.16" PRIx64 ": file_type = MH_EXECUTE\n", vaddr);
- // Check MH_EXECUTABLE file types to see if the dynamic link object flag
- // is NOT set. If it isn't, then we have a mach_kernel.
- if ((header.flags & llvm::MachO::MH_DYLDLINK) == 0) {
- if (log)
- log->Printf("ProcessMachCore::GetDynamicLoaderAddress found a mach "
- "kernel binary image at 0x%" PRIx64,
- addr);
- // Address of the mach kernel "struct mach_header" in the core file.
- m_mach_kernel_addr = addr;
- return true;
- }
- break;
- }
- }
- return false;
-}
-
-//----------------------------------------------------------------------
-// Process Control
-//----------------------------------------------------------------------
-Status ProcessMachCore::DoLoadCore() {
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER |
- LIBLLDB_LOG_PROCESS));
- Status error;
- if (!m_core_module_sp) {
- error.SetErrorString("invalid core module");
- return error;
- }
-
- ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
- if (core_objfile == NULL) {
- error.SetErrorString("invalid core object file");
- return error;
- }
-
- if (core_objfile->GetNumThreadContexts() == 0) {
- error.SetErrorString("core file doesn't contain any LC_THREAD load "
- "commands, or the LC_THREAD architecture is not "
- "supported in this lldb");
- return error;
- }
-
- SectionList *section_list = core_objfile->GetSectionList();
- if (section_list == NULL) {
- error.SetErrorString("core file has no sections");
- return error;
- }
-
- const uint32_t num_sections = section_list->GetNumSections(0);
- if (num_sections == 0) {
- error.SetErrorString("core file has no sections");
- return error;
- }
-
- SetCanJIT(false);
-
- llvm::MachO::mach_header header;
- DataExtractor data(&header, sizeof(header),
- m_core_module_sp->GetArchitecture().GetByteOrder(),
- m_core_module_sp->GetArchitecture().GetAddressByteSize());
-
- bool ranges_are_sorted = true;
- addr_t vm_addr = 0;
- for (uint32_t i = 0; i < num_sections; ++i) {
- Section *section = section_list->GetSectionAtIndex(i).get();
- if (section) {
- lldb::addr_t section_vm_addr = section->GetFileAddress();
- FileRange file_range(section->GetFileOffset(), section->GetFileSize());
- VMRangeToFileOffset::Entry range_entry(
- section_vm_addr, section->GetByteSize(), file_range);
-
- if (vm_addr > section_vm_addr)
- ranges_are_sorted = false;
- vm_addr = section->GetFileAddress();
- VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
- // printf ("LC_SEGMENT[%u] arange=[0x%16.16" PRIx64 " -
- // 0x%16.16" PRIx64 "), frange=[0x%8.8x - 0x%8.8x)\n",
- // i,
- // range_entry.GetRangeBase(),
- // range_entry.GetRangeEnd(),
- // range_entry.data.GetRangeBase(),
- // range_entry.data.GetRangeEnd());
-
- if (last_entry &&
- last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
- last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase()) {
- last_entry->SetRangeEnd(range_entry.GetRangeEnd());
- last_entry->data.SetRangeEnd(range_entry.data.GetRangeEnd());
- // puts("combine");
- } else {
- m_core_aranges.Append(range_entry);
- }
- // Some core files don't fill in the permissions correctly. If that is
- // the case assume read + execute so clients don't think the memory is
- // not readable, or executable. The memory isn't writable since this
- // plug-in doesn't implement DoWriteMemory.
- uint32_t permissions = section->GetPermissions();
- if (permissions == 0)
- permissions = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
- m_core_range_infos.Append(VMRangeToPermissions::Entry(
- section_vm_addr, section->GetByteSize(), permissions));
- }
- }
- if (!ranges_are_sorted) {
- m_core_aranges.Sort();
- m_core_range_infos.Sort();
- }
-
-
- bool found_main_binary_definitively = false;
-
- addr_t objfile_binary_addr;
- UUID objfile_binary_uuid;
- if (core_objfile->GetCorefileMainBinaryInfo (objfile_binary_addr, objfile_binary_uuid))
- {
- if (objfile_binary_addr != LLDB_INVALID_ADDRESS)
- {
- m_mach_kernel_addr = objfile_binary_addr;
- found_main_binary_definitively = true;
- if (log)
- log->Printf ("ProcessMachCore::DoLoadCore: using kernel address 0x%" PRIx64
- " from LC_NOTE 'main bin spec' load command.", m_mach_kernel_addr);
- }
- }
-
- // This checks for the presence of an LC_IDENT string in a core file;
- // LC_IDENT is very obsolete and should not be used in new code, but if the
- // load command is present, let's use the contents.
- std::string corefile_identifier = core_objfile->GetIdentifierString();
- if (!found_main_binary_definitively &&
- corefile_identifier.find("Darwin Kernel") != std::string::npos) {
- UUID uuid;
- addr_t addr = LLDB_INVALID_ADDRESS;
- if (corefile_identifier.find("UUID=") != std::string::npos) {
- size_t p = corefile_identifier.find("UUID=") + strlen("UUID=");
- std::string uuid_str = corefile_identifier.substr(p, 36);
- uuid.SetFromStringRef(uuid_str);
- }
- if (corefile_identifier.find("stext=") != std::string::npos) {
- size_t p = corefile_identifier.find("stext=") + strlen("stext=");
- if (corefile_identifier[p] == '0' && corefile_identifier[p + 1] == 'x') {
- errno = 0;
- addr = ::strtoul(corefile_identifier.c_str() + p, NULL, 16);
- if (errno != 0 || addr == 0)
- addr = LLDB_INVALID_ADDRESS;
- }
- }
- if (uuid.IsValid() && addr != LLDB_INVALID_ADDRESS) {
- m_mach_kernel_addr = addr;
- found_main_binary_definitively = true;
- if (log)
- log->Printf(
- "ProcessMachCore::DoLoadCore: Using the kernel address 0x%" PRIx64
- " from LC_IDENT/LC_NOTE 'kern ver str' string: '%s'",
- addr, corefile_identifier.c_str());
- }
- }
-
- if (!found_main_binary_definitively &&
- (m_dyld_addr == LLDB_INVALID_ADDRESS ||
- m_mach_kernel_addr == LLDB_INVALID_ADDRESS)) {
- // We need to locate the main executable in the memory ranges we have in
- // the core file. We need to search for both a user-process dyld binary
- // and a kernel binary in memory; we must look at all the pages in the
- // binary so we don't miss one or the other. Step through all memory
- // segments searching for a kernel binary and for a user process dyld --
- // we'll decide which to prefer later if both are present.
-
- const size_t num_core_aranges = m_core_aranges.GetSize();
- for (size_t i = 0; i < num_core_aranges; ++i) {
- const VMRangeToFileOffset::Entry *entry =
- m_core_aranges.GetEntryAtIndex(i);
- lldb::addr_t section_vm_addr_start = entry->GetRangeBase();
- lldb::addr_t section_vm_addr_end = entry->GetRangeEnd();
- for (lldb::addr_t section_vm_addr = section_vm_addr_start;
- section_vm_addr < section_vm_addr_end; section_vm_addr += 0x1000) {
- GetDynamicLoaderAddress(section_vm_addr);
- }
- }
- }
-
- if (!found_main_binary_definitively &&
- m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
- // In the case of multiple kernel images found in the core file via
- // exhaustive search, we may not pick the correct one. See if the
- // DynamicLoaderDarwinKernel's search heuristics might identify the correct
- // one. Most of the time, I expect the address from SearchForDarwinKernel()
- // will be the same as the address we found via exhaustive search.
-
- if (!GetTarget().GetArchitecture().IsValid() && m_core_module_sp.get()) {
- GetTarget().SetArchitecture(m_core_module_sp->GetArchitecture());
- }
-
- // SearchForDarwinKernel will end up calling back into this this class in
- // the GetImageInfoAddress method which will give it the
- // m_mach_kernel_addr/m_dyld_addr it already has. Save that aside and set
- // m_mach_kernel_addr/m_dyld_addr to an invalid address temporarily so
- // DynamicLoaderDarwinKernel does a real search for the kernel using its
- // own heuristics.
-
- addr_t saved_mach_kernel_addr = m_mach_kernel_addr;
- addr_t saved_user_dyld_addr = m_dyld_addr;
- m_mach_kernel_addr = LLDB_INVALID_ADDRESS;
- m_dyld_addr = LLDB_INVALID_ADDRESS;
-
- addr_t better_kernel_address =
- DynamicLoaderDarwinKernel::SearchForDarwinKernel(this);
-
- m_mach_kernel_addr = saved_mach_kernel_addr;
- m_dyld_addr = saved_user_dyld_addr;
-
- if (better_kernel_address != LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("ProcessMachCore::DoLoadCore: Using the kernel address "
- "from DynamicLoaderDarwinKernel");
- m_mach_kernel_addr = better_kernel_address;
- }
- }
-
- // If we found both a user-process dyld and a kernel binary, we need to
- // decide which to prefer.
- if (GetCorefilePreference() == eKernelCorefile) {
- if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("ProcessMachCore::DoLoadCore: Using kernel corefile image "
- "at 0x%" PRIx64,
- m_mach_kernel_addr);
- m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
- } else if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("ProcessMachCore::DoLoadCore: Using user process dyld "
- "image at 0x%" PRIx64,
- m_dyld_addr);
- m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
- }
- } else {
- if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("ProcessMachCore::DoLoadCore: Using user process dyld "
- "image at 0x%" PRIx64,
- m_dyld_addr);
- m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
- } else if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
- if (log)
- log->Printf("ProcessMachCore::DoLoadCore: Using kernel corefile image "
- "at 0x%" PRIx64,
- m_mach_kernel_addr);
- m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
- }
- }
-
- if (m_dyld_plugin_name != DynamicLoaderMacOSXDYLD::GetPluginNameStatic()) {
- // For non-user process core files, the permissions on the core file
- // segments are usually meaningless, they may be just "read", because we're
- // dealing with kernel coredumps or early startup coredumps and the dumper
- // is grabbing pages of memory without knowing what they are. If they
- // aren't marked as "exeuctable", that can break the unwinder which will
- // check a pc value to see if it is in an executable segment and stop the
- // backtrace early if it is not ("executable" and "unknown" would both be
- // fine, but "not executable" will break the unwinder).
- size_t core_range_infos_size = m_core_range_infos.GetSize();
- for (size_t i = 0; i < core_range_infos_size; i++) {
- VMRangeToPermissions::Entry *ent =
- m_core_range_infos.GetMutableEntryAtIndex(i);
- ent->data = lldb::ePermissionsReadable | lldb::ePermissionsExecutable;
- }
- }
-
- // Even if the architecture is set in the target, we need to override it to
- // match the core file which is always single arch.
- ArchSpec arch(m_core_module_sp->GetArchitecture());
- if (arch.GetCore() == ArchSpec::eCore_x86_32_i486) {
- arch = Platform::GetAugmentedArchSpec(GetTarget().GetPlatform().get(), "i386");
- }
- if (arch.IsValid())
- GetTarget().SetArchitecture(arch);
-
- return error;
-}
-
-lldb_private::DynamicLoader *ProcessMachCore::GetDynamicLoader() {
- if (m_dyld_ap.get() == NULL)
- m_dyld_ap.reset(DynamicLoader::FindPlugin(
- this,
- m_dyld_plugin_name.IsEmpty() ? NULL : m_dyld_plugin_name.GetCString()));
- return m_dyld_ap.get();
-}
-
-bool ProcessMachCore::UpdateThreadList(ThreadList &old_thread_list,
- ThreadList &new_thread_list) {
- if (old_thread_list.GetSize(false) == 0) {
- // Make up the thread the first time this is called so we can setup our one
- // and only core thread state.
- ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
-
- if (core_objfile) {
- const uint32_t num_threads = core_objfile->GetNumThreadContexts();
- for (lldb::tid_t tid = 0; tid < num_threads; ++tid) {
- ThreadSP thread_sp(new ThreadMachCore(*this, tid));
- new_thread_list.AddThread(thread_sp);
- }
- }
- } else {
- const uint32_t num_threads = old_thread_list.GetSize(false);
- for (uint32_t i = 0; i < num_threads; ++i)
- new_thread_list.AddThread(old_thread_list.GetThreadAtIndex(i, false));
- }
- return new_thread_list.GetSize(false) > 0;
-}
-
-void ProcessMachCore::RefreshStateAfterStop() {
- // Let all threads recover from stopping and do any clean up based on the
- // previous thread state (if any).
- m_thread_list.RefreshStateAfterStop();
- // SetThreadStopInfo (m_last_stop_packet);
-}
-
-Status ProcessMachCore::DoDestroy() { return Status(); }
-
-//------------------------------------------------------------------
-// Process Queries
-//------------------------------------------------------------------
-
-bool ProcessMachCore::IsAlive() { return true; }
-
-bool ProcessMachCore::WarnBeforeDetach() const { return false; }
-
-//------------------------------------------------------------------
-// Process Memory
-//------------------------------------------------------------------
-size_t ProcessMachCore::ReadMemory(addr_t addr, void *buf, size_t size,
- Status &error) {
- // Don't allow the caching that lldb_private::Process::ReadMemory does since
- // in core files we have it all cached our our core file anyway.
- return DoReadMemory(addr, buf, size, error);
-}
-
-size_t ProcessMachCore::DoReadMemory(addr_t addr, void *buf, size_t size,
- Status &error) {
- ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
- size_t bytes_read = 0;
-
- if (core_objfile) {
- //----------------------------------------------------------------------
- // Segments are not always contiguous in mach-o core files. We have core
- // files that have segments like:
- // Address Size File off File size
- // ---------- ---------- ---------- ----------
- // LC_SEGMENT 0x000f6000 0x00001000 0x1d509ee8 0x00001000 --- --- 0
- // 0x00000000 __TEXT LC_SEGMENT 0x0f600000 0x00100000 0x1d50aee8 0x00100000
- // --- --- 0 0x00000000 __TEXT LC_SEGMENT 0x000f7000 0x00001000
- // 0x1d60aee8 0x00001000 --- --- 0 0x00000000 __TEXT
- //
- // Any if the user executes the following command:
- //
- // (lldb) mem read 0xf6ff0
- //
- // We would attempt to read 32 bytes from 0xf6ff0 but would only get 16
- // unless we loop through consecutive memory ranges that are contiguous in
- // the address space, but not in the file data.
- //----------------------------------------------------------------------
- while (bytes_read < size) {
- const addr_t curr_addr = addr + bytes_read;
- const VMRangeToFileOffset::Entry *core_memory_entry =
- m_core_aranges.FindEntryThatContains(curr_addr);
-
- if (core_memory_entry) {
- const addr_t offset = curr_addr - core_memory_entry->GetRangeBase();
- const addr_t bytes_left = core_memory_entry->GetRangeEnd() - curr_addr;
- const size_t bytes_to_read =
- std::min(size - bytes_read, (size_t)bytes_left);
- const size_t curr_bytes_read = core_objfile->CopyData(
- core_memory_entry->data.GetRangeBase() + offset, bytes_to_read,
- (char *)buf + bytes_read);
- if (curr_bytes_read == 0)
- break;
- bytes_read += curr_bytes_read;
- } else {
- // Only set the error if we didn't read any bytes
- if (bytes_read == 0)
- error.SetErrorStringWithFormat(
- "core file does not contain 0x%" PRIx64, curr_addr);
- break;
- }
- }
- }
-
- return bytes_read;
-}
-
-Status ProcessMachCore::GetMemoryRegionInfo(addr_t load_addr,
- MemoryRegionInfo &region_info) {
- region_info.Clear();
- const VMRangeToPermissions::Entry *permission_entry =
- m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
- if (permission_entry) {
- if (permission_entry->Contains(load_addr)) {
- region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
- region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
- const Flags permissions(permission_entry->data);
- region_info.SetReadable(permissions.Test(ePermissionsReadable)
- ? MemoryRegionInfo::eYes
- : MemoryRegionInfo::eNo);
- region_info.SetWritable(permissions.Test(ePermissionsWritable)
- ? MemoryRegionInfo::eYes
- : MemoryRegionInfo::eNo);
- region_info.SetExecutable(permissions.Test(ePermissionsExecutable)
- ? MemoryRegionInfo::eYes
- : MemoryRegionInfo::eNo);
- region_info.SetMapped(MemoryRegionInfo::eYes);
- } else if (load_addr < permission_entry->GetRangeBase()) {
- region_info.GetRange().SetRangeBase(load_addr);
- region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
- region_info.SetReadable(MemoryRegionInfo::eNo);
- region_info.SetWritable(MemoryRegionInfo::eNo);
- region_info.SetExecutable(MemoryRegionInfo::eNo);
- region_info.SetMapped(MemoryRegionInfo::eNo);
- }
- return Status();
- }
-
- region_info.GetRange().SetRangeBase(load_addr);
- region_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
- region_info.SetReadable(MemoryRegionInfo::eNo);
- region_info.SetWritable(MemoryRegionInfo::eNo);
- region_info.SetExecutable(MemoryRegionInfo::eNo);
- region_info.SetMapped(MemoryRegionInfo::eNo);
- return Status();
-}
-
-void ProcessMachCore::Clear() { m_thread_list.Clear(); }
-
-void ProcessMachCore::Initialize() {
- static llvm::once_flag g_once_flag;
-
- llvm::call_once(g_once_flag, []() {
- PluginManager::RegisterPlugin(GetPluginNameStatic(),
- GetPluginDescriptionStatic(), CreateInstance);
- });
-}
-
-addr_t ProcessMachCore::GetImageInfoAddress() {
- // If we found both a user-process dyld and a kernel binary, we need to
- // decide which to prefer.
- if (GetCorefilePreference() == eKernelCorefile) {
- if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
- return m_mach_kernel_addr;
- }
- return m_dyld_addr;
- } else {
- if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
- return m_dyld_addr;
- }
- return m_mach_kernel_addr;
- }
-}
-
-lldb_private::ObjectFile *ProcessMachCore::GetCoreObjectFile() {
- return m_core_module_sp->GetObjectFile();
-}
diff --git a/source/Plugins/Process/mach-core/ProcessMachCore.h b/source/Plugins/Process/mach-core/ProcessMachCore.h
deleted file mode 100644
index 0c6fc693a50c5..0000000000000
--- a/source/Plugins/Process/mach-core/ProcessMachCore.h
+++ /dev/null
@@ -1,149 +0,0 @@
-//===-- ProcessMachCore.h ---------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ProcessMachCore_h_
-#define liblldb_ProcessMachCore_h_
-
-#include <list>
-#include <vector>
-
-#include "lldb/Target/Process.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/Status.h"
-
-class ThreadKDP;
-
-class ProcessMachCore : public lldb_private::Process {
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- ProcessMachCore(lldb::TargetSP target_sp, lldb::ListenerSP listener,
- const lldb_private::FileSpec &core_file);
-
- ~ProcessMachCore() override;
-
- static lldb::ProcessSP
- CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener,
- const lldb_private::FileSpec *crash_file_path);
-
- static void Initialize();
-
- static void Terminate();
-
- static lldb_private::ConstString GetPluginNameStatic();
-
- static const char *GetPluginDescriptionStatic();
-
- //------------------------------------------------------------------
- // Check if a given Process
- //------------------------------------------------------------------
- bool CanDebug(lldb::TargetSP target_sp,
- bool plugin_specified_by_name) override;
-
- //------------------------------------------------------------------
- // Creating a new process, or attaching to an existing one
- //------------------------------------------------------------------
- lldb_private::Status DoLoadCore() override;
-
- lldb_private::DynamicLoader *GetDynamicLoader() override;
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- lldb_private::ConstString GetPluginName() override;
-
- uint32_t GetPluginVersion() override;
-
- //------------------------------------------------------------------
- // Process Control
- //------------------------------------------------------------------
- lldb_private::Status DoDestroy() override;
-
- void RefreshStateAfterStop() override;
-
- //------------------------------------------------------------------
- // Process Queries
- //------------------------------------------------------------------
- bool IsAlive() override;
-
- bool WarnBeforeDetach() const override;
-
- //------------------------------------------------------------------
- // Process Memory
- //------------------------------------------------------------------
- size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size,
- lldb_private::Status &error) override;
-
- size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
- lldb_private::Status &error) override;
-
- lldb_private::Status
- GetMemoryRegionInfo(lldb::addr_t load_addr,
- lldb_private::MemoryRegionInfo &region_info) override;
-
- lldb::addr_t GetImageInfoAddress() override;
-
-protected:
- friend class ThreadMachCore;
-
- void Clear();
-
- bool UpdateThreadList(lldb_private::ThreadList &old_thread_list,
- lldb_private::ThreadList &new_thread_list) override;
-
- lldb_private::ObjectFile *GetCoreObjectFile();
-
-private:
- bool GetDynamicLoaderAddress(lldb::addr_t addr);
-
- typedef enum CorefilePreference {
- eUserProcessCorefile,
- eKernelCorefile
- } CorefilePreferences;
-
- //------------------------------------------------------------------
- /// If a core file can be interpreted multiple ways, this establishes
- /// which style wins.
- ///
- /// If a core file contains both a kernel binary and a user-process
- /// dynamic loader, lldb needs to pick one over the other. This could
- /// be a kernel corefile that happens to have a copy of dyld in its
- /// memory. Or it could be a user process coredump of lldb while doing
- /// kernel debugging - so a copy of the kernel is in its heap. This
- /// should become a setting so it can be over-ridden when necessary.
- //------------------------------------------------------------------
- CorefilePreference GetCorefilePreference() {
- // For now, if both user process and kernel binaries a present,
- // assume this is a kernel coredump which has a copy of a user
- // process dyld in one of its pages.
- return eKernelCorefile;
- }
-
- //------------------------------------------------------------------
- // For ProcessMachCore only
- //------------------------------------------------------------------
- typedef lldb_private::Range<lldb::addr_t, lldb::addr_t> FileRange;
- typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, FileRange>
- VMRangeToFileOffset;
- typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t>
- VMRangeToPermissions;
-
- VMRangeToFileOffset m_core_aranges;
- VMRangeToPermissions m_core_range_infos;
- lldb::ModuleSP m_core_module_sp;
- lldb_private::FileSpec m_core_file;
- lldb::addr_t m_dyld_addr;
- lldb::addr_t m_mach_kernel_addr;
- lldb_private::ConstString m_dyld_plugin_name;
-
- DISALLOW_COPY_AND_ASSIGN(ProcessMachCore);
-};
-
-#endif // liblldb_ProcessMachCore_h_
diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.cpp b/source/Plugins/Process/mach-core/ThreadMachCore.cpp
deleted file mode 100644
index 16edd28f1a132..0000000000000
--- a/source/Plugins/Process/mach-core/ThreadMachCore.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-//===-- ThreadMachCore.cpp --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ThreadMachCore.h"
-
-#include "lldb/Breakpoint/Watchpoint.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/StopInfo.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Unwind.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/DataExtractor.h"
-#include "lldb/Utility/State.h"
-#include "lldb/Utility/StreamString.h"
-
-#include "ProcessMachCore.h"
-//#include "RegisterContextKDP_arm.h"
-//#include "RegisterContextKDP_i386.h"
-//#include "RegisterContextKDP_x86_64.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-//----------------------------------------------------------------------
-// Thread Registers
-//----------------------------------------------------------------------
-
-ThreadMachCore::ThreadMachCore(Process &process, lldb::tid_t tid)
- : Thread(process, tid), m_thread_name(), m_dispatch_queue_name(),
- m_thread_dispatch_qaddr(LLDB_INVALID_ADDRESS), m_thread_reg_ctx_sp() {}
-
-ThreadMachCore::~ThreadMachCore() { DestroyThread(); }
-
-const char *ThreadMachCore::GetName() {
- if (m_thread_name.empty())
- return nullptr;
- return m_thread_name.c_str();
-}
-
-void ThreadMachCore::RefreshStateAfterStop() {
- // Invalidate all registers in our register context. We don't set "force" to
- // true because the stop reply packet might have had some register values
- // that were expedited and these will already be copied into the register
- // context by the time this function gets called. The KDPRegisterContext
- // class has been made smart enough to detect when it needs to invalidate
- // which registers are valid by putting hooks in the register read and
- // register supply functions where they check the process stop ID and do the
- // right thing.
- const bool force = false;
- GetRegisterContext()->InvalidateIfNeeded(force);
-}
-
-bool ThreadMachCore::ThreadIDIsValid(lldb::tid_t thread) { return thread != 0; }
-
-lldb::RegisterContextSP ThreadMachCore::GetRegisterContext() {
- if (!m_reg_context_sp)
- m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
- return m_reg_context_sp;
-}
-
-lldb::RegisterContextSP
-ThreadMachCore::CreateRegisterContextForFrame(StackFrame *frame) {
- lldb::RegisterContextSP reg_ctx_sp;
- uint32_t concrete_frame_idx = 0;
-
- if (frame)
- concrete_frame_idx = frame->GetConcreteFrameIndex();
-
- if (concrete_frame_idx == 0) {
- if (!m_thread_reg_ctx_sp) {
- ProcessSP process_sp(GetProcess());
-
- ObjectFile *core_objfile =
- static_cast<ProcessMachCore *>(process_sp.get())->GetCoreObjectFile();
- if (core_objfile)
- m_thread_reg_ctx_sp =
- core_objfile->GetThreadContextAtIndex(GetID(), *this);
- }
- reg_ctx_sp = m_thread_reg_ctx_sp;
- } else {
- Unwind *unwinder = GetUnwinder();
- if (unwinder != nullptr)
- reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame);
- }
- return reg_ctx_sp;
-}
-
-bool ThreadMachCore::CalculateStopInfo() {
- ProcessSP process_sp(GetProcess());
- if (process_sp) {
- SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, SIGSTOP));
- return true;
- }
- return false;
-}
diff --git a/source/Plugins/Process/mach-core/ThreadMachCore.h b/source/Plugins/Process/mach-core/ThreadMachCore.h
deleted file mode 100644
index 696ba7294e4aa..0000000000000
--- a/source/Plugins/Process/mach-core/ThreadMachCore.h
+++ /dev/null
@@ -1,70 +0,0 @@
-//===-- ThreadMachCore.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ThreadMachCore_h_
-#define liblldb_ThreadMachCore_h_
-
-#include <string>
-
-#include "lldb/Target/Thread.h"
-
-class ProcessMachCore;
-
-class ThreadMachCore : public lldb_private::Thread {
-public:
- ThreadMachCore(lldb_private::Process &process, lldb::tid_t tid);
-
- ~ThreadMachCore() override;
-
- void RefreshStateAfterStop() override;
-
- const char *GetName() override;
-
- lldb::RegisterContextSP GetRegisterContext() override;
-
- lldb::RegisterContextSP
- CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
-
- static bool ThreadIDIsValid(lldb::tid_t thread);
-
- bool ShouldStop(bool &step_more);
-
- const char *GetBasicInfoAsString();
-
- void SetName(const char *name) override {
- if (name && name[0])
- m_thread_name.assign(name);
- else
- m_thread_name.clear();
- }
-
- lldb::addr_t GetThreadDispatchQAddr() { return m_thread_dispatch_qaddr; }
-
- void SetThreadDispatchQAddr(lldb::addr_t thread_dispatch_qaddr) {
- m_thread_dispatch_qaddr = thread_dispatch_qaddr;
- }
-
-protected:
- friend class ProcessMachCore;
-
- //------------------------------------------------------------------
- // Member variables.
- //------------------------------------------------------------------
- std::string m_thread_name;
- std::string m_dispatch_queue_name;
- lldb::addr_t m_thread_dispatch_qaddr;
- lldb::RegisterContextSP m_thread_reg_ctx_sp;
-
- //------------------------------------------------------------------
- // Protected member functions.
- //------------------------------------------------------------------
- bool CalculateStopInfo() override;
-};
-
-#endif // liblldb_ThreadMachCore_h_
diff --git a/source/Plugins/Process/minidump/CMakeLists.txt b/source/Plugins/Process/minidump/CMakeLists.txt
deleted file mode 100644
index 4126a7ea991c2..0000000000000
--- a/source/Plugins/Process/minidump/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-add_lldb_library(lldbPluginProcessMinidump PLUGIN
- MinidumpTypes.cpp
- MinidumpParser.cpp
- RegisterContextMinidump_ARM.cpp
- RegisterContextMinidump_ARM64.cpp
- RegisterContextMinidump_x86_32.cpp
- RegisterContextMinidump_x86_64.cpp
- ProcessMinidump.cpp
- ThreadMinidump.cpp
-
- LINK_LIBS
- lldbCore
- lldbTarget
- lldbUtility
- lldbPluginProcessUtility
- lldbPluginProcessElfCore
- LINK_COMPONENTS
- Support
- )