diff options
| author | Bill Wendling <isanbard@gmail.com> | 2012-04-18 21:39:23 +0000 |
|---|---|---|
| committer | Bill Wendling <isanbard@gmail.com> | 2012-04-18 21:39:23 +0000 |
| commit | 392e4fbdd9b152efff4c051286f6b2c21270c902 (patch) | |
| tree | 4ac339be2c4c7c596f068b59d5e512b157c7b433 /lldb/source/Plugins/Process | |
| parent | eb1c2bdc1f55fbc5d1e7bb86e9f0e038b0f5adb7 (diff) | |
Creating release_31 branchllvmorg-3.1.0-rc1
llvm-svn: 155059
llvm-svn: 155053
llvm-svn: 155051
Diffstat (limited to 'lldb/source/Plugins/Process')
99 files changed, 0 insertions, 31238 deletions
diff --git a/lldb/source/Plugins/Process/FreeBSD/Makefile b/lldb/source/Plugins/Process/FreeBSD/Makefile deleted file mode 100644 index 8d16a4a2b4c2..000000000000 --- a/lldb/source/Plugins/Process/FreeBSD/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -##===- source/Plugins/Process/FreeBSD/Makefile ---------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLDB_LEVEL := ../../../.. -LIBRARYNAME := lldbPluginProcessFreeBSD -BUILD_ARCHIVE = 1 - -# Extend the include path so we may locate UnwindLLDB.h -CPPFLAGS += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Utility - -include $(LLDB_LEVEL)/Makefile diff --git a/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp deleted file mode 100644 index 19e332e2a51a..000000000000 --- a/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp +++ /dev/null @@ -1,137 +0,0 @@ -//===-- ProcessFreeBSD.cpp ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -#include <errno.h> - -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" -#include "lldb/Host/Host.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Target/DynamicLoader.h" -#include "lldb/Target/Target.h" - -#include "ProcessFreeBSD.h" -#include "ProcessPOSIXLog.h" -#include "Plugins/Process/Utility/InferiorCallPOSIX.h" -#include "ProcessMonitor.h" -#include "POSIXThread.h" - -using namespace lldb; -using namespace lldb_private; - -//------------------------------------------------------------------------------ -// Static functions. - -lldb::ProcessSP -ProcessFreeBSD::CreateInstance(Target& target, - Listener &listener, - const FileSpec *crash_file_path) -{ - lldb::ProcessSP process_sp; - if (crash_file_path == NULL) - process_sp.reset(new ProcessFreeBSD (target, listener)); - return process_sp; -} - -void -ProcessFreeBSD::Initialize() -{ - static bool g_initialized = false; - - if (!g_initialized) - { - PluginManager::RegisterPlugin(GetPluginNameStatic(), - GetPluginDescriptionStatic(), - CreateInstance); - Log::Callbacks log_callbacks = { - ProcessPOSIXLog::DisableLog, - ProcessPOSIXLog::EnableLog, - ProcessPOSIXLog::ListLogCategories - }; - - Log::RegisterLogChannel (ProcessFreeBSD::GetPluginNameStatic(), log_callbacks); - ProcessPOSIXLog::RegisterPluginName(GetPluginNameStatic()); - g_initialized = true; - } -} - -const char * -ProcessFreeBSD::GetPluginNameStatic() -{ - return "freebsd"; -} - -const char * -ProcessFreeBSD::GetPluginDescriptionStatic() -{ - return "Process plugin for FreeBSD"; -} - -//------------------------------------------------------------------------------ -// ProcessInterface protocol. - -const char * -ProcessFreeBSD::GetPluginName() -{ - return "process.freebsd"; -} - -const char * -ProcessFreeBSD::GetShortPluginName() -{ - return "process.freebsd"; -} - -uint32_t -ProcessFreeBSD::GetPluginVersion() -{ - return 1; -} - -void -ProcessFreeBSD::GetPluginCommandHelp(const char *command, Stream *strm) -{ -} - -Error -ProcessFreeBSD::ExecutePluginCommand(Args &command, Stream *strm) -{ - return Error(1, eErrorTypeGeneric); -} - -Log * -ProcessFreeBSD::EnablePluginLogging(Stream *strm, Args &command) -{ - return NULL; -} - -//------------------------------------------------------------------------------ -// Constructors and destructors. - -ProcessFreeBSD::ProcessFreeBSD(Target& target, Listener &listener) - : ProcessPOSIX(target, listener) -{ -} - -void -ProcessFreeBSD::Terminate() -{ -} - -bool -ProcessFreeBSD::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) -{ - // XXX haxx - new_thread_list = old_thread_list; - - return false; -} diff --git a/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h b/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h deleted file mode 100644 index 74996f131271..000000000000 --- a/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h +++ /dev/null @@ -1,85 +0,0 @@ -//===-- ProcessFreeBSD.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_ProcessFreeBSD_H_ -#define liblldb_ProcessFreeBSD_H_ - -// C Includes - -// C++ Includes -#include <queue> - -// Other libraries and framework includes -#include "lldb/Target/Process.h" -#include "lldb/Target/ThreadList.h" -#include "ProcessMessage.h" -#include "ProcessPOSIX.h" - -class ProcessMonitor; - -class ProcessFreeBSD : - public ProcessPOSIX -{ - -public: - //------------------------------------------------------------------ - // Static functions. - //------------------------------------------------------------------ - static lldb::ProcessSP - CreateInstance(lldb_private::Target& target, - lldb_private::Listener &listener, - const lldb_private::FileSpec *crash_file_path); - - static void - Initialize(); - - static void - Terminate(); - - static const char * - GetPluginNameStatic(); - - static const char * - GetPluginDescriptionStatic(); - - //------------------------------------------------------------------ - // Constructors and destructors - //------------------------------------------------------------------ - ProcessFreeBSD(lldb_private::Target& target, - lldb_private::Listener &listener); - - virtual bool - UpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list); - - //------------------------------------------------------------------ - // PluginInterface protocol - //------------------------------------------------------------------ - virtual const char * - GetPluginName(); - - virtual const char * - GetShortPluginName(); - - virtual uint32_t - GetPluginVersion(); - - virtual void - GetPluginCommandHelp(const char *command, lldb_private::Stream *strm); - - virtual lldb_private::Error - ExecutePluginCommand(lldb_private::Args &command, - lldb_private::Stream *strm); - - virtual lldb_private::Log * - EnablePluginLogging(lldb_private::Stream *strm, - lldb_private::Args &command); - -}; - -#endif // liblldb_MacOSXProcess_H_ diff --git a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp deleted file mode 100644 index bece1b2f44e2..000000000000 --- a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp +++ /dev/null @@ -1,1560 +0,0 @@ -//===-- ProcessMonitor.cpp ------------------------------------ -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -#include <errno.h> -#include <poll.h> -#include <string.h> -#include <unistd.h> -#include <signal.h> -#include <sys/ptrace.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <sys/wait.h> - -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/Error.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" -#include "lldb/Host/Host.h" -#include "lldb/Target/Thread.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Utility/PseudoTerminal.h" - - -#include "POSIXThread.h" -#include "ProcessFreeBSD.h" -#include "ProcessPOSIXLog.h" -#include "ProcessMonitor.h" - -extern "C" { - extern char ** environ; - } - -using namespace lldb; -using namespace lldb_private; - -// We disable the tracing of ptrace calls for integration builds to -// avoid the additional indirection and checks. -#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION -// Wrapper for ptrace to catch errors and log calls. - -const char * -Get_PT_IO_OP(int op) -{ - switch (op) { - case PIOD_READ_D: return "READ_D"; - case PIOD_WRITE_D: return "WRITE_D"; - case PIOD_READ_I: return "READ_I"; - case PIOD_WRITE_I: return "WRITE_I"; - default: return "Unknown op"; - } -} - -extern long -PtraceWrapper(int req, ::pid_t pid, void *addr, int data, - const char* reqName, const char* file, int line) -{ - long int result; - - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE)); - - if (log) { - log->Printf("ptrace(%s, %u, %p, %x) called from file %s line %d", - reqName, pid, addr, data, file, line); - if (req == PT_IO) { - struct ptrace_io_desc *pi = (struct ptrace_io_desc *) addr; - - log->Printf("PT_IO: op=%s offs=%zx size=%ld", - Get_PT_IO_OP(pi->piod_op), pi->piod_offs, pi->piod_len); - } - } - - //PtraceDisplayBytes(req, data); - - errno = 0; - result = ptrace(req, pid, (caddr_t) addr, data); - - //PtraceDisplayBytes(req, data); - - if (log && (result == -1 || errno != 0)) - { - const char* str; - switch (errno) - { - case ESRCH: str = "ESRCH"; break; - case EINVAL: str = "EINVAL"; break; - case EBUSY: str = "EBUSY"; break; - case EPERM: str = "EPERM"; break; - default: str = "<unknown>"; - } - log->Printf("ptrace() failed; errno=%d (%s)", errno, str); - } - - if (log) { - if (req == PT_GETREGS) { - struct reg *r = (struct reg *) addr; - - log->Printf("PT_GETREGS: ip=0x%lx", r->r_rip); - log->Printf("PT_GETREGS: sp=0x%lx", r->r_rsp); - log->Printf("PT_GETREGS: bp=0x%lx", r->r_rbp); - log->Printf("PT_GETREGS: ax=0x%lx", r->r_rax); - } - } - - return result; -} - -#define PTRACE(req, pid, addr, data) \ - PtraceWrapper((req), (pid), (addr), (data), #req, __FILE__, __LINE__) -#else -#define PTRACE ptrace -#endif - -//------------------------------------------------------------------------------ -// Static implementations of ProcessMonitor::ReadMemory and -// ProcessMonitor::WriteMemory. This enables mutual recursion between these -// functions without needed to go thru the thread funnel. - -static size_t -DoReadMemory(lldb::pid_t pid, lldb::addr_t vm_addr, void *buf, size_t size, - Error &error) -{ - struct ptrace_io_desc pi_desc; - - pi_desc.piod_op = PIOD_READ_D; - pi_desc.piod_offs = (void *)vm_addr; - pi_desc.piod_addr = buf; - pi_desc.piod_len = size; - - if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0) - error.SetErrorToErrno(); - return pi_desc.piod_len; -} - -static size_t -DoWriteMemory(lldb::pid_t pid, lldb::addr_t vm_addr, const void *buf, - size_t size, Error &error) -{ - struct ptrace_io_desc pi_desc; - - pi_desc.piod_op = PIOD_WRITE_D; - pi_desc.piod_offs = (void *)vm_addr; - pi_desc.piod_addr = (void *)buf; - pi_desc.piod_len = size; - - if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0) - error.SetErrorToErrno(); - return pi_desc.piod_len; -} - -// Simple helper function to ensure flags are enabled on the given file -// descriptor. -static bool -EnsureFDFlags(int fd, int flags, Error &error) -{ - int status; - - if ((status = fcntl(fd, F_GETFL)) == -1) - { - error.SetErrorToErrno(); - return false; - } - - if (fcntl(fd, F_SETFL, status | flags) == -1) - { - error.SetErrorToErrno(); - return false; - } - - return true; -} - -//------------------------------------------------------------------------------ -/// @class Operation -/// @brief Represents a ProcessMonitor operation. -/// -/// Under FreeBSD, it is not possible to ptrace() from any other thread but the -/// one that spawned or attached to the process from the start. Therefore, when -/// a ProcessMonitor is asked to deliver or change the state of an inferior -/// process the operation must be "funneled" to a specific thread to perform the -/// task. The Operation class provides an abstract base for all services the -/// ProcessMonitor must perform via the single virtual function Execute, thus -/// encapsulating the code that needs to run in the privileged context. -class Operation -{ -public: - virtual void Execute(ProcessMonitor *monitor) = 0; -}; - -//------------------------------------------------------------------------------ -/// @class ReadOperation -/// @brief Implements ProcessMonitor::ReadMemory. -class ReadOperation : public Operation -{ -public: - ReadOperation(lldb::addr_t addr, void *buff, size_t size, - Error &error, size_t &result) - : m_addr(addr), m_buff(buff), m_size(size), - m_error(error), m_result(result) - { } - - void Execute(ProcessMonitor *monitor); - -private: - lldb::addr_t m_addr; - void *m_buff; - size_t m_size; - Error &m_error; - size_t &m_result; -}; - -void -ReadOperation::Execute(ProcessMonitor *monitor) -{ - lldb::pid_t pid = monitor->GetPID(); - - m_result = DoReadMemory(pid, m_addr, m_buff, m_size, m_error); -} - -//------------------------------------------------------------------------------ -/// @class ReadOperation -/// @brief Implements ProcessMonitor::WriteMemory. -class WriteOperation : public Operation -{ -public: - WriteOperation(lldb::addr_t addr, const void *buff, size_t size, - Error &error, size_t &result) - : m_addr(addr), m_buff(buff), m_size(size), - m_error(error), m_result(result) - { } - - void Execute(ProcessMonitor *monitor); - -private: - lldb::addr_t m_addr; - const void *m_buff; - size_t m_size; - Error &m_error; - size_t &m_result; -}; - -void -WriteOperation::Execute(ProcessMonitor *monitor) -{ - lldb::pid_t pid = monitor->GetPID(); - - m_result = DoWriteMemory(pid, m_addr, m_buff, m_size, m_error); -} - -//------------------------------------------------------------------------------ -/// @class ReadRegOperation -/// @brief Implements ProcessMonitor::ReadRegisterValue. -class ReadRegOperation : public Operation -{ -public: - ReadRegOperation(unsigned offset, unsigned size, RegisterValue &value, bool &result) - : m_offset(offset), m_size(size), m_value(value), m_result(result) - { } - - void Execute(ProcessMonitor *monitor); - -private: - unsigned m_offset; - unsigned m_size; - RegisterValue &m_value; - bool &m_result; -}; - -void -ReadRegOperation::Execute(ProcessMonitor *monitor) -{ - lldb::pid_t pid = monitor->GetPID(); - struct reg regs; - int rc; - - if ((rc = PTRACE(PT_GETREGS, pid, (caddr_t)®s, 0)) < 0) { - m_result = false; - } else { - if (m_size == sizeof(uintptr_t)) - m_value = *(uintptr_t *)(((caddr_t)®s) + m_offset); - else - memcpy(&m_value, (((caddr_t)®s) + m_offset), m_size); - m_result = true; - } -} - -//------------------------------------------------------------------------------ -/// @class WriteRegOperation -/// @brief Implements ProcessMonitor::WriteRegisterValue. -class WriteRegOperation : public Operation -{ -public: - WriteRegOperation(unsigned offset, const RegisterValue &value, bool &result) - : m_offset(offset), m_value(value), m_result(result) - { } - - void Execute(ProcessMonitor *monitor); - -private: - unsigned m_offset; - const RegisterValue &m_value; - bool &m_result; -}; - -void -WriteRegOperation::Execute(ProcessMonitor *monitor) -{ - lldb::pid_t pid = monitor->GetPID(); - struct reg regs; - - if (PTRACE(PT_GETREGS, pid, (caddr_t)®s, 0) < 0) { - m_result = false; - return; - } - *(uintptr_t *)(((caddr_t)®s) + m_offset) = (uintptr_t)m_value.GetAsUInt64(); - if (PTRACE(PT_SETREGS, pid, (caddr_t)®s, 0) < 0) - m_result = false; - else - m_result = true; -} - -//------------------------------------------------------------------------------ -/// @class ReadGPROperation -/// @brief Implements ProcessMonitor::ReadGPR. -class ReadGPROperation : public Operation -{ -public: - ReadGPROperation(void *buf, bool &result) - : m_buf(buf), m_result(result) - { } - - void Execute(ProcessMonitor *monitor); - -private: - void *m_buf; - bool &m_result; -}; - -void -ReadGPROperation::Execute(ProcessMonitor *monitor) -{ - int rc; - - errno = 0; - rc = PTRACE(PT_GETREGS, monitor->GetPID(), (caddr_t)m_buf, 0); - if (errno != 0) - m_result = false; - else - m_result = true; -} - -//------------------------------------------------------------------------------ -/// @class ReadFPROperation -/// @brief Implements ProcessMonitor::ReadFPR. -class ReadFPROperation : public Operation -{ -public: - ReadFPROperation(void *buf, bool &result) - : m_buf(buf), m_result(result) - { } - - void Execute(ProcessMonitor *monitor); - -private: - void *m_buf; - bool &m_result; -}; - -void -ReadFPROperation::Execute(ProcessMonitor *monitor) -{ - if (PTRACE(PT_GETFPREGS, monitor->GetPID(), (caddr_t)m_buf, 0) < 0) - m_result = false; - else - m_result = true; -} - -//------------------------------------------------------------------------------ -/// @class WriteGPROperation -/// @brief Implements ProcessMonitor::WriteGPR. -class WriteGPROperation : public Operation -{ -public: - WriteGPROperation(void *buf, bool &result) - : m_buf(buf), m_result(result) - { } - - void Execute(ProcessMonitor *monitor); - -private: - void *m_buf; - bool &m_result; -}; - -void -WriteGPROperation::Execute(ProcessMonitor *monitor) -{ - if (PTRACE(PT_SETREGS, monitor->GetPID(), (caddr_t)m_buf, 0) < 0) - m_result = false; - else - m_result = true; -} - -//------------------------------------------------------------------------------ -/// @class WriteFPROperation -/// @brief Implements ProcessMonitor::WriteFPR. -class WriteFPROperation : public Operation -{ -public: - WriteFPROperation(void *buf, bool &result) - : m_buf(buf), m_result(result) - { } - - void Execute(ProcessMonitor *monitor); - -private: - void *m_buf; - bool &m_result; -}; - -void -WriteFPROperation::Execute(ProcessMonitor *monitor) -{ - if (PTRACE(PT_SETFPREGS, monitor->GetPID(), (caddr_t)m_buf, 0) < 0) - m_result = false; - else - m_result = true; -} - -//------------------------------------------------------------------------------ -/// @class ResumeOperation -/// @brief Implements ProcessMonitor::Resume. -class ResumeOperation : public Operation -{ -public: - ResumeOperation(lldb::tid_t tid, uint32_t signo, bool &result) : - m_tid(tid), m_signo(signo), m_result(result) { } - - void Execute(ProcessMonitor *monitor); - -private: - lldb::tid_t m_tid; - uint32_t m_signo; - bool &m_result; -}; - -void -ResumeOperation::Execute(ProcessMonitor *monitor) -{ - int data = 0; - - if (m_signo != LLDB_INVALID_SIGNAL_NUMBER) - data = m_signo; - - if (PTRACE(PT_CONTINUE, m_tid, (caddr_t)1, data)) - m_result = false; - else - m_result = true; -} - -//------------------------------------------------------------------------------ -/// @class ResumeOperation -/// @brief Implements ProcessMonitor::SingleStep. -class SingleStepOperation : public Operation -{ -public: - SingleStepOperation(lldb::tid_t tid, uint32_t signo, bool &result) - : m_tid(tid), m_signo(signo), m_result(result) { } - - void Execute(ProcessMonitor *monitor); - -private: - lldb::tid_t m_tid; - uint32_t m_signo; - bool &m_result; -}; - -void -SingleStepOperation::Execute(ProcessMonitor *monitor) -{ - int data = 0; - - if (m_signo != LLDB_INVALID_SIGNAL_NUMBER) - data = m_signo; - - if (PTRACE(PT_STEP, m_tid, NULL, data)) - m_result = false; - else - m_result = true; -} - -//------------------------------------------------------------------------------ -/// @class SiginfoOperation -/// @brief Implements ProcessMonitor::GetSignalInfo. -class SiginfoOperation : public Operation -{ -public: - SiginfoOperation(lldb::tid_t tid, void *info, bool &result) - : m_tid(tid), m_info(info), m_result(result) { } - - void Execute(ProcessMonitor *monitor); - -private: - lldb::tid_t m_tid; - void *m_info; - bool &m_result; -}; - -void -SiginfoOperation::Execute(ProcessMonitor *monitor) -{ - struct ptrace_lwpinfo plwp; - - if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp))) - m_result = false; - else { - memcpy(m_info, &plwp.pl_siginfo, sizeof(siginfo_t)); - m_result = true; - } -} - -//------------------------------------------------------------------------------ -/// @class EventMessageOperation -/// @brief Implements ProcessMonitor::GetEventMessage. -class EventMessageOperation : public Operation -{ -public: - EventMessageOperation(lldb::tid_t tid, unsigned long *message, bool &result) - : m_tid(tid), m_message(message), m_result(result) { } - - void Execute(ProcessMonitor *monitor); - -private: - lldb::tid_t m_tid; - unsigned long *m_message; - bool &m_result; -}; - -void -EventMessageOperation::Execute(ProcessMonitor *monitor) -{ - struct ptrace_lwpinfo plwp; - - if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp))) - m_result = false; - else { - if (plwp.pl_flags & PL_FLAG_FORKED) { - m_message = (unsigned long *)plwp.pl_child_pid; - m_result = true; - } else - m_result = false; - } -} - -//------------------------------------------------------------------------------ -/// @class KillOperation -/// @brief Implements ProcessMonitor::BringProcessIntoLimbo. -class KillOperation : public Operation -{ -public: - KillOperation(bool &result) : m_result(result) { } - - void Execute(ProcessMonitor *monitor); - -private: - bool &m_result; -}; - -void -KillOperation::Execute(ProcessMonitor *monitor) -{ - lldb::pid_t pid = monitor->GetPID(); - - if (PTRACE(PT_KILL, pid, NULL, 0)) - m_result = false; - else - m_result = true; -} - -//------------------------------------------------------------------------------ -/// @class KillOperation -/// @brief Implements ProcessMonitor::BringProcessIntoLimbo. -class DetachOperation : public Operation -{ -public: - DetachOperation(Error &result) : m_error(result) { } - - void Execute(ProcessMonitor *monitor); - -private: - Error &m_error; -}; - -void -DetachOperation::Execute(ProcessMonitor *monitor) -{ - lldb::pid_t pid = monitor->GetPID(); - - if (PTRACE(PT_DETACH, pid, NULL, 0) < 0) - m_error.SetErrorToErrno(); - -} - -ProcessMonitor::OperationArgs::OperationArgs(ProcessMonitor *monitor) - : m_monitor(monitor) -{ - sem_init(&m_semaphore, 0, 0); -} - -ProcessMonitor::OperationArgs::~OperationArgs() -{ - sem_destroy(&m_semaphore); -} - -ProcessMonitor::LaunchArgs::LaunchArgs(ProcessMonitor *monitor, - lldb_private::Module *module, - char const **argv, - char const **envp, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path) - : OperationArgs(monitor), - m_module(module), - m_argv(argv), - m_envp(envp), - m_stdin_path(stdin_path), - m_stdout_path(stdout_path), - m_stderr_path(stderr_path) { } - -ProcessMonitor::LaunchArgs::~LaunchArgs() -{ } - -ProcessMonitor::AttachArgs::AttachArgs(ProcessMonitor *monitor, - lldb::pid_t pid) - : OperationArgs(monitor), m_pid(pid) { } - -ProcessMonitor::AttachArgs::~AttachArgs() -{ } - -//------------------------------------------------------------------------------ -/// The basic design of the ProcessMonitor is built around two threads. -/// -/// One thread (@see SignalThread) simply blocks on a call to waitpid() looking -/// for changes in the debugee state. When a change is detected a -/// ProcessMessage is sent to the associated ProcessFreeBSD instance. This thread -/// "drives" state changes in the debugger. -/// -/// The second thread (@see OperationThread) is responsible for two things 1) -/// launching or attaching to the inferior process, and then 2) servicing -/// operations such as register reads/writes, stepping, etc. See the comments -/// on the Operation class for more info as to why this is needed. -ProcessMonitor::ProcessMonitor(ProcessPOSIX *process, - Module *module, - const char *argv[], - const char *envp[], - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - lldb_private::Error &error) - : m_process(static_cast<ProcessFreeBSD *>(process)), - m_operation_thread(LLDB_INVALID_HOST_THREAD), - m_monitor_thread(LLDB_INVALID_HOST_THREAD), - m_pid(LLDB_INVALID_PROCESS_ID), - m_server_mutex(Mutex::eMutexTypeRecursive), - m_terminal_fd(-1), - m_client_fd(-1), - m_server_fd(-1) -{ - std::auto_ptr<LaunchArgs> args; - - args.reset(new LaunchArgs(this, module, argv, envp, - stdin_path, stdout_path, stderr_path)); - - - // Server/client descriptors. - if (!EnableIPC()) - { - error.SetErrorToGenericError(); - error.SetErrorString("Monitor failed to initialize."); - } - - StartLaunchOpThread(args.get(), error); - if (!error.Success()) - return; - -WAIT_AGAIN: - // Wait for the operation thread to initialize. - if (sem_wait(&args->m_semaphore)) - { - if (errno == EINTR) - goto WAIT_AGAIN; - else - { - error.SetErrorToErrno(); - return; - } - } - - // Check that the launch was a success. - if (!args->m_error.Success()) - { - StopLaunchOpThread(); - error = args->m_error; - return; - } - - // Finally, start monitoring the child process for change in state. - m_monitor_thread = Host::StartMonitoringChildProcess( - ProcessMonitor::MonitorCallback, this, GetPID(), true); - if (!IS_VALID_LLDB_HOST_THREAD(m_monitor_thread)) - { - error.SetErrorToGenericError(); - error.SetErrorString("Process launch failed."); - return; - } -} - -ProcessMonitor::ProcessMonitor(ProcessPOSIX *process, - lldb::pid_t pid, - lldb_private::Error &error) - : m_process(static_cast<ProcessFreeBSD *>(process)), - m_operation_thread(LLDB_INVALID_HOST_THREAD), - m_monitor_thread(LLDB_INVALID_HOST_THREAD), - m_pid(pid), - m_server_mutex(Mutex::eMutexTypeRecursive), - m_terminal_fd(-1), - m_client_fd(-1), - m_server_fd(-1) -{ - std::auto_ptr<AttachArgs> args; - - args.reset(new AttachArgs(this, pid)); - - // Server/client descriptors. - if (!EnableIPC()) - { - error.SetErrorToGenericError(); - error.SetErrorString("Monitor failed to initialize."); - } - - StartAttachOpThread(args.get(), error); - if (!error.Success()) - return; - -WAIT_AGAIN: - // Wait for the operation thread to initialize. - if (sem_wait(&args->m_semaphore)) - { - if (errno == EINTR) - goto WAIT_AGAIN; - else - { - error.SetErrorToErrno(); - return; - } - } - - // Check that the launch was a success. - if (!args->m_error.Success()) - { - StopAttachOpThread(); - error = args->m_error; - return; - } - - // Finally, start monitoring the child process for change in state. - m_monitor_thread = Host::StartMonitoringChildProcess( - ProcessMonitor::MonitorCallback, this, GetPID(), true); - if (!IS_VALID_LLDB_HOST_THREAD(m_monitor_thread)) - { - error.SetErrorToGenericError(); - error.SetErrorString("Process attach failed."); - return; - } -} - -ProcessMonitor::~ProcessMonitor() -{ - StopMonitor(); -} - -//------------------------------------------------------------------------------ -// Thread setup and tear down. -void -ProcessMonitor::StartLaunchOpThread(LaunchArgs *args, Error &error) -{ - static const char *g_thread_name = "lldb.process.freebsd.operation"; - - if (IS_VALID_LLDB_HOST_THREAD(m_operation_thread)) - return; - - m_operation_thread = - Host::ThreadCreate(g_thread_name, LaunchOpThread, args, &error); -} - -void -ProcessMonitor::StopLaunchOpThread() -{ - lldb::thread_result_t result; - - if (!IS_VALID_LLDB_HOST_THREAD(m_operation_thread)) - return; - - Host::ThreadCancel(m_operation_thread, NULL); - Host::ThreadJoin(m_operation_thread, &result, NULL); -} - -void * -ProcessMonitor::LaunchOpThread(void *arg) -{ - LaunchArgs *args = static_cast<LaunchArgs*>(arg); - - if (!Launch(args)) { - sem_post(&args->m_semaphore); - return NULL; - } - - ServeOperation(args); - return NULL; -} - -bool -ProcessMonitor::Launch(LaunchArgs *args) -{ - ProcessMonitor *monitor = args->m_monitor; - ProcessFreeBSD &process = monitor->GetProcess(); - lldb::ProcessSP processSP = process.shared_from_this(); - const char **argv = args->m_argv; - const char **envp = args->m_envp; - const char *stdin_path = args->m_stdin_path; - const char *stdout_path = args->m_stdout_path; - const char *stderr_path = args->m_stderr_path; - lldb::pid_t pid; - - lldb::ThreadSP inferior; - - // Propagate the environment if one is not supplied. - if (envp == NULL || envp[0] == NULL) - envp = const_cast<const char **>(environ); - - // Recognized child exit status codes. - enum { - ePtraceFailed = 1, - eDupStdinFailed, - eDupStdoutFailed, - eDupStderrFailed, - eExecFailed - }; - - pid = fork(); - - // Child process. - if (pid == 0) - { - // Trace this process. - if (PTRACE(PT_TRACE_ME, 0, NULL, 0) < 0) - exit(ePtraceFailed); - - // Do not inherit setgid powers. - setgid(getgid()); - - // Let us have our own process group. - setpgid(0, 0); - - // Dup file descriptors if needed. - // - // FIXME: If two or more of the paths are the same we needlessly open - // the same file multiple times. - if (stdin_path != NULL && stdin_path[0]) - if (!DupDescriptor(stdin_path, STDIN_FILENO, O_RDONLY)) - exit(eDupStdinFailed); - - if (stdout_path != NULL && stdout_path[0]) - if (!DupDescriptor(stdout_path, STDOUT_FILENO, O_WRONLY | O_CREAT)) - exit(eDupStdoutFailed); - - if (stderr_path != NULL && stderr_path[0]) - if (!DupDescriptor(stderr_path, STDERR_FILENO, O_WRONLY | O_CREAT)) - exit(eDupStderrFailed); - - // Execute. We should never return. - execve(argv[0], - const_cast<char *const *>(argv), - const_cast<char *const *>(envp)); - exit(eExecFailed); - } - - // Wait for the child process to to trap on its call to execve. - ::pid_t wpid; - int status; - if ((wpid = waitpid(pid, &status, 0)) < 0) - { - args->m_error.SetErrorToErrno(); - goto FINISH; - } - else if (WIFEXITED(status)) - { - // open, dup or execve likely failed for some reason. - args->m_error.SetErrorToGenericError(); - switch (WEXITSTATUS(status)) - { - case ePtraceFailed: - args->m_error.SetErrorString("Child ptrace failed."); - break; - case eDupStdinFailed: - args->m_error.SetErrorString("Child open stdin failed."); - break; - case eDupStdoutFailed: - args->m_error.SetErrorString("Child open stdout failed."); - break; - case eDupStderrFailed: - args->m_error.SetErrorString("Child open stderr failed."); - break; - case eExecFailed: - args->m_error.SetErrorString("Child exec failed."); - break; - default: - args->m_error.SetErrorString("Child returned unknown exit status."); - break; - } - goto FINISH; - } - assert(WIFSTOPPED(status) && wpid == pid && - "Could not sync with inferior process."); - -#ifdef notyet - // Have the child raise an event on exit. This is used to keep the child in - // limbo until it is destroyed. - if (PTRACE(PTRACE_SETOPTIONS, pid, NULL, PTRACE_O_TRACEEXIT) < 0) - { - args->m_error.SetErrorToErrno(); - goto FINISH; - } -#endif - // XXX - Release the master terminal descriptor and pass it off to the - // XXX - ProcessMonitor instance. Similarly stash the inferior pid. - // For now just use stdin fd - monitor->m_terminal_fd = STDIN_FILENO; - monitor->m_pid = pid; - - // Set the terminal fd to be in non blocking mode (it simplifies the - // implementation of ProcessFreeBSD::GetSTDOUT to have a non-blocking - // descriptor to read from). - if (!EnsureFDFlags(monitor->m_terminal_fd, O_NONBLOCK, args->m_error)) - goto FINISH; - - // Update the process thread list with this new thread. - inferior.reset(new POSIXThread(processSP, pid)); - process.GetThreadList().AddThread(inferior); - - // Let our process instance know the thread has stopped. - process.SendMessage(ProcessMessage::Trace(pid)); - -FINISH: - return args->m_error.Success(); -} - -bool -ProcessMonitor::EnableIPC() -{ - int fd[2]; - - if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) - return false; - - m_client_fd = fd[0]; - m_server_fd = fd[1]; - return true; -} - -void -ProcessMonitor::StartAttachOpThread(AttachArgs *args, lldb_private::Error &error) -{ - static const char *g_thread_name = "lldb.process.freebsd.operation"; - - if (IS_VALID_LLDB_HOST_THREAD(m_operation_thread)) - return; - - m_operation_thread = - Host::ThreadCreate(g_thread_name, AttachOpThread, args, &error); -} - -void -ProcessMonitor::StopAttachOpThread() -{ - assert(!"Not implemented yet!!!"); -} - -void * -ProcessMonitor::AttachOpThread(void *arg) -{ - AttachArgs *args = static_cast<AttachArgs*>(arg); - - if (!Attach(args)) - return NULL; - - ServeOperation(args); - return NULL; -} - -bool -ProcessMonitor::Attach(AttachArgs *args) -{ - lldb::pid_t pid = args->m_pid; - - ProcessMonitor *monitor = args->m_monitor; - ProcessFreeBSD &process = monitor->GetProcess(); - lldb::ProcessSP processSP = process.shared_from_this(); - ThreadList &tl = process.GetThreadList(); - lldb::ThreadSP inferior; - - if (pid <= 1) - { - args->m_error.SetErrorToGenericError(); - args->m_error.SetErrorString("Attaching to process 1 is not allowed."); - goto FINISH; - } - - // Attach to the requested process. - if (PTRACE(PT_ATTACH, pid, NULL, 0) < 0) - { - args->m_error.SetErrorToErrno(); - goto FINISH; - } - - int status; - if ((status = waitpid(pid, NULL, 0)) < 0) - { - args->m_error.SetErrorToErrno(); - goto FINISH; - } - - // Update the process thread list with the attached thread. - inferior.reset(new POSIXThread(processSP, pid)); - tl.AddThread(inferior); - - // Let our process instance know the thread has stopped. - process.SendMessage(ProcessMessage::Trace(pid)); - - FINISH: - return args->m_error.Success(); -} - -bool -ProcessMonitor::MonitorCallback(void *callback_baton, - lldb::pid_t pid, - bool exited, - int signal, - int status) -{ - ProcessMessage message; - ProcessMonitor *monitor = static_cast<ProcessMonitor*>(callback_baton); - ProcessFreeBSD *process = monitor->m_process; - bool stop_monitoring; - siginfo_t info; - - if (!monitor->GetSignalInfo(pid, &info)) - stop_monitoring = true; // pid is gone. Bail. - else { - switch (info.si_signo) - { - case SIGTRAP: - message = MonitorSIGTRAP(monitor, &info, pid); - break; - - default: - message = MonitorSignal(monitor, &info, pid); - break; - } - - process->SendMessage(message); - stop_monitoring = message.GetKind() == ProcessMessage::eExitMessage; - } - - return stop_monitoring; -} - -ProcessMessage -ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor, - const siginfo_t *info, lldb::pid_t pid) -{ - ProcessMessage message; - - assert(info->si_signo == SIGTRAP && "Unexpected child signal!"); - - switch (info->si_code) - { - default: - assert(false && "Unexpected SIGTRAP code!"); - break; - - case (SIGTRAP /* | (PTRACE_EVENT_EXIT << 8) */): - { - // The inferior process is about to exit. Maintain the process in a - // state of "limbo" until we are explicitly commanded to detach, - // destroy, resume, etc. - unsigned long data = 0; - if (!monitor->GetEventMessage(pid, &data)) - data = -1; - message = ProcessMessage::Limbo(pid, (data >> 8)); - break; - } - - case 0: - case TRAP_TRACE: - message = ProcessMessage::Trace(pid); - break; - - case SI_KERNEL: - case TRAP_BRKPT: - message = ProcessMessage::Break(pid); - break; - } - - return message; -} - -ProcessMessage -ProcessMonitor::MonitorSignal(ProcessMonitor *monitor, - const siginfo_t *info, lldb::pid_t pid) -{ - ProcessMessage message; - int signo = info->si_signo; - - // 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 FreeBSD. - // - // IOW, user generated signals never generate what we consider to be a - // "crash". - // - // Similarly, ACK signals generated by this monitor. - if (info->si_code == SI_USER) - { - if (info->si_pid == getpid()) - return ProcessMessage::SignalDelivered(pid, signo); - else - return ProcessMessage::Signal(pid, signo); - } - - if (signo == SIGSEGV) { - lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr); - ProcessMessage::CrashReason reason = GetCrashReasonForSIGSEGV(info); - return ProcessMessage::Crash(pid, reason, signo, fault_addr); - } - - if (signo == SIGILL) { - lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr); - ProcessMessage::CrashReason reason = GetCrashReasonForSIGILL(info); - return ProcessMessage::Crash(pid, reason, signo, fault_addr); - } - - if (signo == SIGFPE) { - lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr); - ProcessMessage::CrashReason reason = GetCrashReasonForSIGFPE(info); - return ProcessMessage::Crash(pid, reason, signo, fault_addr); - } - - if (signo == SIGBUS) { - lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr); - ProcessMessage::CrashReason reason = GetCrashReasonForSIGBUS(info); - return ProcessMessage::Crash(pid, reason, signo, fault_addr); - } - - // Everything else is "normal" and does not require any special action on - // our part. - return ProcessMessage::Signal(pid, signo); -} - -ProcessMessage::CrashReason -ProcessMonitor::GetCrashReasonForSIGSEGV(const siginfo_t *info) -{ - ProcessMessage::CrashReason reason; - assert(info->si_signo == SIGSEGV); - - reason = ProcessMessage::eInvalidCrashReason; - - switch (info->si_code) - { - default: - assert(false && "unexpected si_code for SIGSEGV"); - break; - case SEGV_MAPERR: - reason = ProcessMessage::eInvalidAddress; - break; - case SEGV_ACCERR: - reason = ProcessMessage::ePrivilegedAddress; - break; - } - - return reason; -} - -ProcessMessage::CrashReason -ProcessMonitor::GetCrashReasonForSIGILL(const siginfo_t *info) -{ - ProcessMessage::CrashReason reason; - assert(info->si_signo == SIGILL); - - reason = ProcessMessage::eInvalidCrashReason; - - switch (info->si_code) - { - default: - assert(false && "unexpected si_code for SIGILL"); - break; - case ILL_ILLOPC: - reason = ProcessMessage::eIllegalOpcode; - break; - case ILL_ILLOPN: - reason = ProcessMessage::eIllegalOperand; - break; - case ILL_ILLADR: - reason = ProcessMessage::eIllegalAddressingMode; - break; - case ILL_ILLTRP: - reason = ProcessMessage::eIllegalTrap; - break; - case ILL_PRVOPC: - reason = ProcessMessage::ePrivilegedOpcode; - break; - case ILL_PRVREG: - reason = ProcessMessage::ePrivilegedRegister; - break; - case ILL_COPROC: - reason = ProcessMessage::eCoprocessorError; - break; - case ILL_BADSTK: - reason = ProcessMessage::eInternalStackError; - break; - } - - return reason; -} - -ProcessMessage::CrashReason -ProcessMonitor::GetCrashReasonForSIGFPE(const siginfo_t *info) -{ - ProcessMessage::CrashReason reason; - assert(info->si_signo == SIGFPE); - - reason = ProcessMessage::eInvalidCrashReason; - - switch (info->si_code) - { - default: - assert(false && "unexpected si_code for SIGFPE"); - break; - case FPE_INTDIV: - reason = ProcessMessage::eIntegerDivideByZero; - break; - case FPE_INTOVF: - reason = ProcessMessage::eIntegerOverflow; - break; - case FPE_FLTDIV: - reason = ProcessMessage::eFloatDivideByZero; - break; - case FPE_FLTOVF: - reason = ProcessMessage::eFloatOverflow; - break; - case FPE_FLTUND: - reason = ProcessMessage::eFloatUnderflow; - break; - case FPE_FLTRES: - reason = ProcessMessage::eFloatInexactResult; - break; - case FPE_FLTINV: - reason = ProcessMessage::eFloatInvalidOperation; - break; - case FPE_FLTSUB: - reason = ProcessMessage::eFloatSubscriptRange; - break; - } - - return reason; -} - -ProcessMessage::CrashReason -ProcessMonitor::GetCrashReasonForSIGBUS(const siginfo_t *info) -{ - ProcessMessage::CrashReason reason; - assert(info->si_signo == SIGBUS); - - reason = ProcessMessage::eInvalidCrashReason; - - switch (info->si_code) - { - default: - assert(false && "unexpected si_code for SIGBUS"); - break; - case BUS_ADRALN: - reason = ProcessMessage::eIllegalAlignment; - break; - case BUS_ADRERR: - reason = ProcessMessage::eIllegalAddress; - break; - case BUS_OBJERR: - reason = ProcessMessage::eHardwareError; - break; - } - - return reason; -} - -void -ProcessMonitor::ServeOperation(OperationArgs *args) -{ - int status; - pollfd fdset; - - ProcessMonitor *monitor = args->m_monitor; - - fdset.fd = monitor->m_server_fd; - fdset.events = POLLIN | POLLPRI; - fdset.revents = 0; - - // We are finised with the arguments and are ready to go. Sync with the - // parent thread and start serving operations on the inferior. - sem_post(&args->m_semaphore); - - for (;;) - { - if ((status = poll(&fdset, 1, -1)) < 0) - { - switch (errno) - { - default: - assert(false && "Unexpected poll() failure!"); - continue; - - case EINTR: continue; // Just poll again. - case EBADF: return; // Connection terminated. - } - } - - assert(status == 1 && "Too many descriptors!"); - - if (fdset.revents & POLLIN) - { - Operation *op = NULL; - - READ_AGAIN: - if ((status = read(fdset.fd, &op, sizeof(op))) < 0) - { - // There is only one acceptable failure. - assert(errno == EINTR); - goto READ_AGAIN; - } - - assert(status == sizeof(op)); - op->Execute(monitor); - write(fdset.fd, &op, sizeof(op)); - } - } -} - -void -ProcessMonitor::DoOperation(Operation *op) -{ - int status; - Operation *ack = NULL; - Mutex::Locker lock(m_server_mutex); - - // FIXME: Do proper error checking here. - write(m_client_fd, &op, sizeof(op)); - -READ_AGAIN: - if ((status = read(m_client_fd, &ack, sizeof(ack))) < 0) - { - // If interrupted by a signal handler try again. Otherwise the monitor - // thread probably died and we have a stale file descriptor -- abort the - // operation. - if (errno == EINTR) - goto READ_AGAIN; - return; - } - - assert(status == sizeof(ack)); - assert(ack == op && "Invalid monitor thread response!"); -} - -size_t -ProcessMonitor::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, - Error &error) -{ - size_t result; - ReadOperation op(vm_addr, buf, size, error, result); - DoOperation(&op); - return result; -} - -size_t -ProcessMonitor::WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, - lldb_private::Error &error) -{ - size_t result; - WriteOperation op(vm_addr, buf, size, error, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::ReadRegisterValue(unsigned offset, unsigned size, RegisterValue &value) -{ - bool result; - ReadRegOperation op(offset, size, value, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::WriteRegisterValue(unsigned offset, const RegisterValue &value) -{ - bool result; - WriteRegOperation op(offset, value, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::ReadGPR(void *buf) -{ - bool result; - ReadGPROperation op(buf, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::ReadFPR(void *buf) -{ - bool result; - ReadFPROperation op(buf, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::WriteGPR(void *buf) -{ - bool result; - WriteGPROperation op(buf, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::WriteFPR(void *buf) -{ - bool result; - WriteFPROperation op(buf, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::Resume(lldb::tid_t tid, uint32_t signo) -{ - bool result; - ResumeOperation op(tid, signo, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::SingleStep(lldb::tid_t tid, uint32_t signo) -{ - bool result; - SingleStepOperation op(tid, signo, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::BringProcessIntoLimbo() -{ - bool result; - KillOperation op(result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::GetSignalInfo(lldb::tid_t tid, void *siginfo) -{ - bool result; - SiginfoOperation op(tid, siginfo, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::GetEventMessage(lldb::tid_t tid, unsigned long *message) -{ - bool result; - EventMessageOperation op(tid, message, result); - DoOperation(&op); - return result; -} - -Error -ProcessMonitor::Detach() -{ - Error result; - DetachOperation op(result); - DoOperation(&op); - StopMonitor(); - return result; -} - -bool -ProcessMonitor::DupDescriptor(const char *path, int fd, int flags) -{ - int target_fd = open(path, flags, 0666); - - if (target_fd == -1) - return false; - - return (dup2(target_fd, fd) == -1) ? false : true; -} - -void -ProcessMonitor::StopMonitoringChildProcess() -{ - lldb::thread_result_t thread_result; - - if (IS_VALID_LLDB_HOST_THREAD(m_monitor_thread)) - { - Host::ThreadCancel(m_monitor_thread, NULL); - Host::ThreadJoin(m_monitor_thread, &thread_result, NULL); - m_monitor_thread = LLDB_INVALID_HOST_THREAD; - } -} - -void -ProcessMonitor::StopMonitor() -{ - StopMonitoringChildProcess(); - StopLaunchOpThread(); - CloseFD(m_terminal_fd); - CloseFD(m_client_fd); - CloseFD(m_server_fd); -} - -void -ProcessMonitor::CloseFD(int &fd) -{ - if (fd != -1) - { - close(fd); - fd = -1; - } -} diff --git a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h deleted file mode 100644 index 9c630049caf7..000000000000 --- a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h +++ /dev/null @@ -1,292 +0,0 @@ -//===-- ProcessMonitor.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_ProcessMonitor_H_ -#define liblldb_ProcessMonitor_H_ - -// C Includes -#include <semaphore.h> -#include <signal.h> - -// C++ Includes -// Other libraries and framework includes -#include "lldb/lldb-types.h" -#include "lldb/Host/Mutex.h" - -namespace lldb_private -{ -class Error; -class Module; -class Scalar; -} // End lldb_private namespace. - -class ProcessFreeBSD; -class Operation; - -/// @class ProcessMonitor -/// @brief 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 propagated to the associated -/// ProcessFreeBSD instance by calling ProcessFreeBSD::SendMessage with the -/// appropriate ProcessMessage events. -/// -/// A purposely minimal set of operations are provided to interrogate and change -/// the inferior process state. -class ProcessMonitor -{ -public: - - /// Launches an inferior process ready for debugging. Forms the - /// implementation of Process::DoLaunch. - ProcessMonitor(ProcessPOSIX *process, - lldb_private::Module *module, - char const *argv[], - char const *envp[], - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - lldb_private::Error &error); - - ProcessMonitor(ProcessPOSIX *process, - lldb::pid_t pid, - lldb_private::Error &error); - - ~ProcessMonitor(); - - /// Provides the process number of debugee. - lldb::pid_t - GetPID() const { return m_pid; } - - /// Returns the process associated with this ProcessMonitor. - ProcessFreeBSD & - GetProcess() { return *m_process; } - - /// Returns a file descriptor to the controlling terminal of the inferior - /// process. - /// - /// Reads from this file descriptor yield both the standard output and - /// standard error of this debugee. Even if stderr and stdout were - /// redirected on launch it may still happen that data is available on this - /// descriptor (if the inferior process opens /dev/tty, for example). - /// - /// If this monitor was attached to an existing process this method returns - /// -1. - int - GetTerminalFD() const { return m_terminal_fd; } - - /// Reads @p size bytes from address @vm_adder in the inferior process - /// address space. - /// - /// This method is provided to implement Process::DoReadMemory. - size_t - ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, - lldb_private::Error &error); - - /// Writes @p size bytes from address @p vm_adder in the inferior process - /// address space. - /// - /// This method is provided to implement Process::DoWriteMemory. - size_t - WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, - lldb_private::Error &error); - - /// Reads the contents from the register identified by the given (architecture - /// dependent) offset. - /// - /// This method is provided for use by RegisterContextFreeBSD derivatives. - bool - ReadRegisterValue(unsigned offset, unsigned size, lldb_private::RegisterValue &value); - - /// Writes the given value to the register identified by the given - /// (architecture dependent) offset. - /// - /// This method is provided for use by RegisterContextFreeBSD derivatives. - bool - WriteRegisterValue(unsigned offset, const lldb_private::RegisterValue &value); - - /// Reads all general purpose registers into the specified buffer. - bool - ReadGPR(void *buf); - - /// Reads all floating point registers into the specified buffer. - bool - ReadFPR(void *buf); - - /// Writes all general purpose registers into the specified buffer. - bool - WriteGPR(void *buf); - - /// Writes all floating point registers into the specified buffer. - bool - WriteFPR(void *buf); - - /// Writes a siginfo_t structure corresponding to the given thread ID to the - /// memory region pointed to by @p siginfo. - bool - GetSignalInfo(lldb::tid_t tid, void *siginfo); - - /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG) - /// corresponding to the given thread IDto the memory pointed to by @p - /// message. - bool - GetEventMessage(lldb::tid_t tid, unsigned long *message); - - /// Resumes the given thread. If @p signo is anything but - /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread. - bool - Resume(lldb::tid_t tid, uint32_t signo); - - /// Single steps the given thread. If @p signo is anything but - /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread. - bool - SingleStep(lldb::tid_t tid, uint32_t signo); - - /// Sends the inferior process a PTRACE_KILL signal. The inferior will - /// still exists and can be interrogated. Once resumed it will exit as - /// though it received a SIGKILL. - bool - BringProcessIntoLimbo(); - - lldb_private::Error - Detach(); - - -private: - ProcessFreeBSD *m_process; - - lldb::thread_t m_operation_thread; - lldb::thread_t m_monitor_thread; - lldb::pid_t m_pid; - - - lldb_private::Mutex m_server_mutex; - int m_terminal_fd; - int m_client_fd; - int m_server_fd; - - struct OperationArgs - { - OperationArgs(ProcessMonitor *monitor); - - ~OperationArgs(); - - ProcessMonitor *m_monitor; // The monitor performing the attach. - sem_t m_semaphore; // Posted to once operation complete. - lldb_private::Error m_error; // Set if process operation failed. - }; - - /// @class LauchArgs - /// - /// @brief Simple structure to pass data to the thread responsible for - /// launching a child process. - struct LaunchArgs : OperationArgs - { - LaunchArgs(ProcessMonitor *monitor, - lldb_private::Module *module, - char const **argv, - char const **envp, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path); - - ~LaunchArgs(); - - lldb_private::Module *m_module; // The executable image to launch. - char const **m_argv; // Process arguments. - char const **m_envp; // Process environment. - const char *m_stdin_path; // Redirect stdin or NULL. - const char *m_stdout_path; // Redirect stdout or NULL. - const char *m_stderr_path; // Redirect stderr or NULL. - }; - - void - StartLaunchOpThread(LaunchArgs *args, lldb_private::Error &error); - - void - StopLaunchOpThread(); - - static void * - LaunchOpThread(void *arg); - - static bool - Launch(LaunchArgs *args); - - bool - EnableIPC(); - - struct AttachArgs : OperationArgs - { - AttachArgs(ProcessMonitor *monitor, - lldb::pid_t pid); - - ~AttachArgs(); - - lldb::pid_t m_pid; // pid of the process to be attached. - }; - - void - StartAttachOpThread(AttachArgs *args, lldb_private::Error &error); - - void - StopAttachOpThread(); - - static void * - AttachOpThread(void *args); - - static bool - Attach(AttachArgs *args); - - static void - ServeOperation(OperationArgs *args); - - static bool - DupDescriptor(const char *path, int fd, int flags); - - static bool - MonitorCallback(void *callback_baton, - lldb::pid_t pid, bool exited, int signal, int status); - - static ProcessMessage - MonitorSIGTRAP(ProcessMonitor *monitor, - const siginfo_t *info, lldb::pid_t pid); - - static ProcessMessage - MonitorSignal(ProcessMonitor *monitor, - const siginfo_t *info, lldb::pid_t pid); - - static ProcessMessage::CrashReason - GetCrashReasonForSIGSEGV(const siginfo_t *info); - - static ProcessMessage::CrashReason - GetCrashReasonForSIGILL(const siginfo_t *info); - - static ProcessMessage::CrashReason - GetCrashReasonForSIGFPE(const siginfo_t *info); - - static ProcessMessage::CrashReason - GetCrashReasonForSIGBUS(const siginfo_t *info); - - void - DoOperation(Operation *op); - - /// Stops the child monitor thread. - void - StopMonitoringChildProcess(); - - void - StopMonitor(); - - void - CloseFD(int &fd); -}; - -#endif // #ifndef liblldb_ProcessMonitor_H_ diff --git a/lldb/source/Plugins/Process/FreeBSD/RegisterContextFreeBSD_x86_64.h b/lldb/source/Plugins/Process/FreeBSD/RegisterContextFreeBSD_x86_64.h deleted file mode 100644 index 25590e74c096..000000000000 --- a/lldb/source/Plugins/Process/FreeBSD/RegisterContextFreeBSD_x86_64.h +++ /dev/null @@ -1,43 +0,0 @@ -//===-- RegisterContextFreeBSD_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_RegisterContextFreeBSD_x86_64_H_ -#define liblldb_RegisterContextFreeBSD_x86_64_H_ - - typedef struct _GPR - { - uint64_t r15; - uint64_t r14; - uint64_t r13; - uint64_t r12; - uint64_t r11; - uint64_t r10; - uint64_t r9; - uint64_t r8; - uint64_t rdi; - uint64_t rsi; - uint64_t rbp; - uint64_t rbx; - uint64_t rdx; - uint64_t rcx; - uint64_t rax; - uint32_t trapno; - uint16_t fs; - uint16_t gs; - uint32_t err; - uint16_t es; - uint16_t ds; - uint64_t rip; - uint64_t cs; - uint64_t rflags; - uint64_t rsp; - uint64_t ss; - } GPR; - -#endif diff --git a/lldb/source/Plugins/Process/Linux/LinuxSignals.cpp b/lldb/source/Plugins/Process/Linux/LinuxSignals.cpp deleted file mode 100644 index 0a6c34cfbc6d..000000000000 --- a/lldb/source/Plugins/Process/Linux/LinuxSignals.cpp +++ /dev/null @@ -1,67 +0,0 @@ -//===-- LinuxSignals.cpp ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -#include <signal.h> - -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "LinuxSignals.h" - -LinuxSignals::LinuxSignals() - : UnixSignals() -{ - Reset(); -} - -void -LinuxSignals::Reset() -{ - m_signals.clear(); - -#define ADDSIGNAL(S, SUPPRESS, STOP, NOTIFY, DESCRIPTION) \ - AddSignal(SIG ## S, "SIG" #S, #S, SUPPRESS, STOP, NOTIFY, DESCRIPTION) - - ADDSIGNAL(HUP, false, true, true, "hangup"); - ADDSIGNAL(INT, true, true, true, "interrupt"); - ADDSIGNAL(QUIT, false, true, true, "quit"); - ADDSIGNAL(ILL, false, true, true, "illegal instruction"); - ADDSIGNAL(TRAP, true, true, true, "trace trap (not reset when caught)"); - ADDSIGNAL(ABRT, false, true, true, "abort"); - ADDSIGNAL(IOT, false, true, true, "abort"); - ADDSIGNAL(BUS, false, true, true, "bus error"); - ADDSIGNAL(FPE, false, true, true, "floating point exception"); - ADDSIGNAL(KILL, false, true, true, "kill"); - ADDSIGNAL(USR1, false, true, true, "user defined signal 1"); - ADDSIGNAL(SEGV, false, true, true, "segmentation violation"); - ADDSIGNAL(USR2, false, true, true, "user defined signal 2"); - ADDSIGNAL(PIPE, false, true, true, "write to pipe with reading end closed"); - ADDSIGNAL(ALRM, false, false, true, "alarm"); - ADDSIGNAL(TERM, false, true, true, "termination requested"); - ADDSIGNAL(STKFLT, false, true, true, "stack fault"); - ADDSIGNAL(CHLD, false, false, true, "child process exit"); - ADDSIGNAL(CONT, false, true, true, "process continue"); - ADDSIGNAL(STOP, false, true, true, "process stop"); - ADDSIGNAL(TSTP, false, true, true, "tty stop"); - ADDSIGNAL(TTIN, false, true, true, "background tty read"); - ADDSIGNAL(TTOU, false, true, true, "background tty write"); - ADDSIGNAL(URG, false, true, true, "urgent data on socket"); - ADDSIGNAL(XCPU, false, true, true, "CPU resource exceeded"); - ADDSIGNAL(XFSZ, false, true, true, "file size limit exceeded"); - ADDSIGNAL(VTALRM, false, true, true, "virtual alarm"); - ADDSIGNAL(PROF, false, true, true, "profiling alarm"); - ADDSIGNAL(WINCH, false, true, true, "window size change"); - ADDSIGNAL(POLL, false, true, true, "pollable event"); - ADDSIGNAL(IO, false, true, true, "input/output ready"); - ADDSIGNAL(PWR, false, true, true, "power failure"); - ADDSIGNAL(SYS, false, true, true, "invalid system call"); - -#undef ADDSIGNAL -} diff --git a/lldb/source/Plugins/Process/Linux/LinuxSignals.h b/lldb/source/Plugins/Process/Linux/LinuxSignals.h deleted file mode 100644 index a726ecc4040a..000000000000 --- a/lldb/source/Plugins/Process/Linux/LinuxSignals.h +++ /dev/null @@ -1,31 +0,0 @@ -//===-- LinuxSignals.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_LinuxSignals_H_ -#define liblldb_LinuxSignals_H_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Target/UnixSignals.h" - -/// Linux specific set of Unix signals. -class LinuxSignals - : public lldb_private::UnixSignals -{ -public: - LinuxSignals(); - -private: - void - Reset(); -}; - -#endif diff --git a/lldb/source/Plugins/Process/Linux/Makefile b/lldb/source/Plugins/Process/Linux/Makefile deleted file mode 100644 index 850a0290b623..000000000000 --- a/lldb/source/Plugins/Process/Linux/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -##===- source/Plugins/Process/Linux/Makefile ---------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLDB_LEVEL := ../../../.. -LIBRARYNAME := lldbPluginProcessLinux -BUILD_ARCHIVE = 1 - -# Extend the include path so we may locate UnwindLLDB.h -CPPFLAGS += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Utility - -include $(LLDB_LEVEL)/Makefile diff --git a/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp deleted file mode 100644 index 3327914d8bc1..000000000000 --- a/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp +++ /dev/null @@ -1,157 +0,0 @@ -//===-- ProcessLinux.cpp ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -#include <errno.h> - -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" -#include "lldb/Host/Host.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Target/DynamicLoader.h" -#include "lldb/Target/Target.h" - -#include "ProcessLinux.h" -#include "ProcessPOSIXLog.h" -#include "Plugins/Process/Utility/InferiorCallPOSIX.h" -#include "ProcessMonitor.h" -#include "POSIXThread.h" - -using namespace lldb; -using namespace lldb_private; - -//------------------------------------------------------------------------------ -// Static functions. - -ProcessSP -ProcessLinux::CreateInstance(Target &target, Listener &listener, const FileSpec *) -{ - return ProcessSP(new ProcessLinux(target, listener)); -} - -void -ProcessLinux::Initialize() -{ - static bool g_initialized = false; - - if (!g_initialized) - { - g_initialized = true; - PluginManager::RegisterPlugin(GetPluginNameStatic(), - GetPluginDescriptionStatic(), - CreateInstance); - - Log::Callbacks log_callbacks = { - ProcessPOSIXLog::DisableLog, - ProcessPOSIXLog::EnableLog, - ProcessPOSIXLog::ListLogCategories - }; - - Log::RegisterLogChannel (ProcessLinux::GetPluginNameStatic(), log_callbacks); - ProcessPOSIXLog::RegisterPluginName(GetPluginNameStatic()); - } -} - -//------------------------------------------------------------------------------ -// Constructors and destructors. - -ProcessLinux::ProcessLinux(Target& target, Listener &listener) - : ProcessPOSIX(target, listener) -{ -#if 0 - // FIXME: Putting this code in the ctor and saving the byte order in a - // member variable is a hack to avoid const qual issues in GetByteOrder. - ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile(); - m_byte_order = obj_file->GetByteOrder(); -#else - // XXX: Will work only for local processes. - m_byte_order = lldb::endian::InlHostByteOrder(); -#endif -} - -void -ProcessLinux::Terminate() -{ -} -const char * -ProcessLinux::GetPluginNameStatic() -{ - return "linux"; -} - -const char * -ProcessLinux::GetPluginDescriptionStatic() -{ - return "Process plugin for Linux"; -} - - -bool -ProcessLinux::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) -{ - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf ("ProcessLinux::%s() (pid = %i)", __FUNCTION__, GetID()); - - // Update the process thread list with this new thread. - // FIXME: We should be using tid, not pid. - assert(m_monitor); - ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false)); - if (!thread_sp) { - ProcessSP me = this->shared_from_this(); - thread_sp.reset(new POSIXThread(me, GetID())); - } - - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf ("ProcessLinux::%s() updated pid = %i", __FUNCTION__, GetID()); - new_thread_list.AddThread(thread_sp); - - return new_thread_list.GetSize(false) > 0; -} - - -//------------------------------------------------------------------------------ -// ProcessInterface protocol. - -const char * -ProcessLinux::GetPluginName() -{ - return "process.linux"; -} - -const char * -ProcessLinux::GetShortPluginName() -{ - return "process.linux"; -} - -uint32_t -ProcessLinux::GetPluginVersion() -{ - return 1; -} - -void -ProcessLinux::GetPluginCommandHelp(const char *command, Stream *strm) -{ -} - -Error -ProcessLinux::ExecutePluginCommand(Args &command, Stream *strm) -{ - return Error(1, eErrorTypeGeneric); -} - -Log * -ProcessLinux::EnablePluginLogging(Stream *strm, Args &command) -{ - return NULL; -} diff --git a/lldb/source/Plugins/Process/Linux/ProcessLinux.h b/lldb/source/Plugins/Process/Linux/ProcessLinux.h deleted file mode 100644 index 9acbf49f5f01..000000000000 --- a/lldb/source/Plugins/Process/Linux/ProcessLinux.h +++ /dev/null @@ -1,88 +0,0 @@ -//===-- ProcessLinux.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_ProcessLinux_H_ -#define liblldb_ProcessLinux_H_ - -// C Includes - -// C++ Includes -#include <queue> - -// Other libraries and framework includes -#include "lldb/Target/Process.h" -#include "LinuxSignals.h" -#include "ProcessMessage.h" -#include "ProcessPOSIX.h" - -class ProcessMonitor; - -class ProcessLinux : - public ProcessPOSIX -{ -public: - //------------------------------------------------------------------ - // Static functions. - //------------------------------------------------------------------ - static lldb::ProcessSP - CreateInstance(lldb_private::Target& target, - lldb_private::Listener &listener, - const lldb_private::FileSpec *); - - static void - Initialize(); - - static void - Terminate(); - - static const char * - GetPluginNameStatic(); - - static const char * - GetPluginDescriptionStatic(); - - //------------------------------------------------------------------ - // Constructors and destructors - //------------------------------------------------------------------ - ProcessLinux(lldb_private::Target& target, - lldb_private::Listener &listener); - - virtual bool - UpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list); - //------------------------------------------------------------------ - // PluginInterface protocol - //------------------------------------------------------------------ - virtual const char * - GetPluginName(); - - virtual const char * - GetShortPluginName(); - - virtual uint32_t - GetPluginVersion(); - - virtual void - GetPluginCommandHelp(const char *command, lldb_private::Stream *strm); - - virtual lldb_private::Error - ExecutePluginCommand(lldb_private::Args &command, - lldb_private::Stream *strm); - - virtual lldb_private::Log * - EnablePluginLogging(lldb_private::Stream *strm, - lldb_private::Args &command); - -private: - - /// Linux-specific signal set. - LinuxSignals m_linux_signals; - -}; - -#endif // liblldb_MacOSXProcess_H_ diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp deleted file mode 100644 index 2f060df0bfe9..000000000000 --- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp +++ /dev/null @@ -1,1722 +0,0 @@ -//===-- ProcessMonitor.cpp ------------------------------------ -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -#include <errno.h> -#include <poll.h> -#include <string.h> -#include <unistd.h> -#include <sys/ptrace.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <sys/user.h> -#include <sys/wait.h> - -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/Debugger.h" -#include "lldb/Core/Error.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" -#include "lldb/Host/Host.h" -#include "lldb/Target/Thread.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Utility/PseudoTerminal.h" - -#include "POSIXThread.h" -#include "ProcessLinux.h" -#include "ProcessPOSIXLog.h" -#include "ProcessMonitor.h" - - -#define DEBUG_PTRACE_MAXBYTES 20 - -using namespace lldb_private; - -// FIXME: this code is host-dependent with respect to types and -// endianness and needs to be fixed. For example, lldb::addr_t is -// hard-coded to uint64_t, but on a 32-bit Linux host, ptrace requires -// 32-bit pointer arguments. This code uses casts to work around the -// problem. - -// We disable the tracing of ptrace calls for integration builds to -// avoid the additional indirection and checks. -#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION - -static void -DisplayBytes (lldb_private::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++; - } -} - -static void PtraceDisplayBytes(__ptrace_request &req, void *data) -{ - StreamString buf; - LogSP verbose_log (ProcessPOSIXLog::GetLogIfAllCategoriesSet ( - POSIX_LOG_PTRACE | POSIX_LOG_VERBOSE)); - - if (verbose_log) - { - switch(req) - { - case PTRACE_POKETEXT: - { - DisplayBytes(buf, &data, 8); - verbose_log->Printf("PTRACE_POKETEXT %s", buf.GetData()); - break; - } - case PTRACE_POKEDATA: - { - DisplayBytes(buf, &data, 8); - verbose_log->Printf("PTRACE_POKEDATA %s", buf.GetData()); - break; - } - case PTRACE_POKEUSER: - { - DisplayBytes(buf, &data, 8); - verbose_log->Printf("PTRACE_POKEUSER %s", buf.GetData()); - break; - } - case PTRACE_SETREGS: - { - DisplayBytes(buf, data, sizeof(user_regs_struct)); - verbose_log->Printf("PTRACE_SETREGS %s", buf.GetData()); - break; - } - case PTRACE_SETFPREGS: - { - DisplayBytes(buf, data, sizeof(user_fpregs_struct)); - verbose_log->Printf("PTRACE_SETFPREGS %s", buf.GetData()); - break; - } - case PTRACE_SETSIGINFO: - { - DisplayBytes(buf, data, sizeof(siginfo_t)); - verbose_log->Printf("PTRACE_SETSIGINFO %s", buf.GetData()); - break; - } - default: - { - } - } - } -} - -// Wrapper for ptrace to catch errors and log calls. -extern long -PtraceWrapper(__ptrace_request req, pid_t pid, void *addr, void *data, - const char* reqName, const char* file, int line) -{ - long int result; - - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PTRACE)); - - if (log) - log->Printf("ptrace(%s, %u, %p, %p) called from file %s line %d", - reqName, pid, addr, data, file, line); - - PtraceDisplayBytes(req, data); - - errno = 0; - result = ptrace(req, pid, addr, data); - - PtraceDisplayBytes(req, data); - - if (log && (result == -1 || errno != 0)) - { - const char* str; - switch (errno) - { - case ESRCH: str = "ESRCH"; break; - case EINVAL: str = "EINVAL"; break; - case EBUSY: str = "EBUSY"; break; - case EPERM: str = "EPERM"; break; - default: str = "<unknown>"; - } - log->Printf("ptrace() failed; errno=%d (%s)", errno, str); - } - - return result; -} - -#define PTRACE(req, pid, addr, data) \ - PtraceWrapper((req), (pid), (addr), (data), #req, __FILE__, __LINE__) -#else -#define PTRACE ptrace -#endif - -//------------------------------------------------------------------------------ -// Static implementations of ProcessMonitor::ReadMemory and -// ProcessMonitor::WriteMemory. This enables mutual recursion between these -// functions without needed to go thru the thread funnel. - -static size_t -DoReadMemory(lldb::pid_t pid, unsigned word_size, - lldb::addr_t vm_addr, void *buf, size_t size, Error &error) -{ - unsigned char *dst = static_cast<unsigned char*>(buf); - size_t bytes_read; - size_t remainder; - long data; - - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL)); - if (log) - ProcessPOSIXLog::IncNestLevel(); - if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY)) - log->Printf ("ProcessMonitor::%s(%d, %d, %p, %p, %d, _)", __FUNCTION__, - pid, word_size, (void*)vm_addr, buf, size); - - assert(sizeof(data) >= word_size); - assert(sizeof(void*) == word_size); - for (bytes_read = 0; bytes_read < size; bytes_read += remainder) - { - errno = 0; - data = PTRACE(PTRACE_PEEKDATA, pid, (void*)vm_addr, NULL); - if (data == -1L && errno) - { - error.SetErrorToErrno(); - if (log) - ProcessPOSIXLog::DecNestLevel(); - return bytes_read; - } - - remainder = size - bytes_read; - remainder = remainder > word_size ? word_size : remainder; - - // Copy the data into our buffer - if (log) - memset(dst, 0, sizeof(dst)); - for (unsigned i = 0; i < remainder; ++i) - dst[i] = ((data >> i*8) & 0xFF); - - if (log && ProcessPOSIXLog::AtTopNestLevel() && - (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) || - (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) && - size <= POSIX_LOG_MEMORY_SHORT_BYTES))) - log->Printf ("ProcessMonitor::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__, - (void*)vm_addr, *(unsigned long*)dst, (unsigned long)data); - - vm_addr += word_size; - dst += word_size; - } - - if (log) - ProcessPOSIXLog::DecNestLevel(); - return bytes_read; -} - -static size_t -DoWriteMemory(lldb::pid_t pid, unsigned word_size, - lldb::addr_t vm_addr, const void *buf, size_t size, Error &error) -{ - const unsigned char *src = static_cast<const unsigned char*>(buf); - size_t bytes_written = 0; - size_t remainder; - - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL)); - if (log) - ProcessPOSIXLog::IncNestLevel(); - if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY)) - log->Printf ("ProcessMonitor::%s(%d, %d, %p, %p, %d, _)", __FUNCTION__, - pid, word_size, (void*)vm_addr, buf, size); - - assert(sizeof(void*) == word_size); - for (bytes_written = 0; bytes_written < size; bytes_written += remainder) - { - remainder = size - bytes_written; - remainder = remainder > word_size ? word_size : remainder; - - if (remainder == word_size) - { - unsigned long data = 0; - assert(sizeof(data) >= word_size); - for (unsigned i = 0; i < word_size; ++i) - data |= (unsigned long)src[i] << i*8; - - if (log && ProcessPOSIXLog::AtTopNestLevel() && - (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) || - (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) && - size <= POSIX_LOG_MEMORY_SHORT_BYTES))) - log->Printf ("ProcessMonitor::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__, - (void*)vm_addr, *(unsigned long*)src, data); - - if (PTRACE(PTRACE_POKEDATA, pid, (void*)vm_addr, (void*)data)) - { - error.SetErrorToErrno(); - if (log) - ProcessPOSIXLog::DecNestLevel(); - return bytes_written; - } - } - else - { - unsigned char buff[8]; - if (DoReadMemory(pid, word_size, vm_addr, - buff, word_size, error) != word_size) - { - if (log) - ProcessPOSIXLog::DecNestLevel(); - return bytes_written; - } - - memcpy(buff, src, remainder); - - if (DoWriteMemory(pid, word_size, vm_addr, - buff, word_size, error) != word_size) - { - if (log) - ProcessPOSIXLog::DecNestLevel(); - return bytes_written; - } - - if (log && ProcessPOSIXLog::AtTopNestLevel() && - (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) || - (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) && - size <= POSIX_LOG_MEMORY_SHORT_BYTES))) - log->Printf ("ProcessMonitor::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__, - (void*)vm_addr, *(unsigned long*)src, *(unsigned long*)buff); - } - - vm_addr += word_size; - src += word_size; - } - if (log) - ProcessPOSIXLog::DecNestLevel(); - return bytes_written; -} - -// Simple helper function to ensure flags are enabled on the given file -// descriptor. -static bool -EnsureFDFlags(int fd, int flags, Error &error) -{ - int status; - - if ((status = fcntl(fd, F_GETFL)) == -1) - { - error.SetErrorToErrno(); - return false; - } - - if (fcntl(fd, F_SETFL, status | flags) == -1) - { - error.SetErrorToErrno(); - return false; - } - - return true; -} - -//------------------------------------------------------------------------------ -/// @class Operation -/// @brief Represents a ProcessMonitor operation. -/// -/// Under Linux, it is not possible to ptrace() from any other thread but the -/// one that spawned or attached to the process from the start. Therefore, when -/// a ProcessMonitor is asked to deliver or change the state of an inferior -/// process the operation must be "funneled" to a specific thread to perform the -/// task. The Operation class provides an abstract base for all services the -/// ProcessMonitor must perform via the single virtual function Execute, thus -/// encapsulating the code that needs to run in the privileged context. -class Operation -{ -public: - virtual void Execute(ProcessMonitor *monitor) = 0; -}; - -//------------------------------------------------------------------------------ -/// @class ReadOperation -/// @brief Implements ProcessMonitor::ReadMemory. -class ReadOperation : public Operation -{ -public: - ReadOperation(lldb::addr_t addr, void *buff, size_t size, - Error &error, size_t &result) - : m_addr(addr), m_buff(buff), m_size(size), - m_error(error), m_result(result) - { } - - void Execute(ProcessMonitor *monitor); - -private: - lldb::addr_t m_addr; - void *m_buff; - size_t m_size; - Error &m_error; - size_t &m_result; -}; - -void -ReadOperation::Execute(ProcessMonitor *monitor) -{ - const unsigned word_size = monitor->GetProcess().GetAddressByteSize(); - lldb::pid_t pid = monitor->GetPID(); - - m_result = DoReadMemory(pid, word_size, m_addr, m_buff, m_size, m_error); -} - -//------------------------------------------------------------------------------ -/// @class ReadOperation -/// @brief Implements ProcessMonitor::WriteMemory. -class WriteOperation : public Operation -{ -public: - WriteOperation(lldb::addr_t addr, const void *buff, size_t size, - Error &error, size_t &result) - : m_addr(addr), m_buff(buff), m_size(size), - m_error(error), m_result(result) - { } - - void Execute(ProcessMonitor *monitor); - -private: - lldb::addr_t m_addr; - const void *m_buff; - size_t m_size; - Error &m_error; - size_t &m_result; -}; - -void -WriteOperation::Execute(ProcessMonitor *monitor) -{ - const unsigned word_size = monitor->GetProcess().GetAddressByteSize(); - lldb::pid_t pid = monitor->GetPID(); - - m_result = DoWriteMemory(pid, word_size, m_addr, m_buff, m_size, m_error); -} - - -//------------------------------------------------------------------------------ -/// @class ReadRegOperation -/// @brief Implements ProcessMonitor::ReadRegisterValue. -class ReadRegOperation : public Operation -{ -public: - ReadRegOperation(unsigned offset, RegisterValue &value, bool &result) - : m_offset(offset), m_value(value), m_result(result) - { } - - void Execute(ProcessMonitor *monitor); - -private: - unsigned m_offset; - RegisterValue &m_value; - bool &m_result; -}; - -void -ReadRegOperation::Execute(ProcessMonitor *monitor) -{ - lldb::pid_t pid = monitor->GetPID(); - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS)); - - // Set errno to zero so that we can detect a failed peek. - errno = 0; - lldb::addr_t data = PTRACE(PTRACE_PEEKUSER, pid, (void*)m_offset, NULL); - if (data == -1UL && errno) - m_result = false; - else - { - m_value = data; - m_result = true; - } - if (log) - log->Printf ("ProcessMonitor::%s() reg %s: 0x%x", __FUNCTION__, - POSIXThread::GetRegisterNameFromOffset(m_offset), data); -} - -//------------------------------------------------------------------------------ -/// @class WriteRegOperation -/// @brief Implements ProcessMonitor::WriteRegisterValue. -class WriteRegOperation : public Operation -{ -public: - WriteRegOperation(unsigned offset, const RegisterValue &value, bool &result) - : m_offset(offset), m_value(value), m_result(result) - { } - - void Execute(ProcessMonitor *monitor); - -private: - unsigned m_offset; - const RegisterValue &m_value; - bool &m_result; -}; - -void -WriteRegOperation::Execute(ProcessMonitor *monitor) -{ - void* buf; - lldb::pid_t pid = monitor->GetPID(); - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS)); - - if (sizeof(void*) == sizeof(uint64_t)) - buf = (void*) m_value.GetAsUInt64(); - else - { - assert(sizeof(void*) == sizeof(uint32_t)); - buf = (void*) m_value.GetAsUInt32(); - } - - if (log) - log->Printf ("ProcessMonitor::%s() reg %s: %p", __FUNCTION__, - POSIXThread::GetRegisterNameFromOffset(m_offset), buf); - if (PTRACE(PTRACE_POKEUSER, pid, (void*)m_offset, buf)) - m_result = false; - else - m_result = true; -} - -//------------------------------------------------------------------------------ -/// @class ReadGPROperation -/// @brief Implements ProcessMonitor::ReadGPR. -class ReadGPROperation : public Operation -{ -public: - ReadGPROperation(void *buf, bool &result) - : m_buf(buf), m_result(result) - { } - - void Execute(ProcessMonitor *monitor); - -private: - void *m_buf; - bool &m_result; -}; - -void -ReadGPROperation::Execute(ProcessMonitor *monitor) -{ - if (PTRACE(PTRACE_GETREGS, monitor->GetPID(), NULL, m_buf) < 0) - m_result = false; - else - m_result = true; -} - -//------------------------------------------------------------------------------ -/// @class ReadFPROperation -/// @brief Implements ProcessMonitor::ReadFPR. -class ReadFPROperation : public Operation -{ -public: - ReadFPROperation(void *buf, bool &result) - : m_buf(buf), m_result(result) - { } - - void Execute(ProcessMonitor *monitor); - -private: - void *m_buf; - bool &m_result; -}; - -void -ReadFPROperation::Execute(ProcessMonitor *monitor) -{ - if (PTRACE(PTRACE_GETFPREGS, monitor->GetPID(), NULL, m_buf) < 0) - m_result = false; - else - m_result = true; -} - -//------------------------------------------------------------------------------ -/// @class WriteGPROperation -/// @brief Implements ProcessMonitor::WriteGPR. -class WriteGPROperation : public Operation -{ -public: - WriteGPROperation(void *buf, bool &result) - : m_buf(buf), m_result(result) - { } - - void Execute(ProcessMonitor *monitor); - -private: - void *m_buf; - bool &m_result; -}; - -void -WriteGPROperation::Execute(ProcessMonitor *monitor) -{ - if (PTRACE(PTRACE_SETREGS, monitor->GetPID(), NULL, m_buf) < 0) - m_result = false; - else - m_result = true; -} - -//------------------------------------------------------------------------------ -/// @class WriteFPROperation -/// @brief Implements ProcessMonitor::WriteFPR. -class WriteFPROperation : public Operation -{ -public: - WriteFPROperation(void *buf, bool &result) - : m_buf(buf), m_result(result) - { } - - void Execute(ProcessMonitor *monitor); - -private: - void *m_buf; - bool &m_result; -}; - -void -WriteFPROperation::Execute(ProcessMonitor *monitor) -{ - if (PTRACE(PTRACE_SETFPREGS, monitor->GetPID(), NULL, m_buf) < 0) - m_result = false; - else - m_result = true; -} - -//------------------------------------------------------------------------------ -/// @class ResumeOperation -/// @brief Implements ProcessMonitor::Resume. -class ResumeOperation : public Operation -{ -public: - ResumeOperation(lldb::tid_t tid, uint32_t signo, bool &result) : - m_tid(tid), m_signo(signo), m_result(result) { } - - void Execute(ProcessMonitor *monitor); - -private: - lldb::tid_t m_tid; - uint32_t m_signo; - bool &m_result; -}; - -void -ResumeOperation::Execute(ProcessMonitor *monitor) -{ - int data = 0; - - if (m_signo != LLDB_INVALID_SIGNAL_NUMBER) - data = m_signo; - - if (PTRACE(PTRACE_CONT, m_tid, NULL, (void*)data)) - m_result = false; - else - m_result = true; -} - -//------------------------------------------------------------------------------ -/// @class ResumeOperation -/// @brief Implements ProcessMonitor::SingleStep. -class SingleStepOperation : public Operation -{ -public: - SingleStepOperation(lldb::tid_t tid, uint32_t signo, bool &result) - : m_tid(tid), m_signo(signo), m_result(result) { } - - void Execute(ProcessMonitor *monitor); - -private: - lldb::tid_t m_tid; - uint32_t m_signo; - bool &m_result; -}; - -void -SingleStepOperation::Execute(ProcessMonitor *monitor) -{ - int data = 0; - - if (m_signo != LLDB_INVALID_SIGNAL_NUMBER) - data = m_signo; - - if (PTRACE(PTRACE_SINGLESTEP, m_tid, NULL, (void*)data)) - m_result = false; - else - m_result = true; -} - -//------------------------------------------------------------------------------ -/// @class SiginfoOperation -/// @brief Implements ProcessMonitor::GetSignalInfo. -class SiginfoOperation : public Operation -{ -public: - SiginfoOperation(lldb::tid_t tid, void *info, bool &result) - : m_tid(tid), m_info(info), m_result(result) { } - - void Execute(ProcessMonitor *monitor); - -private: - lldb::tid_t m_tid; - void *m_info; - bool &m_result; -}; - -void -SiginfoOperation::Execute(ProcessMonitor *monitor) -{ - if (PTRACE(PTRACE_GETSIGINFO, m_tid, NULL, m_info)) - m_result = false; - else - m_result = true; -} - -//------------------------------------------------------------------------------ -/// @class EventMessageOperation -/// @brief Implements ProcessMonitor::GetEventMessage. -class EventMessageOperation : public Operation -{ -public: - EventMessageOperation(lldb::tid_t tid, unsigned long *message, bool &result) - : m_tid(tid), m_message(message), m_result(result) { } - - void Execute(ProcessMonitor *monitor); - -private: - lldb::tid_t m_tid; - unsigned long *m_message; - bool &m_result; -}; - -void -EventMessageOperation::Execute(ProcessMonitor *monitor) -{ - if (PTRACE(PTRACE_GETEVENTMSG, m_tid, NULL, m_message)) - m_result = false; - else - m_result = true; -} - -//------------------------------------------------------------------------------ -/// @class KillOperation -/// @brief Implements ProcessMonitor::BringProcessIntoLimbo. -class KillOperation : public Operation -{ -public: - KillOperation(bool &result) : m_result(result) { } - - void Execute(ProcessMonitor *monitor); - -private: - bool &m_result; -}; - -void -KillOperation::Execute(ProcessMonitor *monitor) -{ - lldb::pid_t pid = monitor->GetPID(); - - if (PTRACE(PTRACE_KILL, pid, NULL, NULL)) - m_result = false; - else - m_result = true; -} - -//------------------------------------------------------------------------------ -/// @class KillOperation -/// @brief Implements ProcessMonitor::BringProcessIntoLimbo. -class DetachOperation : public Operation -{ -public: - DetachOperation(Error &result) : m_error(result) { } - - void Execute(ProcessMonitor *monitor); - -private: - Error &m_error; -}; - -void -DetachOperation::Execute(ProcessMonitor *monitor) -{ - lldb::pid_t pid = monitor->GetPID(); - - if (ptrace(PT_DETACH, pid, NULL, 0) < 0) - m_error.SetErrorToErrno(); - -} - -ProcessMonitor::OperationArgs::OperationArgs(ProcessMonitor *monitor) - : m_monitor(monitor) -{ - sem_init(&m_semaphore, 0, 0); -} - -ProcessMonitor::OperationArgs::~OperationArgs() -{ - sem_destroy(&m_semaphore); -} - -ProcessMonitor::LaunchArgs::LaunchArgs(ProcessMonitor *monitor, - lldb_private::Module *module, - char const **argv, - char const **envp, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path) - : OperationArgs(monitor), - m_module(module), - m_argv(argv), - m_envp(envp), - m_stdin_path(stdin_path), - m_stdout_path(stdout_path), - m_stderr_path(stderr_path) { } - -ProcessMonitor::LaunchArgs::~LaunchArgs() -{ } - -ProcessMonitor::AttachArgs::AttachArgs(ProcessMonitor *monitor, - lldb::pid_t pid) - : OperationArgs(monitor), m_pid(pid) { } - -ProcessMonitor::AttachArgs::~AttachArgs() -{ } - -//------------------------------------------------------------------------------ -/// The basic design of the ProcessMonitor is built around two threads. -/// -/// One thread (@see SignalThread) simply blocks on a call to waitpid() looking -/// for changes in the debugee state. When a change is detected a -/// ProcessMessage is sent to the associated ProcessLinux instance. This thread -/// "drives" state changes in the debugger. -/// -/// The second thread (@see OperationThread) is responsible for two things 1) -/// launching or attaching to the inferior process, and then 2) servicing -/// operations such as register reads/writes, stepping, etc. See the comments -/// on the Operation class for more info as to why this is needed. -ProcessMonitor::ProcessMonitor(ProcessPOSIX *process, - Module *module, - const char *argv[], - const char *envp[], - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - lldb_private::Error &error) - : m_process(static_cast<ProcessLinux *>(process)), - m_operation_thread(LLDB_INVALID_HOST_THREAD), - m_pid(LLDB_INVALID_PROCESS_ID), - m_terminal_fd(-1), - m_monitor_thread(LLDB_INVALID_HOST_THREAD), - m_client_fd(-1), - m_server_fd(-1) -{ - std::auto_ptr<LaunchArgs> args; - - args.reset(new LaunchArgs(this, module, argv, envp, - stdin_path, stdout_path, stderr_path)); - - // Server/client descriptors. - if (!EnableIPC()) - { - error.SetErrorToGenericError(); - error.SetErrorString("Monitor failed to initialize."); - } - - StartLaunchOpThread(args.get(), error); - if (!error.Success()) - return; - -WAIT_AGAIN: - // Wait for the operation thread to initialize. - if (sem_wait(&args->m_semaphore)) - { - if (errno == EINTR) - goto WAIT_AGAIN; - else - { - error.SetErrorToErrno(); - return; - } - } - - // Check that the launch was a success. - if (!args->m_error.Success()) - { - StopLaunchOpThread(); - error = args->m_error; - return; - } - - // Finally, start monitoring the child process for change in state. - m_monitor_thread = Host::StartMonitoringChildProcess( - ProcessMonitor::MonitorCallback, this, GetPID(), true); - if (!IS_VALID_LLDB_HOST_THREAD(m_monitor_thread)) - { - error.SetErrorToGenericError(); - error.SetErrorString("Process launch failed."); - return; - } -} - -ProcessMonitor::ProcessMonitor(ProcessPOSIX *process, - lldb::pid_t pid, - lldb_private::Error &error) - : m_process(static_cast<ProcessLinux *>(process)), - m_operation_thread(LLDB_INVALID_HOST_THREAD), - m_pid(LLDB_INVALID_PROCESS_ID), - m_terminal_fd(-1), - m_monitor_thread(LLDB_INVALID_HOST_THREAD), - m_client_fd(-1), - m_server_fd(-1) -{ - std::auto_ptr<AttachArgs> args; - - args.reset(new AttachArgs(this, pid)); - - // Server/client descriptors. - if (!EnableIPC()) - { - error.SetErrorToGenericError(); - error.SetErrorString("Monitor failed to initialize."); - } - - StartAttachOpThread(args.get(), error); - if (!error.Success()) - return; - -WAIT_AGAIN: - // Wait for the operation thread to initialize. - if (sem_wait(&args->m_semaphore)) - { - if (errno == EINTR) - goto WAIT_AGAIN; - else - { - error.SetErrorToErrno(); - return; - } - } - - // Check that the launch was a success. - if (!args->m_error.Success()) - { - StopAttachOpThread(); - error = args->m_error; - return; - } - - // Finally, start monitoring the child process for change in state. - m_monitor_thread = Host::StartMonitoringChildProcess( - ProcessMonitor::MonitorCallback, this, GetPID(), true); - if (!IS_VALID_LLDB_HOST_THREAD(m_monitor_thread)) - { - error.SetErrorToGenericError(); - error.SetErrorString("Process attach failed."); - return; - } -} - -ProcessMonitor::~ProcessMonitor() -{ - StopMonitor(); -} - -//------------------------------------------------------------------------------ -// Thread setup and tear down. -void -ProcessMonitor::StartLaunchOpThread(LaunchArgs *args, Error &error) -{ - static const char *g_thread_name = "lldb.process.linux.operation"; - - if (IS_VALID_LLDB_HOST_THREAD(m_operation_thread)) - return; - - m_operation_thread = - Host::ThreadCreate(g_thread_name, LaunchOpThread, args, &error); -} - -void -ProcessMonitor::StopLaunchOpThread() -{ - lldb::thread_result_t result; - - if (!IS_VALID_LLDB_HOST_THREAD(m_operation_thread)) - return; - - Host::ThreadCancel(m_operation_thread, NULL); - Host::ThreadJoin(m_operation_thread, &result, NULL); -} - -void * -ProcessMonitor::LaunchOpThread(void *arg) -{ - LaunchArgs *args = static_cast<LaunchArgs*>(arg); - - if (!Launch(args)) { - sem_post(&args->m_semaphore); - return NULL; - } - - ServeOperation(args); - return NULL; -} - -bool -ProcessMonitor::Launch(LaunchArgs *args) -{ - ProcessMonitor *monitor = args->m_monitor; - ProcessLinux &process = monitor->GetProcess(); - lldb::ProcessSP processSP = process.shared_from_this(); - const char **argv = args->m_argv; - const char **envp = args->m_envp; - const char *stdin_path = args->m_stdin_path; - const char *stdout_path = args->m_stdout_path; - const char *stderr_path = args->m_stderr_path; - - lldb_utility::PseudoTerminal terminal; - const size_t err_len = 1024; - char err_str[err_len]; - lldb::pid_t pid; - - lldb::ThreadSP inferior; - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); - - // Propagate the environment if one is not supplied. - if (envp == NULL || envp[0] == NULL) - envp = const_cast<const char **>(environ); - - // Pseudo terminal setup. - if (!terminal.OpenFirstAvailableMaster(O_RDWR | O_NOCTTY, err_str, err_len)) - { - args->m_error.SetErrorToGenericError(); - args->m_error.SetErrorString("Could not open controlling TTY."); - goto FINISH; - } - - if ((pid = terminal.Fork(err_str, err_len)) < 0) - { - args->m_error.SetErrorToGenericError(); - args->m_error.SetErrorString("Process fork failed."); - goto FINISH; - } - - // Recognized child exit status codes. - enum { - ePtraceFailed = 1, - eDupStdinFailed, - eDupStdoutFailed, - eDupStderrFailed, - eExecFailed - }; - - // Child process. - if (pid == 0) - { - // Trace this process. - if (PTRACE(PTRACE_TRACEME, 0, NULL, NULL) < 0) - exit(ePtraceFailed); - - // Do not inherit setgid powers. - setgid(getgid()); - - // Let us have our own process group. - setpgid(0, 0); - - // Dup file descriptors if needed. - // - // FIXME: If two or more of the paths are the same we needlessly open - // the same file multiple times. - if (stdin_path != NULL && stdin_path[0]) - if (!DupDescriptor(stdin_path, STDIN_FILENO, O_RDONLY)) - exit(eDupStdinFailed); - - if (stdout_path != NULL && stdout_path[0]) - if (!DupDescriptor(stdout_path, STDOUT_FILENO, O_WRONLY | O_CREAT)) - exit(eDupStdoutFailed); - - if (stderr_path != NULL && stderr_path[0]) - if (!DupDescriptor(stderr_path, STDERR_FILENO, O_WRONLY | O_CREAT)) - exit(eDupStderrFailed); - - // Execute. We should never return. - execve(argv[0], - const_cast<char *const *>(argv), - const_cast<char *const *>(envp)); - exit(eExecFailed); - } - - // Wait for the child process to to trap on its call to execve. - pid_t wpid; - int status; - if ((wpid = waitpid(pid, &status, 0)) < 0) - { - args->m_error.SetErrorToErrno(); - goto FINISH; - } - else if (WIFEXITED(status)) - { - // open, dup or execve likely failed for some reason. - args->m_error.SetErrorToGenericError(); - switch (WEXITSTATUS(status)) - { - case ePtraceFailed: - args->m_error.SetErrorString("Child ptrace failed."); - break; - case eDupStdinFailed: - args->m_error.SetErrorString("Child open stdin failed."); - break; - case eDupStdoutFailed: - args->m_error.SetErrorString("Child open stdout failed."); - break; - case eDupStderrFailed: - args->m_error.SetErrorString("Child open stderr failed."); - break; - case eExecFailed: - args->m_error.SetErrorString("Child exec failed."); - break; - default: - args->m_error.SetErrorString("Child returned unknown exit status."); - break; - } - goto FINISH; - } - assert(WIFSTOPPED(status) && wpid == pid && - "Could not sync with inferior process."); - - // Have the child raise an event on exit. This is used to keep the child in - // limbo until it is destroyed. - if (PTRACE(PTRACE_SETOPTIONS, pid, NULL, (void*)PTRACE_O_TRACEEXIT) < 0) - { - args->m_error.SetErrorToErrno(); - goto FINISH; - } - - // Release the master terminal descriptor and pass it off to the - // ProcessMonitor instance. Similarly stash the inferior pid. - monitor->m_terminal_fd = terminal.ReleaseMasterFileDescriptor(); - monitor->m_pid = pid; - - // Set the terminal fd to be in non blocking mode (it simplifies the - // implementation of ProcessLinux::GetSTDOUT to have a non-blocking - // descriptor to read from). - if (!EnsureFDFlags(monitor->m_terminal_fd, O_NONBLOCK, args->m_error)) - goto FINISH; - - // Update the process thread list with this new thread. - // FIXME: should we be letting UpdateThreadList handle this? - // FIXME: by using pids instead of tids, we can only support one thread. - inferior.reset(new POSIXThread(processSP, pid)); - if (log) - log->Printf ("ProcessMonitor::%s() adding pid = %i", __FUNCTION__, pid); - process.GetThreadList().AddThread(inferior); - - // Let our process instance know the thread has stopped. - process.SendMessage(ProcessMessage::Trace(pid)); - -FINISH: - return args->m_error.Success(); -} - -bool -ProcessMonitor::EnableIPC() -{ - int fd[2]; - - if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) - return false; - - m_client_fd = fd[0]; - m_server_fd = fd[1]; - return true; -} - -void -ProcessMonitor::StartAttachOpThread(AttachArgs *args, lldb_private::Error &error) -{ - static const char *g_thread_name = "lldb.process.linux.operation"; - - if (IS_VALID_LLDB_HOST_THREAD(m_operation_thread)) - return; - - m_operation_thread = - Host::ThreadCreate(g_thread_name, AttachOpThread, args, &error); -} - -void -ProcessMonitor::StopAttachOpThread() -{ - assert(!"Not implemented yet!!!"); -} - -void * -ProcessMonitor::AttachOpThread(void *arg) -{ - AttachArgs *args = static_cast<AttachArgs*>(arg); - - if (!Attach(args)) - return NULL; - - ServeOperation(args); - return NULL; -} - -bool -ProcessMonitor::Attach(AttachArgs *args) -{ - lldb::pid_t pid = args->m_pid; - - ProcessMonitor *monitor = args->m_monitor; - ProcessLinux &process = monitor->GetProcess(); - lldb::ProcessSP processSP = process.shared_from_this(); - lldb::ThreadSP inferior; - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); - - if (pid <= 1) - { - args->m_error.SetErrorToGenericError(); - args->m_error.SetErrorString("Attaching to process 1 is not allowed."); - goto FINISH; - } - - // Attach to the requested process. - if (PTRACE(PTRACE_ATTACH, pid, NULL, NULL) < 0) - { - args->m_error.SetErrorToErrno(); - goto FINISH; - } - - int status; - if ((status = waitpid(pid, NULL, 0)) < 0) - { - args->m_error.SetErrorToErrno(); - goto FINISH; - } - - // Update the process thread list with the attached thread. - inferior.reset(new POSIXThread(processSP, pid)); - if (log) - log->Printf ("ProcessMonitor::%s() adding tid = %i", __FUNCTION__, pid); - process.GetThreadList().AddThread(inferior); - - // Let our process instance know the thread has stopped. - process.SendMessage(ProcessMessage::Trace(pid)); - - FINISH: - return args->m_error.Success(); -} - -bool -ProcessMonitor::MonitorCallback(void *callback_baton, - lldb::pid_t pid, - bool exited, - int signal, - int status) -{ - ProcessMessage message; - ProcessMonitor *monitor = static_cast<ProcessMonitor*>(callback_baton); - ProcessLinux *process = monitor->m_process; - assert(process); - bool stop_monitoring; - siginfo_t info; - - if (!monitor->GetSignalInfo(pid, &info)) - stop_monitoring = true; // pid is gone. Bail. - else { - switch (info.si_signo) - { - case SIGTRAP: - message = MonitorSIGTRAP(monitor, &info, pid); - break; - - default: - message = MonitorSignal(monitor, &info, pid); - break; - } - - process->SendMessage(message); - stop_monitoring = message.GetKind() == ProcessMessage::eExitMessage; - } - - return stop_monitoring; -} - -ProcessMessage -ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor, - const siginfo_t *info, lldb::pid_t pid) -{ - ProcessMessage message; - - assert(monitor); - assert(info && info->si_signo == SIGTRAP && "Unexpected child signal!"); - - switch (info->si_code) - { - default: - assert(false && "Unexpected SIGTRAP code!"); - break; - - case (SIGTRAP | (PTRACE_EVENT_EXIT << 8)): - { - // The inferior process is about to exit. Maintain the process in a - // state of "limbo" until we are explicitly commanded to detach, - // destroy, resume, etc. - unsigned long data = 0; - if (!monitor->GetEventMessage(pid, &data)) - data = -1; - message = ProcessMessage::Limbo(pid, (data >> 8)); - break; - } - - case 0: - case TRAP_TRACE: - message = ProcessMessage::Trace(pid); - break; - - case SI_KERNEL: - case TRAP_BRKPT: - message = ProcessMessage::Break(pid); - break; - } - - return message; -} - -ProcessMessage -ProcessMonitor::MonitorSignal(ProcessMonitor *monitor, - const siginfo_t *info, lldb::pid_t pid) -{ - ProcessMessage message; - int signo = info->si_signo; - - // 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. - if (info->si_code == SI_TKILL || info->si_code == SI_USER) - { - if (info->si_pid == getpid()) - return ProcessMessage::SignalDelivered(pid, signo); - else - return ProcessMessage::Signal(pid, signo); - } - - if (signo == SIGSEGV) { - lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr); - ProcessMessage::CrashReason reason = GetCrashReasonForSIGSEGV(info); - return ProcessMessage::Crash(pid, reason, signo, fault_addr); - } - - if (signo == SIGILL) { - lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr); - ProcessMessage::CrashReason reason = GetCrashReasonForSIGILL(info); - return ProcessMessage::Crash(pid, reason, signo, fault_addr); - } - - if (signo == SIGFPE) { - lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr); - ProcessMessage::CrashReason reason = GetCrashReasonForSIGFPE(info); - return ProcessMessage::Crash(pid, reason, signo, fault_addr); - } - - if (signo == SIGBUS) { - lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr); - ProcessMessage::CrashReason reason = GetCrashReasonForSIGBUS(info); - return ProcessMessage::Crash(pid, reason, signo, fault_addr); - } - - // Everything else is "normal" and does not require any special action on - // our part. - return ProcessMessage::Signal(pid, signo); -} - -ProcessMessage::CrashReason -ProcessMonitor::GetCrashReasonForSIGSEGV(const siginfo_t *info) -{ - ProcessMessage::CrashReason reason; - assert(info->si_signo == SIGSEGV); - - reason = ProcessMessage::eInvalidCrashReason; - - switch (info->si_code) - { - default: - assert(false && "unexpected si_code for SIGSEGV"); - break; - case SEGV_MAPERR: - reason = ProcessMessage::eInvalidAddress; - break; - case SEGV_ACCERR: - reason = ProcessMessage::ePrivilegedAddress; - break; - } - - return reason; -} - -ProcessMessage::CrashReason -ProcessMonitor::GetCrashReasonForSIGILL(const siginfo_t *info) -{ - ProcessMessage::CrashReason reason; - assert(info->si_signo == SIGILL); - - reason = ProcessMessage::eInvalidCrashReason; - - switch (info->si_code) - { - default: - assert(false && "unexpected si_code for SIGILL"); - break; - case ILL_ILLOPC: - reason = ProcessMessage::eIllegalOpcode; - break; - case ILL_ILLOPN: - reason = ProcessMessage::eIllegalOperand; - break; - case ILL_ILLADR: - reason = ProcessMessage::eIllegalAddressingMode; - break; - case ILL_ILLTRP: - reason = ProcessMessage::eIllegalTrap; - break; - case ILL_PRVOPC: - reason = ProcessMessage::ePrivilegedOpcode; - break; - case ILL_PRVREG: - reason = ProcessMessage::ePrivilegedRegister; - break; - case ILL_COPROC: - reason = ProcessMessage::eCoprocessorError; - break; - case ILL_BADSTK: - reason = ProcessMessage::eInternalStackError; - break; - } - - return reason; -} - -ProcessMessage::CrashReason -ProcessMonitor::GetCrashReasonForSIGFPE(const siginfo_t *info) -{ - ProcessMessage::CrashReason reason; - assert(info->si_signo == SIGFPE); - - reason = ProcessMessage::eInvalidCrashReason; - - switch (info->si_code) - { - default: - assert(false && "unexpected si_code for SIGFPE"); - break; - case FPE_INTDIV: - reason = ProcessMessage::eIntegerDivideByZero; - break; - case FPE_INTOVF: - reason = ProcessMessage::eIntegerOverflow; - break; - case FPE_FLTDIV: - reason = ProcessMessage::eFloatDivideByZero; - break; - case FPE_FLTOVF: - reason = ProcessMessage::eFloatOverflow; - break; - case FPE_FLTUND: - reason = ProcessMessage::eFloatUnderflow; - break; - case FPE_FLTRES: - reason = ProcessMessage::eFloatInexactResult; - break; - case FPE_FLTINV: - reason = ProcessMessage::eFloatInvalidOperation; - break; - case FPE_FLTSUB: - reason = ProcessMessage::eFloatSubscriptRange; - break; - } - - return reason; -} - -ProcessMessage::CrashReason -ProcessMonitor::GetCrashReasonForSIGBUS(const siginfo_t *info) -{ - ProcessMessage::CrashReason reason; - assert(info->si_signo == SIGBUS); - - reason = ProcessMessage::eInvalidCrashReason; - - switch (info->si_code) - { - default: - assert(false && "unexpected si_code for SIGBUS"); - break; - case BUS_ADRALN: - reason = ProcessMessage::eIllegalAlignment; - break; - case BUS_ADRERR: - reason = ProcessMessage::eIllegalAddress; - break; - case BUS_OBJERR: - reason = ProcessMessage::eHardwareError; - break; - } - - return reason; -} - -void -ProcessMonitor::ServeOperation(OperationArgs *args) -{ - int status; - pollfd fdset; - - ProcessMonitor *monitor = args->m_monitor; - - fdset.fd = monitor->m_server_fd; - fdset.events = POLLIN | POLLPRI; - fdset.revents = 0; - - // We are finised with the arguments and are ready to go. Sync with the - // parent thread and start serving operations on the inferior. - sem_post(&args->m_semaphore); - - for (;;) - { - if ((status = poll(&fdset, 1, -1)) < 0) - { - switch (errno) - { - default: - assert(false && "Unexpected poll() failure!"); - continue; - - case EINTR: continue; // Just poll again. - case EBADF: return; // Connection terminated. - } - } - - assert(status == 1 && "Too many descriptors!"); - - if (fdset.revents & POLLIN) - { - Operation *op = NULL; - - READ_AGAIN: - if ((status = read(fdset.fd, &op, sizeof(op))) < 0) - { - // There is only one acceptable failure. - assert(errno == EINTR); - goto READ_AGAIN; - } - - assert(status == sizeof(op)); - op->Execute(monitor); - write(fdset.fd, &op, sizeof(op)); - } - } -} - -void -ProcessMonitor::DoOperation(Operation *op) -{ - int status; - Operation *ack = NULL; - Mutex::Locker lock(m_server_mutex); - - // FIXME: Do proper error checking here. - write(m_client_fd, &op, sizeof(op)); - -READ_AGAIN: - if ((status = read(m_client_fd, &ack, sizeof(ack))) < 0) - { - // If interrupted by a signal handler try again. Otherwise the monitor - // thread probably died and we have a stale file descriptor -- abort the - // operation. - if (errno == EINTR) - goto READ_AGAIN; - return; - } - - assert(status == sizeof(ack)); - assert(ack == op && "Invalid monitor thread response!"); -} - -size_t -ProcessMonitor::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, - Error &error) -{ - size_t result; - ReadOperation op(vm_addr, buf, size, error, result); - DoOperation(&op); - return result; -} - -size_t -ProcessMonitor::WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, - lldb_private::Error &error) -{ - size_t result; - WriteOperation op(vm_addr, buf, size, error, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::ReadRegisterValue(unsigned offset, unsigned size, RegisterValue &value) -{ - bool result; - ReadRegOperation op(offset, value, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::WriteRegisterValue(unsigned offset, const RegisterValue &value) -{ - bool result; - WriteRegOperation op(offset, value, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::ReadGPR(void *buf) -{ - bool result; - ReadGPROperation op(buf, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::ReadFPR(void *buf) -{ - bool result; - ReadFPROperation op(buf, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::WriteGPR(void *buf) -{ - bool result; - WriteGPROperation op(buf, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::WriteFPR(void *buf) -{ - bool result; - WriteFPROperation op(buf, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::Resume(lldb::tid_t tid, uint32_t signo) -{ - bool result; - ResumeOperation op(tid, signo, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::SingleStep(lldb::tid_t tid, uint32_t signo) -{ - bool result; - SingleStepOperation op(tid, signo, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::BringProcessIntoLimbo() -{ - bool result; - KillOperation op(result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::GetSignalInfo(lldb::tid_t tid, void *siginfo) -{ - bool result; - SiginfoOperation op(tid, siginfo, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::GetEventMessage(lldb::tid_t tid, unsigned long *message) -{ - bool result; - EventMessageOperation op(tid, message, result); - DoOperation(&op); - return result; -} - -bool -ProcessMonitor::Detach() -{ - bool result; - lldb_private::Error error; - DetachOperation op(error); - result = error.Success(); - DoOperation(&op); - StopMonitor(); - return result; -} - -bool -ProcessMonitor::DupDescriptor(const char *path, int fd, int flags) -{ - int target_fd = open(path, flags, 0666); - - if (target_fd == -1) - return false; - - return (dup2(target_fd, fd) == -1) ? false : true; -} - -void -ProcessMonitor::StopMonitoringChildProcess() -{ - lldb::thread_result_t thread_result; - - if (IS_VALID_LLDB_HOST_THREAD(m_monitor_thread)) - { - Host::ThreadCancel(m_monitor_thread, NULL); - Host::ThreadJoin(m_monitor_thread, &thread_result, NULL); - m_monitor_thread = LLDB_INVALID_HOST_THREAD; - } -} - -void -ProcessMonitor::StopMonitor() -{ - StopMonitoringChildProcess(); - StopLaunchOpThread(); - CloseFD(m_terminal_fd); - CloseFD(m_client_fd); - CloseFD(m_server_fd); -} - -void -ProcessMonitor::CloseFD(int &fd) -{ - if (fd != -1) - { - close(fd); - fd = -1; - } -} diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.h b/lldb/source/Plugins/Process/Linux/ProcessMonitor.h deleted file mode 100644 index 03e8c8c45586..000000000000 --- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.h +++ /dev/null @@ -1,294 +0,0 @@ -//===-- ProcessMonitor.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_ProcessMonitor_H_ -#define liblldb_ProcessMonitor_H_ - -// C Includes -#include <semaphore.h> -#include <signal.h> - -// C++ Includes -// Other libraries and framework includes -#include "lldb/lldb-types.h" -#include "lldb/Host/Mutex.h" - -namespace lldb_private -{ -class Error; -class Module; -class Scalar; - -} // End lldb_private namespace. - -class ProcessLinux; -class Operation; -class ProcessPOSIX; - -/// @class ProcessMonitor -/// @brief 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 propagated to the associated -/// ProcessLinux instance by calling ProcessLinux::SendMessage with the -/// appropriate ProcessMessage events. -/// -/// A purposely minimal set of operations are provided to interrogate and change -/// the inferior process state. -class ProcessMonitor -{ -public: - - /// Launches an inferior process ready for debugging. Forms the - /// implementation of Process::DoLaunch. - ProcessMonitor(ProcessPOSIX *process, - lldb_private::Module *module, - char const *argv[], - char const *envp[], - const char *stdin_path, - const char *stdout_path, - const char *stderr_path, - lldb_private::Error &error); - - ProcessMonitor(ProcessPOSIX *process, - lldb::pid_t pid, - lldb_private::Error &error); - - ~ProcessMonitor(); - - /// Provides the process number of debugee. - lldb::pid_t - GetPID() const { return m_pid; } - - /// Returns the process associated with this ProcessMonitor. - ProcessLinux & - GetProcess() { return *m_process; } - - /// Returns a file descriptor to the controlling terminal of the inferior - /// process. - /// - /// Reads from this file descriptor yield both the standard output and - /// standard error of this debugee. Even if stderr and stdout were - /// redirected on launch it may still happen that data is available on this - /// descriptor (if the inferior process opens /dev/tty, for example). - /// - /// If this monitor was attached to an existing process this method returns - /// -1. - int - GetTerminalFD() const { return m_terminal_fd; } - - /// Reads @p size bytes from address @vm_adder in the inferior process - /// address space. - /// - /// This method is provided to implement Process::DoReadMemory. - size_t - ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, - lldb_private::Error &error); - - /// Writes @p size bytes from address @p vm_adder in the inferior process - /// address space. - /// - /// This method is provided to implement Process::DoWriteMemory. - size_t - WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, - lldb_private::Error &error); - - /// Reads the contents from the register identified by the given (architecture - /// dependent) offset. - /// - /// This method is provided for use by RegisterContextLinux derivatives. - bool - ReadRegisterValue(unsigned offset, unsigned size, lldb_private::RegisterValue &value); - - /// Writes the given value to the register identified by the given - /// (architecture dependent) offset. - /// - /// This method is provided for use by RegisterContextLinux derivatives. - bool - WriteRegisterValue(unsigned offset, const lldb_private::RegisterValue &value); - - /// Reads all general purpose registers into the specified buffer. - bool - ReadGPR(void *buf); - - /// Reads all floating point registers into the specified buffer. - bool - ReadFPR(void *buf); - - /// Writes all general purpose registers into the specified buffer. - bool - WriteGPR(void *buf); - - /// Writes all floating point registers into the specified buffer. - bool - WriteFPR(void *buf); - - /// Writes a siginfo_t structure corresponding to the given thread ID to the - /// memory region pointed to by @p siginfo. - bool - GetSignalInfo(lldb::tid_t tid, void *siginfo); - - /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG) - /// corresponding to the given thread IDto the memory pointed to by @p - /// message. - bool - GetEventMessage(lldb::tid_t tid, unsigned long *message); - - /// Resumes the given thread. If @p signo is anything but - /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread. - bool - Resume(lldb::tid_t tid, uint32_t signo); - - /// Single steps the given thread. If @p signo is anything but - /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread. - bool - SingleStep(lldb::tid_t tid, uint32_t signo); - - /// Sends the inferior process a PTRACE_KILL signal. The inferior will - /// still exists and can be interrogated. Once resumed it will exit as - /// though it received a SIGKILL. - bool - BringProcessIntoLimbo(); - - bool - Detach(); - - -private: - ProcessLinux *m_process; - - lldb::thread_t m_operation_thread; - lldb::pid_t m_pid; - int m_terminal_fd; - - lldb::thread_t m_monitor_thread; - - lldb_private::Mutex m_server_mutex; - int m_client_fd; - int m_server_fd; - - struct OperationArgs - { - OperationArgs(ProcessMonitor *monitor); - - ~OperationArgs(); - - ProcessMonitor *m_monitor; // The monitor performing the attach. - sem_t m_semaphore; // Posted to once operation complete. - lldb_private::Error m_error; // Set if process operation failed. - }; - - /// @class LauchArgs - /// - /// @brief Simple structure to pass data to the thread responsible for - /// launching a child process. - struct LaunchArgs : OperationArgs - { - LaunchArgs(ProcessMonitor *monitor, - lldb_private::Module *module, - char const **argv, - char const **envp, - const char *stdin_path, - const char *stdout_path, - const char *stderr_path); - - ~LaunchArgs(); - - lldb_private::Module *m_module; // The executable image to launch. - char const **m_argv; // Process arguments. - char const **m_envp; // Process environment. - const char *m_stdin_path; // Redirect stdin or NULL. - const char *m_stdout_path; // Redirect stdout or NULL. - const char *m_stderr_path; // Redirect stderr or NULL. - }; - - void - StartLaunchOpThread(LaunchArgs *args, lldb_private::Error &error); - - void - StopLaunchOpThread(); - - static void * - LaunchOpThread(void *arg); - - static bool - Launch(LaunchArgs *args); - - bool - EnableIPC(); - - struct AttachArgs : OperationArgs - { - AttachArgs(ProcessMonitor *monitor, - lldb::pid_t pid); - - ~AttachArgs(); - - lldb::pid_t m_pid; // pid of the process to be attached. - }; - - void - StartAttachOpThread(AttachArgs *args, lldb_private::Error &error); - - void - StopAttachOpThread(); - - static void * - AttachOpThread(void *args); - - static bool - Attach(AttachArgs *args); - - static void - ServeOperation(OperationArgs *args); - - static bool - DupDescriptor(const char *path, int fd, int flags); - - static bool - MonitorCallback(void *callback_baton, - lldb::pid_t pid, bool exited, int signal, int status); - - static ProcessMessage - MonitorSIGTRAP(ProcessMonitor *monitor, - const siginfo_t *info, lldb::pid_t pid); - - static ProcessMessage - MonitorSignal(ProcessMonitor *monitor, - const siginfo_t *info, lldb::pid_t pid); - - static ProcessMessage::CrashReason - GetCrashReasonForSIGSEGV(const siginfo_t *info); - - static ProcessMessage::CrashReason - GetCrashReasonForSIGILL(const siginfo_t *info); - - static ProcessMessage::CrashReason - GetCrashReasonForSIGFPE(const siginfo_t *info); - - static ProcessMessage::CrashReason - GetCrashReasonForSIGBUS(const siginfo_t *info); - - void - DoOperation(Operation *op); - - /// Stops the child monitor thread. - void - StopMonitoringChildProcess(); - - void - StopMonitor(); - - void - CloseFD(int &fd); -}; - -#endif // #ifndef liblldb_ProcessMonitor_H_ diff --git a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h deleted file mode 100644 index e698892b1cd1..000000000000 --- a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h +++ /dev/null @@ -1,44 +0,0 @@ -//===-- RegisterContextLinux_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_RegisterContextLinux_x86_64_H_ -#define liblldb_RegisterContextLinux_x86_64_H_ - -typedef struct _GPR -{ - uint64_t r15; - uint64_t r14; - uint64_t r13; - uint64_t r12; - uint64_t rbp; - uint64_t rbx; - uint64_t r11; - uint64_t r10; - uint64_t r9; - uint64_t r8; - uint64_t rax; - uint64_t rcx; - uint64_t rdx; - uint64_t rsi; - uint64_t rdi; - uint64_t orig_ax; - uint64_t rip; - uint64_t cs; - uint64_t rflags; - uint64_t rsp; - uint64_t ss; - uint64_t fs_base; - uint64_t gs_base; - uint64_t ds; - uint64_t es; - uint64_t fs; - uint64_t gs; -} GPR; - -#endif diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp deleted file mode 100644 index c1d9f9551598..000000000000 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp +++ /dev/null @@ -1,1103 +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" - -// C Includes -#include <limits.h> -#include <string.h> - -// C++ Includes -#include "llvm/Support/MachO.h" - -// Other libraries and framework includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/State.h" -#include "lldb/Host/FileSpec.h" -#include "lldb/Host/Host.h" -#include "lldb/Host/TimeValue.h" -#include "lldb/Target/Process.h" - -// Project includes -#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 (1), - m_sequence_mutex (Mutex::eMutexTypeRecursive), - m_private_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) -{ - Mutex::Locker locker(m_sequence_mutex); - return SendRequestPacketNoLock (request_packet); -} - -#if 0 -typedef struct { - uint8_t request; // Either: CommandType | ePacketTypeRequest, or CommandType | ePacketTypeReply - uint8_t sequence; - uint16_t length; // Length of entire packet including this header - uint32_t key; // Session key -} kdp_hdr_t; -#endif - -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 uint8_t request_sequence_id, - const PacketStreamType &request_packet, - DataExtractor &reply_packet) -{ - - Mutex::Locker locker(m_sequence_mutex); - if (SendRequestPacketNoLock(request_packet)) - { - if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, GetPacketTimeoutInMicroSeconds ())) - { - uint32_t offset = 0; - const uint8_t reply_command = reply_packet.GetU8 (&offset); - const uint8_t reply_sequence_id = reply_packet.GetU8 (&offset); - if ((reply_command & eCommandTypeMask) == command) - { - if (request_sequence_id == reply_sequence_id) - return true; - } - } - } - 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(); - - LogSP 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 %zu of %zu bytes sent", bytes_written, packet_size); - } - return false; -} - -bool -CommunicationKDP::GetSequenceMutex (Mutex::Locker& locker) -{ - return locker.TryLock (m_sequence_mutex.GetMutex()); -} - - -bool -CommunicationKDP::WaitForNotRunningPrivate (const TimeValue *timeout_ptr) -{ - return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL); -} - -size_t -CommunicationKDP::WaitForPacketWithTimeoutMicroSeconds (DataExtractor &packet, uint32_t timeout_usec) -{ - Mutex::Locker locker(m_sequence_mutex); - return WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec); -} - -size_t -CommunicationKDP::WaitForPacketWithTimeoutMicroSecondsNoLock (DataExtractor &packet, uint32_t timeout_usec) -{ - uint8_t buffer[8192]; - Error error; - - LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS | KDP_LOG_VERBOSE)); - - // 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, status, &error); - - if (log) - log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %zu", - __PRETTY_FUNCTION__, - timeout_usec, - Communication::ConnectionStatusAsCString (status), - error.AsCString(), - bytes_read); - - if (bytes_read > 0) - { - if (CheckForPacket (buffer, bytes_read, packet)) - return packet.GetByteSize(); - } - else - { - switch (status) - { - 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 - Mutex::Locker locker(m_bytes_mutex); - - LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS)); - - if (src && src_len > 0) - { - if (log && log->GetVerbose()) - { - PacketStreamType log_strm; - DataExtractor::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); - uint32_t offset = 0; - uint8_t reply_command = packet.GetU8(&offset); - switch (reply_command) - { - 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_EXCEPTION: - case ePacketTypeReply | KDP_TERMINATION: - 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: - { - 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; - const uint32_t request_sequence_id = m_request_sequence_id; - MakeRequestPacketHeader (command, request_packet, command_length); - // Always send connect ports as little endian - request_packet.SetByteOrder (eByteOrderLittle); - request_packet.PutHex16 (reply_port); - request_packet.PutHex16 (exc_port); - request_packet.SetByteOrder (m_byte_order); - request_packet.PutCString (greeting); - DataExtractor reply_packet; - return SendRequestAndGetReply (command, request_sequence_id, 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; - const uint32_t request_sequence_id = m_request_sequence_id; - MakeRequestPacketHeader (command, request_packet, command_length); - // Always send connect ports as little endian - request_packet.SetByteOrder (eByteOrderLittle); - request_packet.PutHex16(reply_port); - request_packet.SetByteOrder (m_byte_order); - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) - { - // Reset the sequence ID to zero for reattach - ClearKDPSettings (); - uint32_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; - const uint32_t request_sequence_id = m_request_sequence_id; - MakeRequestPacketHeader (command, request_packet, command_length); - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) - { - uint32_t offset = 8; - m_kdp_version_version = reply_packet.GetU32 (&offset); - m_kdp_version_feature = reply_packet.GetU32 (&offset); - return true; - } - return false; -} - -#if 0 // Disable KDP_IMAGEPATH for now, it seems to hang the KDP connection... -const char * -CommunicationKDP::GetImagePath () -{ - if (m_image_path.empty()) - SendRequestImagePath(); - return m_image_path.c_str(); -} - -bool -CommunicationKDP::SendRequestImagePath () -{ - PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); - const CommandType command = KDP_IMAGEPATH; - const uint32_t command_length = 8; - const uint32_t request_sequence_id = m_request_sequence_id; - MakeRequestPacketHeader (command, request_packet, command_length); - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) - { - const char *path = reply_packet.PeekCStr(8); - if (path && path[0]) - m_kernel_version.assign (path); - return true; - } - return false; -} -#endif - -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; -} - -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; - const uint32_t request_sequence_id = m_request_sequence_id; - MakeRequestPacketHeader (command, request_packet, command_length); - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) - { - uint32_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; - const uint32_t request_sequence_id = m_request_sequence_id; - MakeRequestPacketHeader (command, request_packet, command_length); - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_sequence_id, 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; - const uint32_t request_sequence_id = m_request_sequence_id; - MakeRequestPacketHeader (command, request_packet, command_length); - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_sequence_id, 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, - Error &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; - const uint32_t request_sequence_id = m_request_sequence_id; - 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_sequence_id, request_packet, reply_packet)) - { - uint32_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"); - } - return 0; -} - - -uint32_t -CommunicationKDP::SendRequestWriteMemory (lldb::addr_t addr, - const void *src, - uint32_t src_len, - Error &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; - const uint32_t request_sequence_id = m_request_sequence_id; - MakeRequestPacketHeader (command, request_packet, command_length); - request_packet.PutMaxHex64 (addr, command_addr_byte_size); - request_packet.PutHex32 (src_len); - request_packet.PutBytesAsRawHex8(src, src_len); - - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) - { - uint32_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; - } - } - return 0; -} - -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"; - } - 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 - { - uint32_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 ("%s {%u:%u} <0x%4.4x> %s", - is_reply ? "<--" : "-->", - key, - sequence_id, - length, - command_name); - - 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: - { - 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[%llu] = { range = [0x%16.16llx - 0x%16.16llx), 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: - { - 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) - packet.Dump (&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) - packet.Dump (&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; - 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 = packet.GetU16 (&offset); - const uint16_t exc_port = 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) - DataExtractor::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.16llx, size = %u)", addr, size); - 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.16llx, size = %u, bytes = \n", addr, size); - if (size > 0) - DataExtractor::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) - packet.Dump (&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.16llx)", 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); - - s.Printf(" (count = %u:", count); - 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 ("\n cpu = 0x%8.8x, exc = %s (%u), code = %u (0x%8.8x), subcode = %u (0x%8.8x)\n", - 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 = packet.GetU16 (&offset); - s.Printf(" (reply_port = %u)", reply_port); - } - break; - } - } - } - else - { - error_desc = "error: invalid packet command: "; - } - } - - if (error_desc) - { - s.PutCString (error_desc); - - packet.Dump (&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, - Error &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; - const uint32_t request_sequence_id = m_request_sequence_id; - MakeRequestPacketHeader (command, request_packet, command_length); - request_packet.PutHex32 (cpu); - request_packet.PutHex32 (flavor); - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) - { - uint32_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); - } - return 0; -} - - -bool -CommunicationKDP::SendRequestResume (uint32_t cpu_mask) -{ - if (cpu_mask == 0) - cpu_mask = GetCPUMask(); - PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order); - const CommandType command = KDP_RESUMECPUS; - const uint32_t command_length = 12; - const uint32_t request_sequence_id = m_request_sequence_id; - MakeRequestPacketHeader (command, request_packet, command_length); - request_packet.PutHex32(cpu_mask); - - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) - return true; - return false; -} - -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; - const uint32_t request_sequence_id = m_request_sequence_id; - MakeRequestPacketHeader (command, request_packet, command_length); - request_packet.PutMaxHex64 (addr, command_addr_byte_size); - - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) - { - uint32_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; - const uint32_t request_sequence_id = m_request_sequence_id; - MakeRequestPacketHeader (command, request_packet, command_length); - DataExtractor reply_packet; - if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet)) - return true; - return false; -} - diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h b/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h deleted file mode 100644 index db1e02f605f9..000000000000 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h +++ /dev/null @@ -1,326 +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_ - -// C Includes -// C++ Includes -#include <list> -#include <string> - -// Other libraries and framework includes -// Project includes -#include "lldb/lldb-private.h" -#include "lldb/Core/Communication.h" -#include "lldb/Core/Listener.h" -#include "lldb/Core/StreamBuffer.h" -#include "lldb/Host/Mutex.h" -#include "lldb/Host/Predicate.h" -#include "lldb/Host/TimeValue.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 - } 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(lldb_private::Mutex::Locker& locker); - - bool - CheckForPacket (const uint8_t *src, - size_t src_len, - lldb_private::DataExtractor &packet); - bool - IsRunning() const - { - return m_public_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. - //------------------------------------------------------------------ - uint32_t - SetPacketTimeout (uint32_t packet_timeout) - { - const uint32_t old_packet_timeout = m_packet_timeout; - m_packet_timeout = packet_timeout; - return old_packet_timeout; - } - - uint32_t - GetPacketTimeoutInMicroSeconds () const - { - return m_packet_timeout * lldb_private::TimeValue::MicroSecPerSec; - } - //------------------------------------------------------------------ - // Start a debugserver instance on the current host using the - // supplied connection URL. - //------------------------------------------------------------------ - lldb_private::Error - StartDebugserverProcess (const char *connect_url, - const char *unix_socket_name, - lldb_private::ProcessLaunchInfo &launch_info); - - - //------------------------------------------------------------------ - // 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::Error &error); - - uint32_t - SendRequestWriteMemory (lldb::addr_t addr, - const void *src, - uint32_t src_len, - lldb_private::Error &error); - - uint32_t - SendRequestReadRegisters (uint32_t cpu, - uint32_t flavor, - void *dst, - uint32_t dst_size, - lldb_private::Error &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 (); - - // If cpu_mask is zero, then we will resume all CPUs - bool - SendRequestResume (uint32_t cpu_mask = 0); - - 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 lldb_private::TimeValue *timeout_ptr); - - 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 uint8_t request_sequence_id, - 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; - uint32_t m_packet_timeout; - lldb_private::Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time - lldb_private::Predicate<bool> m_public_is_running; - lldb_private::Predicate<bool> m_private_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/lldb/source/Plugins/Process/MacOSX-Kernel/Makefile b/lldb/source/Plugins/Process/MacOSX-Kernel/Makefile deleted file mode 100644 index e42f390ffe0d..000000000000 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -##===- source/Plugins/Process/MacOSX-Darwin/Makefile -------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLDB_LEVEL := ../../../.. -LIBRARYNAME := lldbPluginProcessDarwin -BUILD_ARCHIVE = 1 - -include $(LLDB_LEVEL)/Makefile diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp deleted file mode 100644 index 45ed9b5f8543..000000000000 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp +++ /dev/null @@ -1,821 +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. -// -//===----------------------------------------------------------------------===// - -// C Includes -#include <errno.h> -#include <stdlib.h> - -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/ConnectionFileDescriptor.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" -#include "lldb/Host/Host.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/Thread.h" - -// Project includes -#include "ProcessKDP.h" -#include "ProcessKDPLog.h" -#include "ThreadKDP.h" -#include "StopInfoMachException.h" - -using namespace lldb; -using namespace lldb_private; - -const char * -ProcessKDP::GetPluginNameStatic() -{ - return "kdp-remote"; -} - -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 (Target &target, - Listener &listener, - const FileSpec *crash_file_path) -{ - lldb::ProcessSP process_sp; - if (crash_file_path == NULL) - process_sp.reset(new ProcessKDP (target, listener)); - return process_sp; -} - -bool -ProcessKDP::CanDebug(Target &target, 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.GetExecutableModulePointer(); - if (exe_module) - { - const llvm::Triple &triple_ref = target.GetArchitecture().GetTriple(); - if (triple_ref.getOS() == llvm::Triple::Darwin && - 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; - } - } - return false; -} - -//---------------------------------------------------------------------- -// ProcessKDP constructor -//---------------------------------------------------------------------- -ProcessKDP::ProcessKDP(Target& target, Listener &listener) : - Process (target, listener), - m_comm("lldb.process.kdp-remote.communication"), - m_async_broadcaster (NULL, "lldb.process.kdp-remote.async-broadcaster"), - m_async_thread (LLDB_INVALID_HOST_THREAD) -{ -// m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit"); -// m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue"); -} - -//---------------------------------------------------------------------- -// 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 -//---------------------------------------------------------------------- -const char * -ProcessKDP::GetPluginName() -{ - return "Process debugging plug-in that uses the Darwin KDP remote protocol"; -} - -const char * -ProcessKDP::GetShortPluginName() -{ - return GetPluginNameStatic(); -} - -uint32_t -ProcessKDP::GetPluginVersion() -{ - return 1; -} - -Error -ProcessKDP::WillLaunch (Module* module) -{ - Error error; - error.SetErrorString ("launching not supported in kdp-remote plug-in"); - return error; -} - -Error -ProcessKDP::WillAttachToProcessWithID (lldb::pid_t pid) -{ - Error error; - error.SetErrorString ("attaching to a by process ID not supported in kdp-remote plug-in"); - return error; -} - -Error -ProcessKDP::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch) -{ - Error error; - error.SetErrorString ("attaching to a by process name not supported in kdp-remote plug-in"); - return error; -} - -Error -ProcessKDP::DoConnectRemote (const char *remote_url) -{ - // TODO: fill in the remote connection to the remote KDP here! - Error error; - - if (remote_url == NULL || remote_url[0] == '\0') - remote_url = "udp://localhost:41139"; - - std::auto_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 uint16_t reply_port = conn_ap->GetReadPort (); - - 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(); - uint32_t cpu = m_comm.GetCPUType(); - uint32_t sub = m_comm.GetCPUSubtype(); - ArchSpec kernel_arch; - kernel_arch.SetArchitecture(eArchTypeMachO, cpu, sub); - m_target.SetArchitecture(kernel_arch); - SetID (1); - GetThreadList (); - SetPrivateState (eStateStopped); - StreamSP async_strm_sp(m_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("invalid reply port from UDP connection"); - } - } - else - { - if (error.Success()) - error.SetErrorStringWithFormat ("failed to connect to '%s'", remote_url); - } - if (error.Fail()) - m_comm.Disconnect(); - - return error; -} - -//---------------------------------------------------------------------- -// Process Control -//---------------------------------------------------------------------- -Error -ProcessKDP::DoLaunch (Module *exe_module, - const ProcessLaunchInfo &launch_info) -{ - Error error; - error.SetErrorString ("launching not supported in kdp-remote plug-in"); - return error; -} - - -Error -ProcessKDP::DoAttachToProcessWithID (lldb::pid_t attach_pid) -{ - Error error; - error.SetErrorString ("attach to process by ID is not suppported in kdp remote debugging"); - return error; -} - -Error -ProcessKDP::DoAttachToProcessWithID (lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info) -{ - Error error; - error.SetErrorString ("attach to process by ID is not suppported in kdp remote debugging"); - return error; -} - -Error -ProcessKDP::DoAttachToProcessWithName (const char *process_name, bool wait_for_launch, const ProcessAttachInfo &attach_info) -{ - Error error; - error.SetErrorString ("attach to process by name is not suppported in kdp remote debugging"); - return error; -} - - -void -ProcessKDP::DidAttach () -{ - LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS)); - if (log) - log->Printf ("ProcessKDP::DidAttach()"); - if (GetID() != LLDB_INVALID_PROCESS_ID) - { - // TODO: figure out the register context that we will use - } -} - -Error -ProcessKDP::WillResume () -{ - return Error(); -} - -Error -ProcessKDP::DoResume () -{ - Error error; - if (!m_comm.SendRequestResume ()) - error.SetErrorString ("KDP resume failed"); - return error; -} - -bool -ProcessKDP::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list) -{ - // locker will keep a mutex locked until it goes out of scope - LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_THREAD)); - if (log && log->GetMask().Test(KDP_LOG_VERBOSE)) - log->Printf ("ProcessKDP::%s (pid = %llu)", __FUNCTION__, GetID()); - - // We currently are making only one thread per core and we - // actually don't know about actual threads. Eventually we - // want to get the thread list from memory and note which - // threads are on CPU as those are the only ones that we - // will be able to resume. - const uint32_t cpu_mask = m_comm.GetCPUMask(); - for (uint32_t cpu_mask_bit = 1; cpu_mask_bit & cpu_mask; cpu_mask_bit <<= 1) - { - lldb::tid_t tid = cpu_mask_bit; - ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false)); - if (!thread_sp) - thread_sp.reset(new ThreadKDP (shared_from_this(), tid)); - new_thread_list.AddThread(thread_sp); - } - return new_thread_list.GetSize(false) > 0; -} - - -StateType -ProcessKDP::SetThreadStopInfo (StringExtractor& stop_packet) -{ - // TODO: figure out why we stopped given the packet that tells us we stopped... - return eStateStopped; -} - -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(); - //SetThreadStopInfo (m_last_stop_packet); -} - -Error -ProcessKDP::DoHalt (bool &caused_stop) -{ - Error error; - -// bool timed_out = false; - Mutex::Locker locker; - - if (m_public_state.GetValue() == eStateAttaching) - { - // We are being asked to halt during an attach. We need to just close - // our file handle and debugserver will go away, and we can be done... - m_comm.Disconnect(); - } - else - { - if (!m_comm.SendRequestSuspend ()) - error.SetErrorString ("KDP halt failed"); - } - return error; -} - -Error -ProcessKDP::InterruptIfRunning (bool discard_thread_plans, - bool catch_stop_event, - EventSP &stop_event_sp) -{ - Error error; - - LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); - - bool paused_private_state_thread = false; - const bool is_running = m_comm.IsRunning(); - if (log) - log->Printf ("ProcessKDP::InterruptIfRunning(discard_thread_plans=%i, catch_stop_event=%i) is_running=%i", - discard_thread_plans, - catch_stop_event, - is_running); - - if (discard_thread_plans) - { - if (log) - log->Printf ("ProcessKDP::InterruptIfRunning() discarding all thread plans"); - m_thread_list.DiscardThreadPlans(); - } - if (is_running) - { - if (catch_stop_event) - { - if (log) - log->Printf ("ProcessKDP::InterruptIfRunning() pausing private state thread"); - PausePrivateStateThread(); - paused_private_state_thread = true; - } - - bool timed_out = false; -// bool sent_interrupt = false; - Mutex::Locker locker; - - // TODO: implement halt in CommunicationKDP -// if (!m_comm.SendInterrupt (locker, 1, sent_interrupt, timed_out)) -// { -// if (timed_out) -// error.SetErrorString("timed out sending interrupt packet"); -// else -// error.SetErrorString("unknown error sending interrupt packet"); -// if (paused_private_state_thread) -// ResumePrivateStateThread(); -// return error; -// } - - if (catch_stop_event) - { - // LISTEN HERE - TimeValue timeout_time; - timeout_time = TimeValue::Now(); - timeout_time.OffsetWithSeconds(5); - StateType state = WaitForStateChangedEventsPrivate (&timeout_time, stop_event_sp); - - timed_out = state == eStateInvalid; - if (log) - log->Printf ("ProcessKDP::InterruptIfRunning() catch stop event: state = %s, timed-out=%i", StateAsCString(state), timed_out); - - if (timed_out) - error.SetErrorString("unable to verify target stopped"); - } - - if (paused_private_state_thread) - { - if (log) - log->Printf ("ProcessKDP::InterruptIfRunning() resuming private state thread"); - ResumePrivateStateThread(); - } - } - return error; -} - -Error -ProcessKDP::WillDetach () -{ - LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); - if (log) - log->Printf ("ProcessKDP::WillDetach()"); - - bool discard_thread_plans = true; - bool catch_stop_event = true; - EventSP event_sp; - return InterruptIfRunning (discard_thread_plans, catch_stop_event, event_sp); -} - -Error -ProcessKDP::DoDetach() -{ - Error error; - LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); - if (log) - log->Printf ("ProcessKDP::DoDetach()"); - - DisableAllBreakpointSites (); - - m_thread_list.DiscardThreadPlans(); - - if (m_comm.IsConnected()) - { - - m_comm.SendRequestDisconnect(); - - size_t response_size = m_comm.Disconnect (); - if (log) - { - if (response_size) - log->PutCString ("ProcessKDP::DoDetach() detach packet sent successfully"); - else - log->PutCString ("ProcessKDP::DoDetach() detach packet send failed"); - } - } - // Sleep for one second to let the process get all detached... - StopAsyncThread (); - - m_comm.Clear(); - - SetPrivateState (eStateDetached); - ResumePrivateStateThread(); - - //KillDebugserverProcess (); - return error; -} - -Error -ProcessKDP::DoDestroy () -{ - Error error; - LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); - if (log) - log->Printf ("ProcessKDP::DoDestroy()"); - - // Interrupt if our inferior is running... - if (m_comm.IsConnected()) - { - if (m_public_state.GetValue() == eStateAttaching) - { - // We are being asked to halt during an attach. We need to just close - // our file handle and debugserver will go away, and we can be done... - m_comm.Disconnect(); - } - else - { - DisableAllBreakpointSites (); - - m_comm.SendRequestDisconnect(); - - StringExtractor response; - // TODO: Send kill packet? - SetExitStatus(SIGABRT, NULL); - } - } - StopAsyncThread (); - m_comm.Clear(); - return error; -} - -//------------------------------------------------------------------ -// Process Queries -//------------------------------------------------------------------ - -bool -ProcessKDP::IsAlive () -{ - return m_comm.IsConnected() && m_private_state.GetValue() != eStateExited; -} - -//------------------------------------------------------------------ -// Process Memory -//------------------------------------------------------------------ -size_t -ProcessKDP::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error) -{ - if (m_comm.IsConnected()) - return m_comm.SendRequestReadMemory (addr, buf, size, error); - error.SetErrorString ("not connected"); - return 0; -} - -size_t -ProcessKDP::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error) -{ - error.SetErrorString ("ProcessKDP::DoReadMemory not implemented"); - return 0; -} - -lldb::addr_t -ProcessKDP::DoAllocateMemory (size_t size, uint32_t permissions, Error &error) -{ - error.SetErrorString ("memory allocation not suppported in kdp remote debugging"); - return LLDB_INVALID_ADDRESS; -} - -Error -ProcessKDP::DoDeallocateMemory (lldb::addr_t addr) -{ - Error error; - error.SetErrorString ("memory deallocation not suppported in kdp remote debugging"); - return error; -} - -Error -ProcessKDP::EnableBreakpoint (BreakpointSite *bp_site) -{ - if (m_comm.LocalBreakpointsAreSupported ()) - { - Error 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); -} - -Error -ProcessKDP::DisableBreakpoint (BreakpointSite *bp_site) -{ - if (m_comm.LocalBreakpointsAreSupported ()) - { - Error error; - if (bp_site->IsEnabled()) - { - BreakpointSite::Type bp_type = bp_site->GetType(); - if (bp_type == BreakpointSite::eExternal) - { - 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); -} - -Error -ProcessKDP::EnableWatchpoint (Watchpoint *wp) -{ - Error error; - error.SetErrorString ("watchpoints are not suppported in kdp remote debugging"); - return error; -} - -Error -ProcessKDP::DisableWatchpoint (Watchpoint *wp) -{ - Error error; - error.SetErrorString ("watchpoints are not suppported in kdp remote debugging"); - return error; -} - -void -ProcessKDP::Clear() -{ - m_thread_list.Clear(); -} - -Error -ProcessKDP::DoSignal (int signo) -{ - Error error; - error.SetErrorString ("sending signals is not suppported in kdp remote debugging"); - return error; -} - -void -ProcessKDP::Initialize() -{ - static bool g_initialized = false; - - if (g_initialized == false) - { - g_initialized = true; - PluginManager::RegisterPlugin (GetPluginNameStatic(), - GetPluginDescriptionStatic(), - CreateInstance); - - Log::Callbacks log_callbacks = { - ProcessKDPLog::DisableLog, - ProcessKDPLog::EnableLog, - ProcessKDPLog::ListLogCategories - }; - - Log::RegisterLogChannel (ProcessKDP::GetPluginNameStatic(), log_callbacks); - } -} - -bool -ProcessKDP::StartAsyncThread () -{ - LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); - - if (log) - log->Printf ("ProcessKDP::%s ()", __FUNCTION__); - - // Create a thread that watches our internal state and controls which - // events make it to clients (into the DCProcess event queue). - m_async_thread = Host::ThreadCreate ("<lldb.process.kdp-remote.async>", ProcessKDP::AsyncThread, this, NULL); - return IS_VALID_LLDB_HOST_THREAD(m_async_thread); -} - -void -ProcessKDP::StopAsyncThread () -{ - LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS)); - - if (log) - log->Printf ("ProcessKDP::%s ()", __FUNCTION__); - - m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit); - - // Stop the stdio thread - if (IS_VALID_LLDB_HOST_THREAD(m_async_thread)) - { - Host::ThreadJoin (m_async_thread, NULL, NULL); - } -} - - -void * -ProcessKDP::AsyncThread (void *arg) -{ - ProcessKDP *process = (ProcessKDP*) arg; - - LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS)); - if (log) - log->Printf ("ProcessKDP::%s (arg = %p, pid = %llu) thread starting...", __FUNCTION__, arg, process->GetID()); - - Listener listener ("ProcessKDP::AsyncThread"); - EventSP event_sp; - const uint32_t desired_event_mask = eBroadcastBitAsyncContinue | - eBroadcastBitAsyncThreadShouldExit; - - if (listener.StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask) - { - listener.StartListeningForEvents (&process->m_comm, Communication::eBroadcastBitReadThreadDidExit); - - bool done = false; - while (!done) - { - if (log) - log->Printf ("ProcessKDP::%s (arg = %p, pid = %llu) listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID()); - if (listener.WaitForEvent (NULL, event_sp)) - { - const uint32_t event_type = event_sp->GetType(); - if (event_sp->BroadcasterIs (&process->m_async_broadcaster)) - { - if (log) - log->Printf ("ProcessKDP::%s (arg = %p, pid = %llu) Got an event of type: %d...", __FUNCTION__, arg, process->GetID(), event_type); - - switch (event_type) - { - case eBroadcastBitAsyncContinue: - { - const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event_sp.get()); - - if (continue_packet) - { - // TODO: do continue support here - -// const char *continue_cstr = (const char *)continue_packet->GetBytes (); -// const size_t continue_cstr_len = continue_packet->GetByteSize (); -// if (log) -// log->Printf ("ProcessKDP::%s (arg = %p, pid = %i) got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr); -// -// if (::strstr (continue_cstr, "vAttach") == NULL) -// process->SetPrivateState(eStateRunning); -// StringExtractor response; -// StateType stop_state = process->GetCommunication().SendContinuePacketAndWaitForResponse (process, continue_cstr, continue_cstr_len, response); -// -// switch (stop_state) -// { -// case eStateStopped: -// case eStateCrashed: -// case eStateSuspended: -// process->m_last_stop_packet = response; -// process->SetPrivateState (stop_state); -// break; -// -// case eStateExited: -// process->m_last_stop_packet = response; -// response.SetFilePos(1); -// process->SetExitStatus(response.GetHexU8(), NULL); -// done = true; -// break; -// -// case eStateInvalid: -// process->SetExitStatus(-1, "lost connection"); -// break; -// -// default: -// process->SetPrivateState (stop_state); -// break; -// } - } - } - break; - - case eBroadcastBitAsyncThreadShouldExit: - if (log) - log->Printf ("ProcessKDP::%s (arg = %p, pid = %llu) got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID()); - done = true; - break; - - default: - if (log) - log->Printf ("ProcessKDP::%s (arg = %p, pid = %llu) got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type); - done = true; - break; - } - } - else if (event_sp->BroadcasterIs (&process->m_comm)) - { - if (event_type & Communication::eBroadcastBitReadThreadDidExit) - { - process->SetExitStatus (-1, "lost connection"); - done = true; - } - } - } - else - { - if (log) - log->Printf ("ProcessKDP::%s (arg = %p, pid = %llu) listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID()); - done = true; - } - } - } - - if (log) - log->Printf ("ProcessKDP::%s (arg = %p, pid = %llu) thread exiting...", __FUNCTION__, arg, process->GetID()); - - process->m_async_thread = LLDB_INVALID_HOST_THREAD; - return NULL; -} - - diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h deleted file mode 100644 index 297d854cd9cf..000000000000 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h +++ /dev/null @@ -1,277 +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_ - -// C Includes - -// C++ Includes -#include <list> -#include <vector> - -// Other libraries and framework includes -#include "lldb/Core/ArchSpec.h" -#include "lldb/Core/Broadcaster.h" -#include "lldb/Core/Error.h" -#include "lldb/Core/InputReader.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Core/StringList.h" -#include "lldb/Core/ThreadSafeValue.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/Thread.h" - -#include "CommunicationKDP.h" -#include "Utility/StringExtractor.h" - -class ThreadKDP; - -class ProcessKDP : public lldb_private::Process -{ -public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - static lldb::ProcessSP - CreateInstance (lldb_private::Target& target, - lldb_private::Listener &listener, - const lldb_private::FileSpec *crash_file_path); - - static void - Initialize(); - - static void - Terminate(); - - static const char * - GetPluginNameStatic(); - - static const char * - GetPluginDescriptionStatic(); - - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - ProcessKDP(lldb_private::Target& target, lldb_private::Listener &listener); - - virtual - ~ProcessKDP(); - - //------------------------------------------------------------------ - // Check if a given Process - //------------------------------------------------------------------ - virtual bool - CanDebug (lldb_private::Target &target, - bool plugin_specified_by_name); - - // virtual uint32_t - // ListProcessesMatchingName (const char *name, lldb_private::StringList &matches, std::vector<lldb::pid_t> &pids); - - //------------------------------------------------------------------ - // Creating a new process, or attaching to an existing one - //------------------------------------------------------------------ - virtual lldb_private::Error - WillLaunch (lldb_private::Module* module); - - virtual lldb_private::Error - DoLaunch (lldb_private::Module *exe_module, - const lldb_private::ProcessLaunchInfo &launch_info); - - virtual lldb_private::Error - WillAttachToProcessWithID (lldb::pid_t pid); - - virtual lldb_private::Error - WillAttachToProcessWithName (const char *process_name, bool wait_for_launch); - - virtual lldb_private::Error - DoConnectRemote (const char *remote_url); - - virtual lldb_private::Error - DoAttachToProcessWithID (lldb::pid_t pid); - - virtual lldb_private::Error - DoAttachToProcessWithID (lldb::pid_t pid, const lldb_private::ProcessAttachInfo &attach_info); - - virtual lldb_private::Error - DoAttachToProcessWithName (const char *process_name, bool wait_for_launch, const lldb_private::ProcessAttachInfo &attach_info); - - virtual void - DidAttach (); - - //------------------------------------------------------------------ - // PluginInterface protocol - //------------------------------------------------------------------ - virtual const char * - GetPluginName(); - - virtual const char * - GetShortPluginName(); - - virtual uint32_t - GetPluginVersion(); - - //------------------------------------------------------------------ - // Process Control - //------------------------------------------------------------------ - virtual lldb_private::Error - WillResume (); - - virtual lldb_private::Error - DoResume (); - - virtual lldb_private::Error - DoHalt (bool &caused_stop); - - virtual lldb_private::Error - WillDetach (); - - virtual lldb_private::Error - DoDetach (); - - virtual lldb_private::Error - DoSignal (int signal); - - virtual lldb_private::Error - DoDestroy (); - - virtual void - RefreshStateAfterStop(); - - //------------------------------------------------------------------ - // Process Queries - //------------------------------------------------------------------ - virtual bool - IsAlive (); - - //------------------------------------------------------------------ - // Process Memory - //------------------------------------------------------------------ - virtual size_t - DoReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error); - - virtual size_t - DoWriteMemory (lldb::addr_t addr, const void *buf, size_t size, lldb_private::Error &error); - - virtual lldb::addr_t - DoAllocateMemory (size_t size, uint32_t permissions, lldb_private::Error &error); - - virtual lldb_private::Error - DoDeallocateMemory (lldb::addr_t ptr); - - //---------------------------------------------------------------------- - // Process Breakpoints - //---------------------------------------------------------------------- - virtual lldb_private::Error - EnableBreakpoint (lldb_private::BreakpointSite *bp_site); - - virtual lldb_private::Error - DisableBreakpoint (lldb_private::BreakpointSite *bp_site); - - //---------------------------------------------------------------------- - // Process Watchpoints - //---------------------------------------------------------------------- - virtual lldb_private::Error - EnableWatchpoint (lldb_private::Watchpoint *wp); - - virtual lldb_private::Error - DisableWatchpoint (lldb_private::Watchpoint *wp); - - 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 - ProcessIDIsValid ( ) const; - - // static void - // STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len); - - // void - // AppendSTDOUT (const char* s, size_t len); - - void - Clear ( ); - - virtual bool - UpdateThreadList (lldb_private::ThreadList &old_thread_list, - lldb_private::ThreadList &new_thread_list); - - enum - { - eBroadcastBitAsyncContinue = (1 << 0), - eBroadcastBitAsyncThreadShouldExit = (1 << 1) - }; - - lldb_private::Error - InterruptIfRunning (bool discard_thread_plans, - bool catch_stop_event, - lldb::EventSP &stop_event_sp); - - //------------------------------------------------------------------ - /// Broadcaster event bits definitions. - //------------------------------------------------------------------ - CommunicationKDP m_comm; - lldb_private::Broadcaster m_async_broadcaster; - lldb::thread_t m_async_thread; - - bool - StartAsyncThread (); - - void - StopAsyncThread (); - - static void * - AsyncThread (void *arg); - - lldb::StateType - SetThreadStopInfo (StringExtractor& stop_packet); - -private: - //------------------------------------------------------------------ - // For ProcessKDP only - //------------------------------------------------------------------ - - DISALLOW_COPY_AND_ASSIGN (ProcessKDP); - -}; - -#endif // liblldb_ProcessKDP_h_ diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp deleted file mode 100644 index ff3c46ece3fd..000000000000 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp +++ /dev/null @@ -1,181 +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" - -#include "lldb/Interpreter/Args.h" -#include "lldb/Core/StreamFile.h" - -#include "ProcessKDP.h" - -using namespace lldb; -using namespace lldb_private; - - -// We want to avoid global constructors where code needs to be run so here we -// control access to our static g_log_sp by hiding it in a singleton function -// that will construct the static g_lob_sp the first time this function is -// called. -static LogSP & -GetLog () -{ - static LogSP g_log_sp; - return g_log_sp; -} - -LogSP -ProcessKDPLog::GetLogIfAllCategoriesSet (uint32_t mask) -{ - LogSP log(GetLog ()); - if (log && mask) - { - uint32_t log_mask = log->GetMask().Get(); - if ((log_mask & mask) != mask) - return LogSP(); - } - return log; -} - -void -ProcessKDPLog::DisableLog (const char **categories, Stream *feedback_strm) -{ - LogSP log (GetLog ()); - if (log) - { - uint32_t flag_bits = 0; - - if (categories[0] != NULL) - { - flag_bits = log->GetMask().Get(); - for (size_t i = 0; categories[i] != NULL; ++i) - { - const char *arg = categories[i]; - - - if (::strcasecmp (arg, "all") == 0 ) flag_bits &= ~KDP_LOG_ALL; - else if (::strcasecmp (arg, "async") == 0 ) flag_bits &= ~KDP_LOG_ASYNC; - else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits &= ~KDP_LOG_BREAKPOINTS; - else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits &= ~KDP_LOG_COMM; - else if (::strcasecmp (arg, "default") == 0 ) flag_bits &= ~KDP_LOG_DEFAULT; - else if (::strcasecmp (arg, "packets") == 0 ) flag_bits &= ~KDP_LOG_PACKETS; - else if (::strcasecmp (arg, "memory") == 0 ) flag_bits &= ~KDP_LOG_MEMORY; - else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits &= ~KDP_LOG_MEMORY_DATA_SHORT; - else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits &= ~KDP_LOG_MEMORY_DATA_LONG; - else if (::strcasecmp (arg, "process") == 0 ) flag_bits &= ~KDP_LOG_PROCESS; - else if (::strcasecmp (arg, "step") == 0 ) flag_bits &= ~KDP_LOG_STEP; - else if (::strcasecmp (arg, "thread") == 0 ) flag_bits &= ~KDP_LOG_THREAD; - else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits &= ~KDP_LOG_VERBOSE; - else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits &= ~KDP_LOG_WATCHPOINTS; - else - { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - ListLogCategories (feedback_strm); - } - - } - } - - if (flag_bits == 0) - GetLog ().reset(); - else - log->GetMask().Reset (flag_bits); - } - - return; -} - -LogSP -ProcessKDPLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **categories, Stream *feedback_strm) -{ - // Try see if there already is a log - that way we can reuse its settings. - // We could reuse the log in toto, but we don't know that the stream is the same. - uint32_t flag_bits = 0; - LogSP log(GetLog ()); - if (log) - flag_bits = log->GetMask().Get(); - - // Now make a new log with this stream if one was provided - if (log_stream_sp) - { - log.reset (new Log(log_stream_sp)); - GetLog () = log; - } - - if (log) - { - bool got_unknown_category = false; - for (size_t i=0; categories[i] != NULL; ++i) - { - const char *arg = categories[i]; - - if (::strcasecmp (arg, "all") == 0 ) flag_bits |= KDP_LOG_ALL; - else if (::strcasecmp (arg, "async") == 0 ) flag_bits |= KDP_LOG_ASYNC; - else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits |= KDP_LOG_BREAKPOINTS; - else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits |= KDP_LOG_COMM; - else if (::strcasecmp (arg, "default") == 0 ) flag_bits |= KDP_LOG_DEFAULT; - else if (::strcasecmp (arg, "packets") == 0 ) flag_bits |= KDP_LOG_PACKETS; - else if (::strcasecmp (arg, "memory") == 0 ) flag_bits |= KDP_LOG_MEMORY; - else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits |= KDP_LOG_MEMORY_DATA_SHORT; - else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits |= KDP_LOG_MEMORY_DATA_LONG; - else if (::strcasecmp (arg, "process") == 0 ) flag_bits |= KDP_LOG_PROCESS; - else if (::strcasecmp (arg, "step") == 0 ) flag_bits |= KDP_LOG_STEP; - else if (::strcasecmp (arg, "thread") == 0 ) flag_bits |= KDP_LOG_THREAD; - else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits |= KDP_LOG_VERBOSE; - else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits |= KDP_LOG_WATCHPOINTS; - else - { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - if (got_unknown_category == false) - { - got_unknown_category = true; - ListLogCategories (feedback_strm); - } - } - } - if (flag_bits == 0) - flag_bits = KDP_LOG_DEFAULT; - log->GetMask().Reset(flag_bits); - log->GetOptions().Reset(log_options); - } - return log; -} - -void -ProcessKDPLog::ListLogCategories (Stream *strm) -{ - strm->Printf ("Logging categories for '%s':\n" - " all - turn on all available logging categories\n" - " async - log asynchronous activity\n" - " break - log breakpoints\n" - " communication - log communication activity\n" - " default - enable the default set of logging categories for liblldb\n" - " packets - log gdb remote packets\n" - " memory - log memory reads and writes\n" - " data-short - log memory bytes for memory reads and writes for short transactions only\n" - " data-long - log memory bytes for memory reads and writes for all transactions\n" - " process - log process events and activities\n" - " thread - log thread events and activities\n" - " step - log step related activities\n" - " verbose - enable verbose logging\n" - " watch - log watchpoint related activities\n", ProcessKDP::GetPluginNameStatic()); -} - - -void -ProcessKDPLog::LogIf (uint32_t mask, const char *format, ...) -{ - LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (mask)); - if (log) - { - va_list args; - va_start (args, format); - log->VAPrintf (format, args); - va_end (args); - } -} diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h deleted file mode 100644 index ffdc471ff3a1..000000000000 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h +++ /dev/null @@ -1,54 +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_ - -// C Includes -// C++ Includes -// Other libraries and framework includes - -// Project includes -#include "lldb/Core/Log.h" - -#define KDP_LOG_VERBOSE (1u << 0) -#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 - -class ProcessKDPLog -{ -public: - static lldb::LogSP - GetLogIfAllCategoriesSet(uint32_t mask = 0); - - static void - DisableLog (const char **categories, lldb_private::Stream *feedback_strm); - - static lldb::LogSP - EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options, const char **categories, lldb_private::Stream *feedback_strm); - - static void - ListLogCategories (lldb_private::Stream *strm); - - static void - LogIf (uint32_t mask, const char *format, ...); -}; - -#endif // liblldb_ProcessKDPLog_h_ diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp deleted file mode 100644 index 296fbbac7e98..000000000000 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.cpp +++ /dev/null @@ -1,121 +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" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#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) - { - Error 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) - { - Error 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) - { - Error 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) - { - Error 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) -{ - return -1; -} - -int -RegisterContextKDP_arm::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) -{ - return -1; -} - -int -RegisterContextKDP_arm::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) -{ - return -1; -} - -int -RegisterContextKDP_arm::DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg) -{ - return -1; -} - - diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h deleted file mode 100644 index 1e547289d9ce..000000000000 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_arm.h +++ /dev/null @@ -1,61 +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_ - -// C Includes - -// C++ Includes -// Other libraries and framework includes -// Project includes -#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/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp deleted file mode 100644 index 504ea07ba4f9..000000000000 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.cpp +++ /dev/null @@ -1,99 +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. -// -//===----------------------------------------------------------------------===// - - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#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) - { - Error 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) - { - Error 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) - { - Error 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) -{ - return -1; -} - -int -RegisterContextKDP_i386::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) -{ - return -1; -} - -int -RegisterContextKDP_i386::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) -{ - return -1; -} - - diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h deleted file mode 100644 index 4b6bc5b262f7..000000000000 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_i386.h +++ /dev/null @@ -1,53 +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_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#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/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp deleted file mode 100644 index 360bc6e0dac6..000000000000 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.cpp +++ /dev/null @@ -1,67 +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. -// -//===----------------------------------------------------------------------===// - - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#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) -{ - return -1; -} - -int -RegisterContextKDP_x86_64::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) -{ - return -1; -} - -int -RegisterContextKDP_x86_64::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) -{ - return -1; -} - -int -RegisterContextKDP_x86_64::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) -{ - return -1; -} - -int -RegisterContextKDP_x86_64::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) -{ - return -1; -} - -int -RegisterContextKDP_x86_64::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) -{ - return -1; -} diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h b/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h deleted file mode 100644 index a426349198ff..000000000000 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/RegisterContextKDP_x86_64.h +++ /dev/null @@ -1,54 +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_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#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/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp deleted file mode 100644 index 9f68d104942e..000000000000 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp +++ /dev/null @@ -1,216 +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 "llvm/Support/MachO.h" - -#include "lldb/Core/ArchSpec.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Core/State.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/Breakpoint/Watchpoint.h" - -#include "ProcessKDP.h" -#include "ProcessKDPLog.h" -#include "RegisterContextKDP_arm.h" -#include "RegisterContextKDP_i386.h" -#include "RegisterContextKDP_x86_64.h" - -using namespace lldb; -using namespace lldb_private; - -//---------------------------------------------------------------------- -// Thread Registers -//---------------------------------------------------------------------- - -ThreadKDP::ThreadKDP (const lldb::ProcessSP &process_sp, lldb::tid_t tid) : - Thread(process_sp, tid), - m_thread_name (), - m_dispatch_queue_name (), - m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS) -{ - ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::ThreadKDP (tid = 0x%4.4x)", this, GetID()); -} - -ThreadKDP::~ThreadKDP () -{ - ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::~ThreadKDP (tid = 0x%4.4x)", this, GetID()); - DestroyThread(); -} - -const char * -ThreadKDP::GetName () -{ - if (m_thread_name.empty()) - return NULL; - return m_thread_name.c_str(); -} - -const char * -ThreadKDP::GetQueueName () -{ - return NULL; -} - -bool -ThreadKDP::WillResume (StateType resume_state) -{ - ClearStackFrames(); - // Call the Thread::WillResume first. If we stop at a signal, the stop info - // class for signal will set the resume signal that we need below. The signal - // stuff obeys the Process::UnixSignal defaults. - Thread::WillResume(resume_state); - - lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP)); - if (log) - log->Printf ("Resuming thread: %4.4llx with state: %s.", GetID(), StateAsCString(resume_state)); - -// ProcessKDP &process = GetKDPProcess(); -// switch (resume_state) -// { -// case eStateSuspended: -// case eStateStopped: -// // Don't append anything for threads that should stay stopped. -// break; -// -// case eStateRunning: -// case eStateStepping: -// break; -// -// default: -// break; -// } - return true; -} - -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; - GetRegisterContext()->InvalidateIfNeeded (force); -} - -void -ThreadKDP::ClearStackFrames () -{ - Unwind *unwinder = GetUnwinder (); - if (unwinder) - unwinder->Clear(); - Thread::ClearStackFrames(); -} - - -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.get() == NULL) - m_reg_context_sp = CreateRegisterContextForFrame (NULL); - 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::CPUTypeARM: - reg_ctx_sp.reset (new RegisterContextKDP_arm (*this, concrete_frame_idx)); - break; - case llvm::MachO::CPUTypeI386: - reg_ctx_sp.reset (new RegisterContextKDP_i386 (*this, concrete_frame_idx)); - break; - case llvm::MachO::CPUTypeX86_64: - reg_ctx_sp.reset (new RegisterContextKDP_x86_64 (*this, concrete_frame_idx)); - break; - default: - assert (!"Add CPU type support in KDP"); - break; - } - } - } - else if (m_unwinder_ap.get()) - reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame); - return reg_ctx_sp; -} - -lldb::StopInfoSP -ThreadKDP::GetPrivateStopReason () -{ - ProcessSP process_sp (GetProcess()); - if (process_sp) - { - const uint32_t process_stop_id = process_sp->GetStopID(); - if (m_thread_stop_reason_stop_id != process_stop_id || - (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid())) - { - // TODO: can we query the initial state of the thread here? - // For now I am just going to pretend that a SIGSTOP happened. - - SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP)); - - // If GetKDPProcess().SetThreadStopInfo() doesn't find a stop reason - // for this thread, then m_actual_stop_info_sp will not ever contain - // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false" - // check will never be able to tell us if we have the correct stop info - // for this thread and we will continually send qThreadStopInfo packets - // down to the remote KDP server, so we need to keep our own notion - // of the stop ID that m_actual_stop_info_sp is valid for (even if it - // contains nothing). We use m_thread_stop_reason_stop_id for this below. - // m_thread_stop_reason_stop_id = process_stop_id; - // m_actual_stop_info_sp.reset(); - - } - } - return m_actual_stop_info_sp; -} - - diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h b/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h deleted file mode 100644 index 1bf688de20af..000000000000 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h +++ /dev/null @@ -1,103 +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 (const lldb::ProcessSP &process_sp, - lldb::tid_t tid); - - virtual - ~ThreadKDP (); - - virtual bool - WillResume (lldb::StateType resume_state); - - virtual void - RefreshStateAfterStop(); - - virtual const char * - GetName (); - - virtual const char * - GetQueueName (); - - virtual lldb::RegisterContextSP - GetRegisterContext (); - - virtual lldb::RegisterContextSP - CreateRegisterContextForFrame (lldb_private::StackFrame *frame); - - virtual void - ClearStackFrames (); - - 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; - } - -protected: - - friend class ProcessKDP; - - //------------------------------------------------------------------ - // Member variables. - //------------------------------------------------------------------ - std::string m_thread_name; - std::string m_dispatch_queue_name; - lldb::addr_t m_thread_dispatch_qaddr; - //------------------------------------------------------------------ - // Member variables. - //------------------------------------------------------------------ - - virtual lldb::StopInfoSP - GetPrivateStopReason (); - - -}; - -#endif // liblldb_ThreadKDP_h_ diff --git a/lldb/source/Plugins/Process/POSIX/Makefile b/lldb/source/Plugins/Process/POSIX/Makefile deleted file mode 100644 index 6705b0d8d16b..000000000000 --- a/lldb/source/Plugins/Process/POSIX/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -##===- source/Plugins/Process/POSIX/Makefile ---------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLDB_LEVEL := ../../../.. -LIBRARYNAME := lldbPluginProcessPOSIX -BUILD_ARCHIVE = 1 - -include $(LLDB_LEVEL)/../../Makefile.config - -# Extend the include path so we may locate UnwindLLDB.h -CPPFLAGS += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Utility - -ifeq ($(HOST_OS),Linux) -CPPFLAGS += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Process/Linux -endif - -ifeq ($(HOST_OS),FreeBSD) -# Extend the include path so we may locate ProcessMonitor -CPPFLAGS += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Process/FreeBSD -endif - -include $(LLDB_LEVEL)/Makefile diff --git a/lldb/source/Plugins/Process/POSIX/POSIXStopInfo.cpp b/lldb/source/Plugins/Process/POSIX/POSIXStopInfo.cpp deleted file mode 100644 index 79f0a58115b9..000000000000 --- a/lldb/source/Plugins/Process/POSIX/POSIXStopInfo.cpp +++ /dev/null @@ -1,60 +0,0 @@ -//===-- POSIXStopInfo.cpp ---------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "POSIXStopInfo.h" - -using namespace lldb; -using namespace lldb_private; - - -//===----------------------------------------------------------------------===// -// POSIXLimboStopInfo - -POSIXLimboStopInfo::~POSIXLimboStopInfo() { } - -lldb::StopReason -POSIXLimboStopInfo::GetStopReason() const -{ - return lldb::eStopReasonTrace; -} - -const char * -POSIXLimboStopInfo::GetDescription() -{ - return "thread exiting"; -} - -bool -POSIXLimboStopInfo::ShouldStop(Event *event_ptr) -{ - return true; -} - -bool -POSIXLimboStopInfo::ShouldNotify(Event *event_ptr) -{ - return true; -} - -//===----------------------------------------------------------------------===// -// POSIXCrashStopInfo - -POSIXCrashStopInfo::~POSIXCrashStopInfo() { } - -lldb::StopReason -POSIXCrashStopInfo::GetStopReason() const -{ - return lldb::eStopReasonException; -} - -const char * -POSIXCrashStopInfo::GetDescription() -{ - return ProcessMessage::GetCrashReasonString(m_crash_reason); -} diff --git a/lldb/source/Plugins/Process/POSIX/POSIXStopInfo.h b/lldb/source/Plugins/Process/POSIX/POSIXStopInfo.h deleted file mode 100644 index c510377f4623..000000000000 --- a/lldb/source/Plugins/Process/POSIX/POSIXStopInfo.h +++ /dev/null @@ -1,92 +0,0 @@ -//===-- POSIXStopInfo.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_POSIXStopInfo_H_ -#define liblldb_POSIXStopInfo_H_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Target/StopInfo.h" - -#include "POSIXThread.h" -#include "ProcessMessage.h" - -//===----------------------------------------------------------------------===// -/// @class POSIXStopInfo -/// @brief Simple base class for all POSIX-specific StopInfo objects. -/// -class POSIXStopInfo - : public lldb_private::StopInfo -{ -public: - POSIXStopInfo(lldb_private::Thread &thread, uint32_t status) - : StopInfo(thread, status) - { } -}; - -//===----------------------------------------------------------------------===// -/// @class POSIXLimboStopInfo -/// @brief Represents the stop state of a process ready to exit. -/// -class POSIXLimboStopInfo - : public POSIXStopInfo -{ -public: - POSIXLimboStopInfo(POSIXThread &thread) - : POSIXStopInfo(thread, 0) - { } - - ~POSIXLimboStopInfo(); - - lldb::StopReason - GetStopReason() const; - - const char * - GetDescription(); - - bool - ShouldStop(lldb_private::Event *event_ptr); - - bool - ShouldNotify(lldb_private::Event *event_ptr); -}; - - -//===----------------------------------------------------------------------===// -/// @class POSIXCrashStopInfo -/// @brief Represents the stop state of process that is ready to crash. -/// -class POSIXCrashStopInfo - : public POSIXStopInfo -{ -public: - POSIXCrashStopInfo(POSIXThread &thread, uint32_t status, - ProcessMessage::CrashReason reason) - : POSIXStopInfo(thread, status), - m_crash_reason(reason) - { } - - ~POSIXCrashStopInfo(); - - lldb::StopReason - GetStopReason() const; - - const char * - GetDescription(); - - ProcessMessage::CrashReason - GetCrashReason() const; - -private: - ProcessMessage::CrashReason m_crash_reason; -}; - -#endif diff --git a/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp b/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp deleted file mode 100644 index 9de6c859b833..000000000000 --- a/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp +++ /dev/null @@ -1,355 +0,0 @@ -//===-- POSIXThread.cpp -----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -#include <errno.h> - -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Debugger.h" -#include "lldb/Host/Host.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/StopInfo.h" -#include "lldb/Target/Target.h" -#include "POSIXStopInfo.h" -#include "POSIXThread.h" -#include "ProcessPOSIX.h" -#include "ProcessPOSIXLog.h" -#include "ProcessMonitor.h" -#include "RegisterContext_i386.h" -#include "RegisterContext_x86_64.h" -#include "RegisterContextPOSIX.h" - -#include "UnwindLLDB.h" - -using namespace lldb; -using namespace lldb_private; - - -POSIXThread::POSIXThread(ProcessSP &process, lldb::tid_t tid) - : Thread(process, tid), - m_frame_ap(0) -{ - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf ("POSIXThread::%s (tid = %i)", __FUNCTION__, tid); -} - -POSIXThread::~POSIXThread() -{ - DestroyThread(); -} - -ProcessMonitor & -POSIXThread::GetMonitor() -{ - ProcessSP base = GetProcess(); - ProcessPOSIX &process = static_cast<ProcessPOSIX&>(*base); - return process.GetMonitor(); -} - -void -POSIXThread::RefreshStateAfterStop() -{ - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf ("POSIXThread::%s ()", __FUNCTION__); - - // Let all threads recover from stopping and do any clean up based - // on the previous thread state (if any). - ProcessSP base = GetProcess(); - ProcessPOSIX &process = static_cast<ProcessPOSIX&>(*base); - process.GetThreadList().RefreshStateAfterStop(); -} - -const char * -POSIXThread::GetInfo() -{ - return NULL; -} - -lldb::RegisterContextSP -POSIXThread::GetRegisterContext() -{ - if (!m_reg_context_sp) - { - ArchSpec arch = Host::GetArchitecture(); - - switch (arch.GetCore()) - { - default: - assert(false && "CPU type not supported!"); - break; - - case ArchSpec::eCore_x86_32_i386: - case ArchSpec::eCore_x86_32_i486: - case ArchSpec::eCore_x86_32_i486sx: - m_reg_context_sp.reset(new RegisterContext_i386(*this, 0)); - break; - - case ArchSpec::eCore_x86_64_x86_64: - m_reg_context_sp.reset(new RegisterContext_x86_64(*this, 0)); - break; - } - } - return m_reg_context_sp; -} - -lldb::RegisterContextSP -POSIXThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame) -{ - lldb::RegisterContextSP reg_ctx_sp; - uint32_t concrete_frame_idx = 0; - - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf ("POSIXThread::%s ()", __FUNCTION__); - - if (frame) - concrete_frame_idx = frame->GetConcreteFrameIndex(); - - if (concrete_frame_idx == 0) - reg_ctx_sp = GetRegisterContext(); - else - { - assert(GetUnwinder()); - reg_ctx_sp = GetUnwinder()->CreateRegisterContextForFrame(frame); - } - - return reg_ctx_sp; -} - -lldb::StopInfoSP -POSIXThread::GetPrivateStopReason() -{ - return m_stop_info; -} - -Unwind * -POSIXThread::GetUnwinder() -{ - if (m_unwinder_ap.get() == NULL) - m_unwinder_ap.reset(new UnwindLLDB(*this)); - - return m_unwinder_ap.get(); -} - -bool -POSIXThread::WillResume(lldb::StateType resume_state) -{ - SetResumeState(resume_state); - - ClearStackFrames(); - if (m_unwinder_ap.get()) - m_unwinder_ap->Clear(); - - return Thread::WillResume(resume_state); -} - -bool -POSIXThread::Resume() -{ - lldb::StateType resume_state = GetResumeState(); - ProcessMonitor &monitor = GetMonitor(); - bool status; - - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf ("POSIXThread::%s ()", __FUNCTION__); - - switch (resume_state) - { - default: - assert(false && "Unexpected state for resume!"); - status = false; - break; - - case lldb::eStateRunning: - SetState(resume_state); - status = monitor.Resume(GetID(), GetResumeSignal()); - break; - - case lldb::eStateStepping: - SetState(resume_state); - status = monitor.SingleStep(GetID(), GetResumeSignal()); - break; - } - - return status; -} - -void -POSIXThread::Notify(const ProcessMessage &message) -{ - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); - if (log) - log->Printf ("POSIXThread::%s () message kind = '%s'", __FUNCTION__, message.PrintKind()); - - switch (message.GetKind()) - { - default: - assert(false && "Unexpected message kind!"); - break; - - case ProcessMessage::eLimboMessage: - LimboNotify(message); - break; - - case ProcessMessage::eSignalMessage: - SignalNotify(message); - break; - - case ProcessMessage::eSignalDeliveredMessage: - SignalDeliveredNotify(message); - break; - - case ProcessMessage::eTraceMessage: - TraceNotify(message); - break; - - case ProcessMessage::eBreakpointMessage: - BreakNotify(message); - break; - - case ProcessMessage::eCrashMessage: - CrashNotify(message); - break; - } -} - -void -POSIXThread::BreakNotify(const ProcessMessage &message) -{ - bool status; - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); - - assert(GetRegisterContext()); - status = GetRegisterContextPOSIX()->UpdateAfterBreakpoint(); - assert(status && "Breakpoint update failed!"); - - // With our register state restored, resolve the breakpoint object - // corresponding to our current PC. - assert(GetRegisterContext()); - lldb::addr_t pc = GetRegisterContext()->GetPC(); - if (log) - log->Printf ("POSIXThread::%s () PC=0x%8.8llx", __FUNCTION__, pc); - lldb::BreakpointSiteSP bp_site(GetProcess()->GetBreakpointSiteList().FindByAddress(pc)); - assert(bp_site); - lldb::break_id_t bp_id = bp_site->GetID(); - assert(bp_site && bp_site->ValidForThisThread(this)); - - - m_breakpoint = bp_site; - m_stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id); -} - -void -POSIXThread::TraceNotify(const ProcessMessage &message) -{ - m_stop_info = StopInfo::CreateStopReasonToTrace(*this); -} - -void -POSIXThread::LimboNotify(const ProcessMessage &message) -{ - m_stop_info = lldb::StopInfoSP(new POSIXLimboStopInfo(*this)); -} - -void -POSIXThread::SignalNotify(const ProcessMessage &message) -{ - int signo = message.GetSignal(); - - m_stop_info = StopInfo::CreateStopReasonWithSignal(*this, signo); - SetResumeSignal(signo); -} - -void -POSIXThread::SignalDeliveredNotify(const ProcessMessage &message) -{ - int signo = message.GetSignal(); - - // Just treat debugger generated signal events like breakpoints for now. - m_stop_info = StopInfo::CreateStopReasonToTrace(*this); - SetResumeSignal(signo); -} - -void -POSIXThread::CrashNotify(const ProcessMessage &message) -{ - int signo = message.GetSignal(); - - assert(message.GetKind() == ProcessMessage::eCrashMessage); - - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); - if (log) - log->Printf ("POSIXThread::%s () signo = %i, reason = '%s'", __FUNCTION__, signo, message.PrintCrashReason()); - - m_stop_info = lldb::StopInfoSP(new POSIXCrashStopInfo( - *this, signo, message.GetCrashReason())); - SetResumeSignal(signo); -} - -unsigned -POSIXThread::GetRegisterIndexFromOffset(unsigned offset) -{ - unsigned reg; - ArchSpec arch = Host::GetArchitecture(); - - switch (arch.GetCore()) - { - default: - assert(false && "CPU type not supported!"); - break; - - case ArchSpec::eCore_x86_32_i386: - case ArchSpec::eCore_x86_32_i486: - case ArchSpec::eCore_x86_32_i486sx: - reg = RegisterContext_i386::GetRegisterIndexFromOffset(offset); - break; - - case ArchSpec::eCore_x86_64_x86_64: - reg = RegisterContext_x86_64::GetRegisterIndexFromOffset(offset); - break; - } - return reg; -} - -const char * -POSIXThread::GetRegisterName(unsigned reg) -{ - const char * name; - ArchSpec arch = Host::GetArchitecture(); - - switch (arch.GetCore()) - { - default: - assert(false && "CPU type not supported!"); - break; - - case ArchSpec::eCore_x86_32_i386: - case ArchSpec::eCore_x86_32_i486: - case ArchSpec::eCore_x86_32_i486sx: - name = RegisterContext_i386::GetRegisterName(reg); - break; - - case ArchSpec::eCore_x86_64_x86_64: - name = RegisterContext_x86_64::GetRegisterName(reg); - break; - } - return name; -} - -const char * -POSIXThread::GetRegisterNameFromOffset(unsigned offset) -{ - return GetRegisterName(GetRegisterIndexFromOffset(offset)); -} - diff --git a/lldb/source/Plugins/Process/POSIX/POSIXThread.h b/lldb/source/Plugins/Process/POSIX/POSIXThread.h deleted file mode 100644 index 7343884fe99a..000000000000 --- a/lldb/source/Plugins/Process/POSIX/POSIXThread.h +++ /dev/null @@ -1,106 +0,0 @@ -//===-- POSIXThread.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_POSIXThread_H_ -#define liblldb_POSIXThread_H_ - -// C Includes -// C++ Includes -#include <memory> - -// Other libraries and framework includes -#include "lldb/Target/Thread.h" -#include "RegisterContextPOSIX.h" - -class ProcessMessage; -class ProcessMonitor; -class RegisterContextPOSIX; - -//------------------------------------------------------------------------------ -// @class POSIXThread -// @brief Abstraction of a linux process (thread). -class POSIXThread - : public lldb_private::Thread -{ -public: - POSIXThread(lldb::ProcessSP &process, lldb::tid_t tid); - - virtual ~POSIXThread(); - - void - RefreshStateAfterStop(); - - bool - WillResume(lldb::StateType resume_state); - - const char * - GetInfo(); - - virtual lldb::RegisterContextSP - GetRegisterContext(); - - virtual lldb::RegisterContextSP - CreateRegisterContextForFrame (lldb_private::StackFrame *frame); - - //-------------------------------------------------------------------------- - // These static functions provide a mapping from the register offset - // back to the register index or name for use in debugging or log - // output. - - static unsigned - GetRegisterIndexFromOffset(unsigned offset); - - static const char * - GetRegisterName(unsigned reg); - - static const char * - GetRegisterNameFromOffset(unsigned offset); - - //-------------------------------------------------------------------------- - // These methods form a specialized interface to linux threads. - // - bool Resume(); - - void Notify(const ProcessMessage &message); - -private: - RegisterContextPOSIX * - GetRegisterContextPOSIX () - { - if (!m_reg_context_sp) - m_reg_context_sp = GetRegisterContext(); -#if 0 - return dynamic_cast<RegisterContextPOSIX*>(m_reg_context_sp.get()); -#endif - return (RegisterContextPOSIX *)m_reg_context_sp.get(); - } - - std::auto_ptr<lldb_private::StackFrame> m_frame_ap; - - lldb::BreakpointSiteSP m_breakpoint; - lldb::StopInfoSP m_stop_info; - - ProcessMonitor & - GetMonitor(); - - lldb::StopInfoSP - GetPrivateStopReason(); - - void BreakNotify(const ProcessMessage &message); - void TraceNotify(const ProcessMessage &message); - void LimboNotify(const ProcessMessage &message); - void SignalNotify(const ProcessMessage &message); - void SignalDeliveredNotify(const ProcessMessage &message); - void CrashNotify(const ProcessMessage &message); - - lldb_private::Unwind * - GetUnwinder(); -}; - -#endif // #ifndef liblldb_POSIXThread_H_ diff --git a/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp b/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp deleted file mode 100644 index 2e72b592a0d4..000000000000 --- a/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp +++ /dev/null @@ -1,245 +0,0 @@ -//===-- ProcessMessage.cpp --------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "ProcessMessage.h" - -using namespace lldb_private; - -const char * -ProcessMessage::GetCrashReasonString(CrashReason reason) -{ - const char *str = NULL; - - switch (reason) - { - default: - assert(false && "invalid CrashReason"); - break; - - case eInvalidAddress: - str = "invalid address"; - break; - case ePrivilegedAddress: - str = "address access protected"; - break; - case eIllegalOpcode: - str = "illegal instruction"; - break; - case eIllegalOperand: - str = "illegal instruction operand"; - break; - case eIllegalAddressingMode: - str = "illegal addressing mode"; - break; - case eIllegalTrap: - str = "illegal trap"; - break; - case ePrivilegedOpcode: - str = "privileged instruction"; - break; - case ePrivilegedRegister: - str = "privileged register"; - break; - case eCoprocessorError: - str = "coprocessor error"; - break; - case eInternalStackError: - str = "internal stack error"; - break; - case eIllegalAlignment: - str = "illegal alignment"; - break; - case eIllegalAddress: - str = "illegal address"; - break; - case eHardwareError: - str = "hardware error"; - break; - case eIntegerDivideByZero: - str = "integer divide by zero"; - break; - case eIntegerOverflow: - str = "integer overflow"; - break; - case eFloatDivideByZero: - str = "floating point divide by zero"; - break; - case eFloatOverflow: - str = "floating point overflow"; - break; - case eFloatUnderflow: - str = "floating point underflow"; - break; - case eFloatInexactResult: - str = "inexact floating point result"; - break; - case eFloatInvalidOperation: - str = "invalid floating point operation"; - break; - case eFloatSubscriptRange: - str = "invalid floating point subscript range"; - break; - } - - return str; -} - -const char * -ProcessMessage::PrintCrashReason(CrashReason reason) -{ -#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION - // Just return the code in asci for integration builds. - chcar str[8]; - sprintf(str, "%d", reason); -#else - const char *str = NULL; - - switch (reason) - { - default: - assert(false && "invalid CrashReason"); - break; - - case eInvalidCrashReason: - str = "eInvalidCrashReason"; - break; - - // SIGSEGV crash reasons. - case eInvalidAddress: - str = "eInvalidAddress"; - break; - case ePrivilegedAddress: - str = "ePrivilegedAddress"; - break; - - // SIGILL crash reasons. - case eIllegalOpcode: - str = "eIllegalOpcode"; - break; - case eIllegalOperand: - str = "eIllegalOperand"; - break; - case eIllegalAddressingMode: - str = "eIllegalAddressingMode"; - break; - case eIllegalTrap: - str = "eIllegalTrap"; - break; - case ePrivilegedOpcode: - str = "ePrivilegedOpcode"; - break; - case ePrivilegedRegister: - str = "ePrivilegedRegister"; - break; - case eCoprocessorError: - str = "eCoprocessorError"; - break; - case eInternalStackError: - str = "eInternalStackError"; - break; - - // SIGBUS crash reasons: - case eIllegalAlignment: - str = "eIllegalAlignment"; - break; - case eIllegalAddress: - str = "eIllegalAddress"; - break; - case eHardwareError: - str = "eHardwareError"; - break; - - // SIGFPE crash reasons: - case eIntegerDivideByZero: - str = "eIntegerDivideByZero"; - break; - case eIntegerOverflow: - str = "eIntegerOverflow"; - break; - case eFloatDivideByZero: - str = "eFloatDivideByZero"; - break; - case eFloatOverflow: - str = "eFloatOverflow"; - break; - case eFloatUnderflow: - str = "eFloatUnderflow"; - break; - case eFloatInexactResult: - str = "eFloatInexactResult"; - break; - case eFloatInvalidOperation: - str = "eFloatInvalidOperation"; - break; - case eFloatSubscriptRange: - str = "eFloatSubscriptRange"; - break; - } -#endif - - return str; -} - -const char * -ProcessMessage::PrintCrashReason() const -{ - return PrintCrashReason(m_crash_reason); -} - -const char * -ProcessMessage::PrintKind(Kind kind) -{ -#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION - // Just return the code in asci for integration builds. - chcar str[8]; - sprintf(str, "%d", reason); -#else - const char *str = NULL; - - switch (kind) - { - default: - assert(false && "invalid Kind"); - break; - - case eInvalidMessage: - str = "eInvalidMessage"; - break; - case eExitMessage: - str = "eExitMessage"; - break; - case eLimboMessage: - str = "eLimboMessage"; - break; - case eSignalMessage: - str = "eSignalMessage"; - break; - case eSignalDeliveredMessage: - str = "eSignalDeliveredMessage"; - break; - case eTraceMessage: - str = "eTraceMessage"; - break; - case eBreakpointMessage: - str = "eBreakpointMessage"; - break; - case eCrashMessage: - str = "eCrashMessage"; - break; - } -#endif - - return str; -} - -const char * -ProcessMessage::PrintKind() const -{ - return PrintKind(m_kind); -} diff --git a/lldb/source/Plugins/Process/POSIX/ProcessMessage.h b/lldb/source/Plugins/Process/POSIX/ProcessMessage.h deleted file mode 100644 index 826567e582b4..000000000000 --- a/lldb/source/Plugins/Process/POSIX/ProcessMessage.h +++ /dev/null @@ -1,171 +0,0 @@ -//===-- ProcessMessage.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_ProcessMessage_H_ -#define liblldb_ProcessMessage_H_ - -#include <cassert> - -#include "lldb/lldb-defines.h" -#include "lldb/lldb-types.h" - -class ProcessMessage -{ -public: - - /// The type of signal this message can correspond to. - enum Kind - { - eInvalidMessage, - eExitMessage, - eLimboMessage, - eSignalMessage, - eSignalDeliveredMessage, - eTraceMessage, - eBreakpointMessage, - eCrashMessage - }; - - enum CrashReason - { - eInvalidCrashReason, - - // SIGSEGV crash reasons. - eInvalidAddress, - ePrivilegedAddress, - - // SIGILL crash reasons. - eIllegalOpcode, - eIllegalOperand, - eIllegalAddressingMode, - eIllegalTrap, - ePrivilegedOpcode, - ePrivilegedRegister, - eCoprocessorError, - eInternalStackError, - - // SIGBUS crash reasons, - eIllegalAlignment, - eIllegalAddress, - eHardwareError, - - // SIGFPE crash reasons, - eIntegerDivideByZero, - eIntegerOverflow, - eFloatDivideByZero, - eFloatOverflow, - eFloatUnderflow, - eFloatInexactResult, - eFloatInvalidOperation, - eFloatSubscriptRange - }; - - ProcessMessage() - : m_tid(LLDB_INVALID_PROCESS_ID), - m_kind(eInvalidMessage), - m_crash_reason(eInvalidCrashReason), - m_status(0), - m_addr(0) { } - - Kind GetKind() const { return m_kind; } - - lldb::tid_t GetTID() const { return m_tid; } - - /// Indicates that the thread @p tid is about to exit with status @p status. - static ProcessMessage Limbo(lldb::tid_t tid, int status) { - return ProcessMessage(tid, eLimboMessage, status); - } - - /// Indicates that the thread @p tid had the signal @p signum delivered. - static ProcessMessage Signal(lldb::tid_t tid, int signum) { - return ProcessMessage(tid, eSignalMessage, signum); - } - - /// Indicates that a signal @p signum generated by the debugging process was - /// delivered to the thread @p tid. - static ProcessMessage SignalDelivered(lldb::tid_t tid, int signum) { - return ProcessMessage(tid, eSignalDeliveredMessage, signum); - } - - /// Indicates that the thread @p tid encountered a trace point. - static ProcessMessage Trace(lldb::tid_t tid) { - return ProcessMessage(tid, eTraceMessage); - } - - /// Indicates that the thread @p tid encountered a break point. - static ProcessMessage Break(lldb::tid_t tid) { - return ProcessMessage(tid, eBreakpointMessage); - } - - /// Indicates that the thread @p tid crashed. - static ProcessMessage Crash(lldb::pid_t pid, CrashReason reason, - int signo, lldb::addr_t fault_addr) { - ProcessMessage message(pid, eCrashMessage, signo, fault_addr); - message.m_crash_reason = reason; - return message; - } - - int GetExitStatus() const { - assert(GetKind() == eExitMessage || GetKind() == eLimboMessage); - return m_status; - } - - int GetSignal() const { - assert(GetKind() == eSignalMessage || GetKind() == eCrashMessage || - GetKind() == eSignalDeliveredMessage); - return m_status; - } - - int GetStopStatus() const { - assert(GetKind() == eSignalMessage); - return m_status; - } - - CrashReason GetCrashReason() const { - assert(GetKind() == eCrashMessage); - return m_crash_reason; - } - - lldb::addr_t GetFaultAddress() const { - assert(GetKind() == eCrashMessage); - return m_addr; - } - - static const char * - GetCrashReasonString(CrashReason reason); - - const char * - PrintCrashReason() const; - - static const char * - PrintCrashReason(CrashReason reason); - - const char * - PrintKind() const; - - static const char * - PrintKind(Kind); - -private: - ProcessMessage(lldb::tid_t tid, Kind kind, - int status = 0, lldb::addr_t addr = 0) - : m_tid(tid), - m_kind(kind), - m_crash_reason(eInvalidCrashReason), - m_status(status), - m_addr(addr) { } - - lldb::tid_t m_tid; - Kind m_kind : 8; - CrashReason m_crash_reason : 8; - int m_status; - lldb::addr_t m_addr; -}; - -#endif // #ifndef liblldb_ProcessMessage_H_ diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp deleted file mode 100644 index fd1b0e0ebad7..000000000000 --- a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp +++ /dev/null @@ -1,598 +0,0 @@ -//===-- ProcessPOSIX.cpp ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -#include <errno.h> - -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" -#include "lldb/Host/Host.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Target/DynamicLoader.h" -#include "lldb/Target/Target.h" - -#include "ProcessPOSIX.h" -#include "ProcessPOSIXLog.h" -#include "Plugins/Process/Utility/InferiorCallPOSIX.h" -#include "ProcessMonitor.h" -#include "POSIXThread.h" - -using namespace lldb; -using namespace lldb_private; - -//------------------------------------------------------------------------------ -// Static functions. -#if 0 -Process* -ProcessPOSIX::CreateInstance(Target& target, Listener &listener) -{ - return new ProcessPOSIX(target, listener); -} - - -void -ProcessPOSIX::Initialize() -{ - static bool g_initialized = false; - - if (!g_initialized) - { - g_initialized = true; - PluginManager::RegisterPlugin(GetPluginNameStatic(), - GetPluginDescriptionStatic(), - CreateInstance); - - Log::Callbacks log_callbacks = { - ProcessPOSIXLog::DisableLog, - ProcessPOSIXLog::EnableLog, - ProcessPOSIXLog::ListLogCategories - }; - - Log::RegisterLogChannel (ProcessPOSIX::GetPluginNameStatic(), log_callbacks); - } -} -#endif - -//------------------------------------------------------------------------------ -// Constructors and destructors. - -ProcessPOSIX::ProcessPOSIX(Target& target, Listener &listener) - : Process(target, listener), - m_byte_order(lldb::endian::InlHostByteOrder()), - m_monitor(NULL), - m_module(NULL), - m_in_limbo(false), - m_exit_now(false) -{ - // FIXME: Putting this code in the ctor and saving the byte order in a - // member variable is a hack to avoid const qual issues in GetByteOrder. - lldb::ModuleSP module = GetTarget().GetExecutableModule(); - if (module != NULL && module->GetObjectFile() != NULL) - m_byte_order = module->GetObjectFile()->GetByteOrder(); -} - -ProcessPOSIX::~ProcessPOSIX() -{ - delete m_monitor; -} - -//------------------------------------------------------------------------------ -// Process protocol. - -bool -ProcessPOSIX::CanDebug(Target &target, bool plugin_specified_by_name) -{ - // For now we are just making sure the file exists for a given module - ModuleSP exe_module_sp(target.GetExecutableModule()); - if (exe_module_sp.get()) - return exe_module_sp->GetFileSpec().Exists(); - return false; -} - -Error -ProcessPOSIX::DoAttachToProcessWithID(lldb::pid_t pid) -{ - Error error; - assert(m_monitor == NULL); - - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf ("ProcessPOSIX::%s(pid = %i)", __FUNCTION__, GetID()); - - m_monitor = new ProcessMonitor(this, pid, error); - - if (!error.Success()) - return error; - - SetID(pid); - return error; -} - -Error -ProcessPOSIX::WillLaunch(Module* module) -{ - Error error; - return error; -} - -const char * -ProcessPOSIX::GetFilePath( - const lldb_private::ProcessLaunchInfo::FileAction *file_action, - const char *default_path) -{ - const char *pts_name = "/dev/pts/"; - const char *path = NULL; - - if (file_action) - { - if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen) - path = file_action->GetPath(); - // By default the stdio paths passed in will be pseudo-terminal - // (/dev/pts). If so, convert to using a different default path - // instead to redirect I/O to the debugger console. This should - // also handle user overrides to /dev/null or a different file. - if (::strncmp(path, pts_name, ::strlen(pts_name)) == 0) - path = default_path; - } - - return path; -} - -Error -ProcessPOSIX::DoLaunch (Module *module, - const ProcessLaunchInfo &launch_info) -{ - Error error; - assert(m_monitor == NULL); - - SetPrivateState(eStateLaunching); - - const lldb_private::ProcessLaunchInfo::FileAction *file_action; - - // Default of NULL will mean to use existing open file descriptors - const char *stdin_path = NULL; - const char *stdout_path = NULL; - const char *stderr_path = NULL; - - file_action = launch_info.GetFileActionForFD (STDIN_FILENO); - stdin_path = GetFilePath(file_action, stdin_path); - - file_action = launch_info.GetFileActionForFD (STDOUT_FILENO); - stdout_path = GetFilePath(file_action, stdout_path); - - file_action = launch_info.GetFileActionForFD (STDERR_FILENO); - stderr_path = GetFilePath(file_action, stderr_path); - - m_monitor = new ProcessMonitor (this, - module, - launch_info.GetArguments().GetConstArgumentVector(), - launch_info.GetEnvironmentEntries().GetConstArgumentVector(), - stdin_path, - stdout_path, - stderr_path, - error); - - m_module = module; - - if (!error.Success()) - return error; - - SetID(m_monitor->GetPID()); - return error; -} - -void -ProcessPOSIX::DidLaunch() -{ -} - -Error -ProcessPOSIX::DoResume() -{ - StateType state = GetPrivateState(); - - assert(state == eStateStopped || state == eStateCrashed); - - // We are about to resume a thread that will cause the process to exit so - // set our exit status now. Do not change our state if the inferior - // crashed. - if (state == eStateStopped) - { - if (m_in_limbo) - SetExitStatus(m_exit_status, NULL); - else - SetPrivateState(eStateRunning); - } - - bool did_resume = false; - uint32_t thread_count = m_thread_list.GetSize(false); - for (uint32_t i = 0; i < thread_count; ++i) - { - POSIXThread *thread = static_cast<POSIXThread*>( - m_thread_list.GetThreadAtIndex(i, false).get()); - did_resume = thread->Resume() || did_resume; - } - assert(did_resume && "Process resume failed!"); - - return Error(); -} - -addr_t -ProcessPOSIX::GetImageInfoAddress() -{ - Target *target = &GetTarget(); - ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile(); - Address addr = obj_file->GetImageInfoAddress(); - - if (addr.IsValid()) - return addr.GetLoadAddress(target); - else - return LLDB_INVALID_ADDRESS; -} - -Error -ProcessPOSIX::DoHalt(bool &caused_stop) -{ - Error error; - - if (IsStopped()) - { - caused_stop = false; - } - else if (kill(GetID(), SIGSTOP)) - { - caused_stop = false; - error.SetErrorToErrno(); - } - else - { - caused_stop = true; - } - - return error; -} - -Error -ProcessPOSIX::DoDetach() -{ - Error error; - - error = m_monitor->Detach(); - if (error.Success()) - SetPrivateState(eStateDetached); - - return error; -} - -Error -ProcessPOSIX::DoSignal(int signal) -{ - Error error; - - if (kill(GetID(), signal)) - error.SetErrorToErrno(); - - return error; -} - -Error -ProcessPOSIX::DoDestroy() -{ - Error error; - - if (!HasExited()) - { - // Drive the exit event to completion (do not keep the inferior in - // limbo). - m_exit_now = true; - - if ((m_monitor == NULL || kill(m_monitor->GetPID(), SIGKILL)) && error.Success()) - { - error.SetErrorToErrno(); - return error; - } - - SetPrivateState(eStateExited); - } - - return error; -} - -void -ProcessPOSIX::SendMessage(const ProcessMessage &message) -{ - Mutex::Locker lock(m_message_mutex); - - switch (message.GetKind()) - { - default: - assert(false && "Unexpected process message!"); - break; - - case ProcessMessage::eInvalidMessage: - return; - - case ProcessMessage::eLimboMessage: - m_in_limbo = true; - m_exit_status = message.GetExitStatus(); - if (m_exit_now) - { - SetPrivateState(eStateExited); - m_monitor->Detach(); - } - else - SetPrivateState(eStateStopped); - break; - - case ProcessMessage::eExitMessage: - m_exit_status = message.GetExitStatus(); - SetExitStatus(m_exit_status, NULL); - break; - - case ProcessMessage::eTraceMessage: - case ProcessMessage::eBreakpointMessage: - SetPrivateState(eStateStopped); - break; - - case ProcessMessage::eSignalMessage: - case ProcessMessage::eSignalDeliveredMessage: - SetPrivateState(eStateStopped); - break; - - case ProcessMessage::eCrashMessage: - SetPrivateState(eStateCrashed); - break; - } - - m_message_queue.push(message); -} - -void -ProcessPOSIX::RefreshStateAfterStop() -{ - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf ("ProcessPOSIX::%s()", __FUNCTION__); - - Mutex::Locker lock(m_message_mutex); - if (m_message_queue.empty()) - return; - - ProcessMessage &message = m_message_queue.front(); - - // Resolve the thread this message corresponds to and pass it along. - // FIXME: we're really dealing with the pid here. This should get - // fixed when this code is fixed to handle multiple threads. - lldb::tid_t tid = message.GetTID(); - if (log) - log->Printf ("ProcessPOSIX::%s() pid = %i", __FUNCTION__, tid); - POSIXThread *thread = static_cast<POSIXThread*>( - GetThreadList().FindThreadByID(tid, false).get()); - - assert(thread); - thread->Notify(message); - - m_message_queue.pop(); -} - -bool -ProcessPOSIX::IsAlive() -{ - StateType state = GetPrivateState(); - return state != eStateDetached && state != eStateExited && state != eStateInvalid; -} - -size_t -ProcessPOSIX::DoReadMemory(addr_t vm_addr, - void *buf, size_t size, Error &error) -{ - assert(m_monitor); - return m_monitor->ReadMemory(vm_addr, buf, size, error); -} - -size_t -ProcessPOSIX::DoWriteMemory(addr_t vm_addr, const void *buf, size_t size, - Error &error) -{ - assert(m_monitor); - return m_monitor->WriteMemory(vm_addr, buf, size, error); -} - -addr_t -ProcessPOSIX::DoAllocateMemory(size_t size, uint32_t permissions, - Error &error) -{ - addr_t allocated_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; - - if (InferiorCallMmap(this, allocated_addr, 0, size, prot, - eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) { - m_addr_to_mmap_size[allocated_addr] = size; - error.Clear(); - } else { - allocated_addr = LLDB_INVALID_ADDRESS; - error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions)); - } - - return allocated_addr; -} - -Error -ProcessPOSIX::DoDeallocateMemory(lldb::addr_t addr) -{ - Error error; - MMapMap::iterator pos = m_addr_to_mmap_size.find(addr); - if (pos != m_addr_to_mmap_size.end() && - InferiorCallMunmap(this, addr, pos->second)) - m_addr_to_mmap_size.erase (pos); - else - error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr); - - return error; -} - -size_t -ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site) -{ - static const uint8_t g_i386_opcode[] = { 0xCC }; - - ArchSpec arch = GetTarget().GetArchitecture(); - const uint8_t *opcode = NULL; - size_t opcode_size = 0; - - switch (arch.GetCore()) - { - default: - assert(false && "CPU type not supported!"); - break; - - case ArchSpec::eCore_x86_32_i386: - case ArchSpec::eCore_x86_64_x86_64: - opcode = g_i386_opcode; - opcode_size = sizeof(g_i386_opcode); - break; - } - - bp_site->SetTrapOpcode(opcode, opcode_size); - return opcode_size; -} - -Error -ProcessPOSIX::EnableBreakpoint(BreakpointSite *bp_site) -{ - return EnableSoftwareBreakpoint(bp_site); -} - -Error -ProcessPOSIX::DisableBreakpoint(BreakpointSite *bp_site) -{ - return DisableSoftwareBreakpoint(bp_site); -} - -uint32_t -ProcessPOSIX::UpdateThreadListIfNeeded() -{ - // Do not allow recursive updates. - return m_thread_list.GetSize(false); -} - -bool -ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) -{ - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD)); - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf ("ProcessPOSIX::%s() (pid = %i)", __FUNCTION__, GetID()); - - // Update the process thread list with this new thread. - // FIXME: We should be using tid, not pid. - assert(m_monitor); - ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false)); - if (!thread_sp) { - ProcessSP me = this->shared_from_this(); - thread_sp.reset(new POSIXThread(me, GetID())); - } - - if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) - log->Printf ("ProcessPOSIX::%s() updated pid = %i", __FUNCTION__, GetID()); - new_thread_list.AddThread(thread_sp); - - return new_thread_list.GetSize(false) > 0; -} - -ByteOrder -ProcessPOSIX::GetByteOrder() const -{ - // FIXME: We should be able to extract this value directly. See comment in - // ProcessPOSIX(). - return m_byte_order; -} - -size_t -ProcessPOSIX::PutSTDIN(const char *buf, size_t len, Error &error) -{ - ssize_t status; - if ((status = write(m_monitor->GetTerminalFD(), buf, len)) < 0) - { - error.SetErrorToErrno(); - return 0; - } - return status; -} - -size_t -ProcessPOSIX::GetSTDOUT(char *buf, size_t len, Error &error) -{ - ssize_t bytes_read; - - // The terminal file descriptor is always in non-block mode. - if ((bytes_read = read(m_monitor->GetTerminalFD(), buf, len)) < 0) - { - if (errno != EAGAIN) - error.SetErrorToErrno(); - return 0; - } - return bytes_read; -} - -size_t -ProcessPOSIX::GetSTDERR(char *buf, size_t len, Error &error) -{ - return GetSTDOUT(buf, len, error); -} - -UnixSignals & -ProcessPOSIX::GetUnixSignals() -{ - return m_signals; -} - -//------------------------------------------------------------------------------ -// Utility functions. - -bool -ProcessPOSIX::HasExited() -{ - switch (GetPrivateState()) - { - default: - break; - - case eStateDetached: - case eStateExited: - return true; - } - - return false; -} - -bool -ProcessPOSIX::IsStopped() -{ - switch (GetPrivateState()) - { - default: - break; - - case eStateStopped: - case eStateCrashed: - case eStateSuspended: - return true; - } - - return false; -} diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h b/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h deleted file mode 100644 index adcdee5de923..000000000000 --- a/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h +++ /dev/null @@ -1,180 +0,0 @@ -//===-- ProcessPOSIX.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_ProcessPOSIX_H_ -#define liblldb_ProcessPOSIX_H_ - -// C Includes - -// C++ Includes -#include <queue> - -// Other libraries and framework includes -#include "lldb/Target/Process.h" -#include "lldb/Target/UnixSignals.h" -#include "ProcessMessage.h" - -class ProcessMonitor; - -class ProcessPOSIX : - public lldb_private::Process -{ -public: - - //------------------------------------------------------------------ - // Constructors and destructors - //------------------------------------------------------------------ - ProcessPOSIX(lldb_private::Target& target, - lldb_private::Listener &listener); - - virtual - ~ProcessPOSIX(); - - //------------------------------------------------------------------ - // Process protocol. - //------------------------------------------------------------------ - virtual bool - CanDebug(lldb_private::Target &target, bool plugin_specified_by_name); - - virtual lldb_private::Error - WillLaunch(lldb_private::Module *module); - - virtual lldb_private::Error - DoAttachToProcessWithID(lldb::pid_t pid); - - virtual lldb_private::Error - DoLaunch (lldb_private::Module *exe_module, - const lldb_private::ProcessLaunchInfo &launch_info); - - virtual void - DidLaunch(); - - virtual lldb_private::Error - DoResume(); - - virtual lldb_private::Error - DoHalt(bool &caused_stop); - - virtual lldb_private::Error - DoDetach(); - - virtual lldb_private::Error - DoSignal(int signal); - - virtual lldb_private::Error - DoDestroy(); - - virtual void - RefreshStateAfterStop(); - - virtual bool - IsAlive(); - - virtual size_t - DoReadMemory(lldb::addr_t vm_addr, - void *buf, - size_t size, - lldb_private::Error &error); - - virtual size_t - DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, - lldb_private::Error &error); - - virtual lldb::addr_t - DoAllocateMemory(size_t size, uint32_t permissions, - lldb_private::Error &error); - - virtual lldb_private::Error - DoDeallocateMemory(lldb::addr_t ptr); - - virtual size_t - GetSoftwareBreakpointTrapOpcode(lldb_private::BreakpointSite* bp_site); - - virtual lldb_private::Error - EnableBreakpoint(lldb_private::BreakpointSite *bp_site); - - virtual lldb_private::Error - DisableBreakpoint(lldb_private::BreakpointSite *bp_site); - - virtual uint32_t - UpdateThreadListIfNeeded(); - - virtual bool - UpdateThreadList(lldb_private::ThreadList &old_thread_list, - lldb_private::ThreadList &new_thread_list) = 0; - - virtual lldb::ByteOrder - GetByteOrder() const; - - virtual lldb::addr_t - GetImageInfoAddress(); - - virtual size_t - PutSTDIN(const char *buf, size_t len, lldb_private::Error &error); - - virtual size_t - GetSTDOUT(char *buf, size_t len, lldb_private::Error &error); - - virtual size_t - GetSTDERR(char *buf, size_t len, lldb_private::Error &error); - - //-------------------------------------------------------------------------- - // ProcessPOSIX internal API. - - /// Registers the given message with this process. - void SendMessage(const ProcessMessage &message); - - ProcessMonitor & - GetMonitor() { assert(m_monitor); return *m_monitor; } - - lldb_private::UnixSignals & - GetUnixSignals(); - - const char * - GetFilePath(const lldb_private::ProcessLaunchInfo::FileAction *file_action, - const char *default_path); - -protected: - /// Target byte order. - lldb::ByteOrder m_byte_order; - - /// Process monitor; - ProcessMonitor *m_monitor; - - /// The module we are executing. - lldb_private::Module *m_module; - - /// Message queue notifying this instance of inferior process state changes. - lldb_private::Mutex m_message_mutex; - std::queue<ProcessMessage> m_message_queue; - - /// True when the process has entered a state of "limbo". - /// - /// This flag qualifies eStateStopped. It lets us know that when we - /// continue from this state the process will exit. Also, when true, - /// Process::m_exit_status is set. - bool m_in_limbo; - - /// Drive any exit events to completion. - bool m_exit_now; - - /// OS-specific signal set. - lldb_private::UnixSignals m_signals; - - /// Returns true if the process has exited. - bool HasExited(); - - /// Returns true if the process is stopped. - bool IsStopped(); - - typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap; - MMapMap m_addr_to_mmap_size; -}; - -#endif // liblldb_MacOSXProcess_H_ diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp b/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp deleted file mode 100644 index 017035d483ee..000000000000 --- a/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp +++ /dev/null @@ -1,188 +0,0 @@ -//===-- ProcessPOSIXLog.cpp ---------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "ProcessPOSIXLog.h" - -#include "lldb/Interpreter/Args.h" -#include "lldb/Core/StreamFile.h" - -#include "ProcessPOSIX.h" -#include "ProcessPOSIXLog.h" - -using namespace lldb; -using namespace lldb_private; - - -// We want to avoid global constructors where code needs to be run so here we -// control access to our static g_log_sp by hiding it in a singleton function -// that will construct the static g_lob_sp the first time this function is -// called. -static LogSP & -GetLog () -{ - static LogSP g_log_sp; - return g_log_sp; -} - -LogSP -ProcessPOSIXLog::GetLogIfAllCategoriesSet (uint32_t mask) -{ - LogSP log(GetLog ()); - if (log && mask) - { - uint32_t log_mask = log->GetMask().Get(); - if ((log_mask & mask) != mask) - return LogSP(); - } - return log; -} - -void -ProcessPOSIXLog::DisableLog (const char **args, Stream *feedback_strm) -{ - LogSP log (GetLog ()); - if (log) - { - uint32_t flag_bits = 0; - - flag_bits = log->GetMask().Get(); - for (; args[0]; args++) - { - const char *arg = args[0]; - - if (::strcasecmp (arg, "all") == 0 ) flag_bits &= ~POSIX_LOG_ALL; - else if (::strcasecmp (arg, "async") == 0 ) flag_bits &= ~POSIX_LOG_ASYNC; - else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits &= ~POSIX_LOG_BREAKPOINTS; - else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits &= ~POSIX_LOG_COMM; - else if (::strcasecmp (arg, "default") == 0 ) flag_bits &= ~POSIX_LOG_DEFAULT; - else if (::strcasecmp (arg, "packets") == 0 ) flag_bits &= ~POSIX_LOG_PACKETS; - else if (::strcasecmp (arg, "memory") == 0 ) flag_bits &= ~POSIX_LOG_MEMORY; - else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits &= ~POSIX_LOG_MEMORY_DATA_SHORT; - else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits &= ~POSIX_LOG_MEMORY_DATA_LONG; - else if (::strcasecmp (arg, "process") == 0 ) flag_bits &= ~POSIX_LOG_PROCESS; - else if (::strcasecmp (arg, "ptrace") == 0 ) flag_bits &= ~POSIX_LOG_PTRACE; - else if (::strcasecmp (arg, "registers") == 0 ) flag_bits &= ~POSIX_LOG_REGISTERS; - else if (::strcasecmp (arg, "step") == 0 ) flag_bits &= ~POSIX_LOG_STEP; - else if (::strcasecmp (arg, "thread") == 0 ) flag_bits &= ~POSIX_LOG_THREAD; - else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits &= ~POSIX_LOG_VERBOSE; - else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits &= ~POSIX_LOG_WATCHPOINTS; - else - { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - ListLogCategories (feedback_strm); - } - } - - if (flag_bits == 0) - GetLog ().reset(); - else - log->GetMask().Reset (flag_bits); - } - - return; -} - -LogSP -ProcessPOSIXLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **args, Stream *feedback_strm) -{ - // Try see if there already is a log - that way we can reuse its settings. - // We could reuse the log in toto, but we don't know that the stream is the same. - uint32_t flag_bits = 0; - LogSP log(GetLog ()); - if (log) - flag_bits = log->GetMask().Get(); - - // Now make a new log with this stream if one was provided - if (log_stream_sp) - { - log = LogSP(new Log(log_stream_sp)); - GetLog () = log; - } - - if (log) - { - bool got_unknown_category = false; - for (; args[0]; args++) - { - const char *arg = args[0]; - - if (::strcasecmp (arg, "all") == 0 ) flag_bits |= POSIX_LOG_ALL; - else if (::strcasecmp (arg, "async") == 0 ) flag_bits |= POSIX_LOG_ASYNC; - else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits |= POSIX_LOG_BREAKPOINTS; - else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits |= POSIX_LOG_COMM; - else if (::strcasecmp (arg, "default") == 0 ) flag_bits |= POSIX_LOG_DEFAULT; - else if (::strcasecmp (arg, "packets") == 0 ) flag_bits |= POSIX_LOG_PACKETS; - else if (::strcasecmp (arg, "memory") == 0 ) flag_bits |= POSIX_LOG_MEMORY; - else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits |= POSIX_LOG_MEMORY_DATA_SHORT; - else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits |= POSIX_LOG_MEMORY_DATA_LONG; - else if (::strcasecmp (arg, "process") == 0 ) flag_bits |= POSIX_LOG_PROCESS; - else if (::strcasecmp (arg, "ptrace") == 0 ) flag_bits |= POSIX_LOG_PTRACE; - else if (::strcasecmp (arg, "registers") == 0 ) flag_bits |= POSIX_LOG_REGISTERS; - else if (::strcasecmp (arg, "step") == 0 ) flag_bits |= POSIX_LOG_STEP; - else if (::strcasecmp (arg, "thread") == 0 ) flag_bits |= POSIX_LOG_THREAD; - else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits |= POSIX_LOG_VERBOSE; - else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits |= POSIX_LOG_WATCHPOINTS; - else - { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - if (got_unknown_category == false) - { - got_unknown_category = true; - ListLogCategories (feedback_strm); - } - } - } - if (flag_bits == 0) - flag_bits = POSIX_LOG_DEFAULT; - log->GetMask().Reset(flag_bits); - log->GetOptions().Reset(log_options); - } - return log; -} - -void -ProcessPOSIXLog::ListLogCategories (Stream *strm) -{ - strm->Printf ("Logging categories for '%s':\n" - " all - turn on all available logging categories\n" - " async - log asynchronous activity\n" - " break - log breakpoints\n" - " communication - log communication activity\n" - " default - enable the default set of logging categories for liblldb\n" - " packets - log gdb remote packets\n" - " memory - log memory reads and writes\n" - " data-short - log memory bytes for memory reads and writes for short transactions only\n" - " data-long - log memory bytes for memory reads and writes for all transactions\n" - " process - log process events and activities\n" -#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION - " ptrace - log all calls to ptrace\n" -#endif - " registers - log register read/writes\n" - " thread - log thread events and activities\n" - " step - log step related activities\n" - " verbose - enable verbose logging\n" - " watch - log watchpoint related activities\n", ProcessPOSIXLog::m_pluginname); -} - - -void -ProcessPOSIXLog::LogIf (uint32_t mask, const char *format, ...) -{ - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (mask)); - if (log) - { - va_list args; - va_start (args, format); - log->VAPrintf (format, args); - va_end (args); - } -} - -int ProcessPOSIXLog::m_nestinglevel; -const char *ProcessPOSIXLog::m_pluginname = ""; diff --git a/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h b/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h deleted file mode 100644 index 2e4000c0389a..000000000000 --- a/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h +++ /dev/null @@ -1,106 +0,0 @@ -//===-- ProcessLinuxLog.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_ProcessLinuxLog_h_ -#define liblldb_ProcessLinuxLog_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes - -// Project includes -#include "lldb/Core/Log.h" - -#define POSIX_LOG_VERBOSE (1u << 0) -#define POSIX_LOG_PROCESS (1u << 1) -#define POSIX_LOG_THREAD (1u << 2) -#define POSIX_LOG_PACKETS (1u << 3) -#define POSIX_LOG_MEMORY (1u << 4) // Log memory reads/writes calls -#define POSIX_LOG_MEMORY_DATA_SHORT (1u << 5) // Log short memory reads/writes bytes -#define POSIX_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes -#define POSIX_LOG_BREAKPOINTS (1u << 7) -#define POSIX_LOG_WATCHPOINTS (1u << 8) -#define POSIX_LOG_STEP (1u << 9) -#define POSIX_LOG_COMM (1u << 10) -#define POSIX_LOG_ASYNC (1u << 11) -#define POSIX_LOG_PTRACE (1u << 12) -#define POSIX_LOG_REGISTERS (1u << 13) -#define POSIX_LOG_ALL (UINT32_MAX) -#define POSIX_LOG_DEFAULT POSIX_LOG_PACKETS - -// The size which determines "short memory reads/writes". -#define POSIX_LOG_MEMORY_SHORT_BYTES (4 * sizeof(ptrdiff_t)) - -class ProcessPOSIXLog -{ - static int m_nestinglevel; - static const char *m_pluginname; - -public: - static void - RegisterPluginName(const char *pluginName) - { - m_pluginname = pluginName; - } - - - static lldb::LogSP - GetLogIfAllCategoriesSet(uint32_t mask = 0); - - static void - DisableLog (const char **args, lldb_private::Stream *feedback_strm); - - static lldb::LogSP - EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options, - const char **args, lldb_private::Stream *feedback_strm); - - static void - ListLogCategories (lldb_private::Stream *strm); - - static void - LogIf (uint32_t mask, const char *format, ...); - - // The following functions can be used to enable the client to limit - // logging to only the top level function calls. This is useful for - // recursive functions. FIXME: not thread safe! - // Example: - // void NestingFunc() { - // LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet(POSIX_LOG_ALL)); - // if (log) - // { - // ProcessLinuxLog::IncNestLevel(); - // if (ProcessLinuxLog::AtTopNestLevel()) - // log->Print(msg); - // } - // NestingFunc(); - // if (log) - // ProcessLinuxLog::DecNestLevel(); - // } - - static bool - AtTopNestLevel() - { - return m_nestinglevel == 1; - } - - static void - IncNestLevel() - { - ++m_nestinglevel; - } - - static void - DecNestLevel() - { - --m_nestinglevel; - assert(m_nestinglevel >= 0); - } -}; - -#endif // liblldb_ProcessLinuxLog_h_ diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIX.h b/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIX.h deleted file mode 100644 index f97e710fcaa1..000000000000 --- a/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIX.h +++ /dev/null @@ -1,40 +0,0 @@ -//===-- RegisterContextPOSIX.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_RegisterContextPOSIX_H_ -#define liblldb_RegisterContextPOSIX_H_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "lldb/Target/RegisterContext.h" - -//------------------------------------------------------------------------------ -/// @class RegisterContextPOSIX -/// -/// @brief Extends RegisterClass with a few virtual operations useful on POSIX. -class RegisterContextPOSIX - : public lldb_private::RegisterContext -{ -public: - RegisterContextPOSIX(lldb_private::Thread &thread, - uint32_t concrete_frame_idx) - : RegisterContext(thread, concrete_frame_idx) { } - - /// Updates the register state of the associated thread after hitting a - /// breakpoint (if that make sense for the architecture). Default - /// implementation simply returns true for architectures which do not - /// require any update. - /// - /// @return - /// True if the operation succeeded and false otherwise. - virtual bool UpdateAfterBreakpoint() { return true; } -}; - -#endif // #ifndef liblldb_RegisterContextPOSIX_H_ diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContext_i386.cpp b/lldb/source/Plugins/Process/POSIX/RegisterContext_i386.cpp deleted file mode 100644 index 9485164c2b6a..000000000000 --- a/lldb/source/Plugins/Process/POSIX/RegisterContext_i386.cpp +++ /dev/null @@ -1,644 +0,0 @@ -//===-- RegisterContextPOSIX_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 "lldb/Core/DataExtractor.h" -#include "lldb/Target/Thread.h" -#include "lldb/Host/Endian.h" - -#include "ProcessPOSIX.h" -#include "ProcessPOSIXLog.h" -#include "ProcessMonitor.h" -#include "RegisterContext_i386.h" - -using namespace lldb_private; -using namespace lldb; - -enum -{ - k_first_gpr, - gpr_eax = k_first_gpr, - gpr_ebx, - gpr_ecx, - gpr_edx, - gpr_edi, - gpr_esi, - gpr_ebp, - gpr_esp, - gpr_ss, - gpr_eflags, -#ifdef __FreeBSD__ - gpr_orig_ax, -#endif - gpr_eip, - gpr_cs, - gpr_ds, - gpr_es, - gpr_fs, - gpr_gs, - k_last_gpr = gpr_gs, - - k_first_fpr, - fpu_fcw = k_first_fpr, - fpu_fsw, - fpu_ftw, - fpu_fop, - fpu_ip, - fpu_cs, - fpu_foo, - fpu_fos, - fpu_mxcsr, - fpu_stmm0, - fpu_stmm1, - fpu_stmm2, - fpu_stmm3, - fpu_stmm4, - fpu_stmm5, - fpu_stmm6, - fpu_stmm7, - fpu_xmm0, - fpu_xmm1, - fpu_xmm2, - fpu_xmm3, - fpu_xmm4, - fpu_xmm5, - fpu_xmm6, - fpu_xmm7, - k_last_fpr = fpu_xmm7, - - k_num_registers, - k_num_gpr_registers = k_last_gpr - k_first_gpr + 1, - k_num_fpu_registers = k_last_fpr - k_first_fpr + 1 -}; - -// Number of register sets provided by this context. -enum -{ - k_num_register_sets = 2 -}; - -enum -{ - gcc_eax = 0, - gcc_ecx, - gcc_edx, - gcc_ebx, - gcc_ebp, - gcc_esp, - gcc_esi, - gcc_edi, - gcc_eip, - gcc_eflags -}; - -enum -{ - dwarf_eax = 0, - dwarf_ecx, - dwarf_edx, - dwarf_ebx, - dwarf_esp, - dwarf_ebp, - dwarf_esi, - dwarf_edi, - dwarf_eip, - dwarf_eflags, - dwarf_stmm0 = 11, - dwarf_stmm1, - dwarf_stmm2, - dwarf_stmm3, - dwarf_stmm4, - dwarf_stmm5, - dwarf_stmm6, - dwarf_stmm7, - dwarf_xmm0 = 21, - dwarf_xmm1, - dwarf_xmm2, - dwarf_xmm3, - dwarf_xmm4, - dwarf_xmm5, - dwarf_xmm6, - dwarf_xmm7 -}; - -enum -{ - gdb_eax = 0, - gdb_ecx = 1, - gdb_edx = 2, - gdb_ebx = 3, - gdb_esp = 4, - gdb_ebp = 5, - gdb_esi = 6, - gdb_edi = 7, - gdb_eip = 8, - gdb_eflags = 9, - gdb_cs = 10, - gdb_ss = 11, - gdb_ds = 12, - gdb_es = 13, - gdb_fs = 14, - gdb_gs = 15, - gdb_stmm0 = 16, - gdb_stmm1 = 17, - gdb_stmm2 = 18, - gdb_stmm3 = 19, - gdb_stmm4 = 20, - gdb_stmm5 = 21, - gdb_stmm6 = 22, - gdb_stmm7 = 23, - gdb_fcw = 24, - gdb_fsw = 25, - gdb_ftw = 26, - gdb_fpu_cs = 27, - gdb_ip = 28, - gdb_fpu_ds = 29, - gdb_dp = 30, - gdb_fop = 31, - gdb_xmm0 = 32, - gdb_xmm1 = 33, - gdb_xmm2 = 34, - gdb_xmm3 = 35, - gdb_xmm4 = 36, - gdb_xmm5 = 37, - gdb_xmm6 = 38, - gdb_xmm7 = 39, - gdb_mxcsr = 40, - gdb_mm0 = 41, - gdb_mm1 = 42, - gdb_mm2 = 43, - gdb_mm3 = 44, - gdb_mm4 = 45, - gdb_mm5 = 46, - gdb_mm6 = 47, - gdb_mm7 = 48 -}; - -static const -uint32_t g_gpr_regnums[k_num_gpr_registers] = -{ - gpr_eax, - gpr_ebx, - gpr_ecx, - gpr_edx, - gpr_edi, - gpr_esi, - gpr_ebp, - gpr_esp, - gpr_ss, - gpr_eflags, -#ifdef __FreeBSD__ - gpr_orig_ax, -#endif - gpr_eip, - gpr_cs, - gpr_ds, - gpr_es, - gpr_fs, - gpr_gs, -}; - -static const uint32_t -g_fpu_regnums[k_num_fpu_registers] = -{ - fpu_fcw, - fpu_fsw, - fpu_ftw, - fpu_fop, - fpu_ip, - fpu_cs, - fpu_foo, - fpu_fos, - fpu_mxcsr, - fpu_stmm0, - fpu_stmm1, - fpu_stmm2, - fpu_stmm3, - fpu_stmm4, - fpu_stmm5, - fpu_stmm6, - fpu_stmm7, - fpu_xmm0, - fpu_xmm1, - fpu_xmm2, - fpu_xmm3, - fpu_xmm4, - fpu_xmm5, - fpu_xmm6, - fpu_xmm7, -}; - -static const RegisterSet -g_reg_sets[k_num_register_sets] = -{ - { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums }, - { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums } -}; - -// Computes the offset of the given GPR in the user data area. -#define GPR_OFFSET(regname) \ - (offsetof(RegisterContext_i386::UserArea, regs) + \ - offsetof(RegisterContext_i386::GPR, regname)) - -// Computes the offset of the given FPR in the user data area. -#define FPR_OFFSET(regname) \ - (offsetof(RegisterContext_i386::UserArea, i387) + \ - offsetof(RegisterContext_i386::FPU, regname)) - -// Number of bytes needed to represent a GPR. -#define GPR_SIZE(reg) sizeof(((RegisterContext_i386::GPR*)NULL)->reg) - -// Number of bytes needed to represent a FPR. -#define FPR_SIZE(reg) sizeof(((RegisterContext_i386::FPU*)NULL)->reg) - -// Number of bytes needed to represent the i'th FP register. -#define FP_SIZE sizeof(((RegisterContext_i386::MMSReg*)NULL)->bytes) - -// Number of bytes needed to represent an XMM register. -#define XMM_SIZE sizeof(RegisterContext_i386::XMMReg) - -#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ - { #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg }, NULL, NULL } - -#define DEFINE_FPR(reg, kind1, kind2, kind3, kind4) \ - { #reg, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, fpu_##reg }, NULL, NULL } - -#define DEFINE_FP(reg, i) \ - { #reg#i, NULL, FP_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \ - eFormatVectorOfUInt8, \ - { dwarf_##reg##i, dwarf_##reg##i, \ - LLDB_INVALID_REGNUM, gdb_##reg##i, fpu_##reg##i }, NULL, NULL } - -#define DEFINE_XMM(reg, i) \ - { #reg#i, NULL, XMM_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \ - eFormatVectorOfUInt8, \ - { dwarf_##reg##i, dwarf_##reg##i, \ - LLDB_INVALID_REGNUM, gdb_##reg##i, fpu_##reg##i }, NULL, NULL } - -static RegisterInfo -g_register_infos[k_num_registers] = -{ - // General purpose registers. - DEFINE_GPR(eax, NULL, gcc_eax, dwarf_eax, LLDB_INVALID_REGNUM, gdb_eax), - DEFINE_GPR(ebx, NULL, gcc_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, gdb_ebx), - DEFINE_GPR(ecx, NULL, gcc_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, gdb_ecx), - DEFINE_GPR(edx, NULL, gcc_edx, dwarf_edx, LLDB_INVALID_REGNUM, gdb_edx), - DEFINE_GPR(edi, NULL, gcc_edi, dwarf_edi, LLDB_INVALID_REGNUM, gdb_edi), - DEFINE_GPR(esi, NULL, gcc_esi, dwarf_esi, LLDB_INVALID_REGNUM, gdb_esi), - DEFINE_GPR(ebp, "fp", gcc_ebp, dwarf_ebp, LLDB_INVALID_REGNUM, gdb_ebp), - DEFINE_GPR(esp, "sp", gcc_esp, dwarf_esp, LLDB_INVALID_REGNUM, gdb_esp), - DEFINE_GPR(ss, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ss), - DEFINE_GPR(eflags, "flags", gcc_eflags, dwarf_eflags, LLDB_INVALID_REGNUM, gdb_eflags), - DEFINE_GPR(eip, "pc", gcc_eip, dwarf_eip, LLDB_INVALID_REGNUM, gdb_eip), - DEFINE_GPR(cs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_cs), - DEFINE_GPR(ds, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ds), - DEFINE_GPR(es, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_es), - DEFINE_GPR(fs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fs), - DEFINE_GPR(gs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gs), - - // Floating point registers. - DEFINE_FPR(fcw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fcw), - DEFINE_FPR(fsw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fsw), - DEFINE_FPR(ftw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ftw), - DEFINE_FPR(fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fop), - DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ip), - DEFINE_FPR(cs, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_cs), - DEFINE_FPR(foo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_dp), - DEFINE_FPR(fos, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ds), - DEFINE_FPR(mxcsr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_mxcsr), - - DEFINE_FP(stmm, 0), - DEFINE_FP(stmm, 1), - DEFINE_FP(stmm, 2), - DEFINE_FP(stmm, 3), - DEFINE_FP(stmm, 4), - DEFINE_FP(stmm, 5), - DEFINE_FP(stmm, 6), - DEFINE_FP(stmm, 7), - - // XMM registers - DEFINE_XMM(xmm, 0), - DEFINE_XMM(xmm, 1), - DEFINE_XMM(xmm, 2), - DEFINE_XMM(xmm, 3), - DEFINE_XMM(xmm, 4), - DEFINE_XMM(xmm, 5), - DEFINE_XMM(xmm, 6), - DEFINE_XMM(xmm, 7), - -}; - -#ifndef NDEBUG -static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo)); -#endif - -static unsigned GetRegOffset(unsigned reg) -{ - assert(reg < k_num_registers && "Invalid register number."); - return g_register_infos[reg].byte_offset; -} - -static unsigned GetRegSize(unsigned reg) -{ - assert(reg < k_num_registers && "Invalid register number."); - return g_register_infos[reg].byte_size; -} - -RegisterContext_i386::RegisterContext_i386(Thread &thread, - uint32_t concrete_frame_idx) - : RegisterContextPOSIX(thread, concrete_frame_idx) -{ -} - -RegisterContext_i386::~RegisterContext_i386() -{ -} - -ProcessMonitor & -RegisterContext_i386::GetMonitor() -{ - ProcessSP base = CalculateProcess(); - ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get()); - return process->GetMonitor(); -} - -void -RegisterContext_i386::Invalidate() -{ -} - -void -RegisterContext_i386::InvalidateAllRegisters() -{ -} - -size_t -RegisterContext_i386::GetRegisterCount() -{ - assert(k_num_register_infos == k_num_registers); - return k_num_registers; -} - -const RegisterInfo * -RegisterContext_i386::GetRegisterInfoAtIndex(uint32_t reg) -{ - assert(k_num_register_infos == k_num_registers); - if (reg < k_num_registers) - return &g_register_infos[reg]; - else - return NULL; -} - -size_t -RegisterContext_i386::GetRegisterSetCount() -{ - return k_num_register_sets; -} - -const RegisterSet * -RegisterContext_i386::GetRegisterSet(uint32_t set) -{ - if (set < k_num_register_sets) - return &g_reg_sets[set]; - else - return NULL; -} - -unsigned -RegisterContext_i386::GetRegisterIndexFromOffset(unsigned offset) -{ - unsigned reg; - for (reg = 0; reg < k_num_registers; reg++) - { - if (g_register_infos[reg].byte_offset == offset) - break; - } - assert(reg < k_num_registers && "Invalid register offset."); - return reg; -} - -const char * -RegisterContext_i386::GetRegisterName(unsigned reg) -{ - assert(reg < k_num_registers && "Invalid register offset."); - return g_register_infos[reg].name; -} - -bool -RegisterContext_i386::ReadRegister(const RegisterInfo *reg_info, - RegisterValue &value) -{ - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadRegisterValue(GetRegOffset(reg), GetRegSize(reg), value); -} - -bool -RegisterContext_i386::ReadAllRegisterValues(DataBufferSP &data_sp) -{ - return false; -} - -bool RegisterContext_i386::WriteRegister(const RegisterInfo *reg_info, - const RegisterValue &value) -{ - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - ProcessMonitor &monitor = GetMonitor(); - return monitor.WriteRegisterValue(GetRegOffset(reg), value); -} - -bool -RegisterContext_i386::WriteAllRegisterValues(const DataBufferSP &data) -{ - return false; -} - -bool -RegisterContext_i386::UpdateAfterBreakpoint() -{ - // PC points one byte past the int3 responsible for the breakpoint. - lldb::addr_t pc; - - if ((pc = GetPC()) == LLDB_INVALID_ADDRESS) - return false; - - SetPC(pc - 1); - return true; -} - -uint32_t -RegisterContext_i386::ConvertRegisterKindToRegisterNumber(uint32_t kind, - uint32_t num) -{ - if (kind == eRegisterKindGeneric) - { - switch (num) - { - case LLDB_REGNUM_GENERIC_PC: return gpr_eip; - case LLDB_REGNUM_GENERIC_SP: return gpr_esp; - case LLDB_REGNUM_GENERIC_FP: return gpr_ebp; - case LLDB_REGNUM_GENERIC_FLAGS: return gpr_eflags; - case LLDB_REGNUM_GENERIC_RA: - default: - return LLDB_INVALID_REGNUM; - } - } - - if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF) - { - switch (num) - { - case dwarf_eax: return gpr_eax; - case dwarf_edx: return gpr_edx; - case dwarf_ecx: return gpr_ecx; - case dwarf_ebx: return gpr_ebx; - case dwarf_esi: return gpr_esi; - case dwarf_edi: return gpr_edi; - case dwarf_ebp: return gpr_ebp; - case dwarf_esp: return gpr_esp; - case dwarf_eip: return gpr_eip; - case dwarf_xmm0: return fpu_xmm0; - case dwarf_xmm1: return fpu_xmm1; - case dwarf_xmm2: return fpu_xmm2; - case dwarf_xmm3: return fpu_xmm3; - case dwarf_xmm4: return fpu_xmm4; - case dwarf_xmm5: return fpu_xmm5; - case dwarf_xmm6: return fpu_xmm6; - case dwarf_xmm7: return fpu_xmm7; - case dwarf_stmm0: return fpu_stmm0; - case dwarf_stmm1: return fpu_stmm1; - case dwarf_stmm2: return fpu_stmm2; - case dwarf_stmm3: return fpu_stmm3; - case dwarf_stmm4: return fpu_stmm4; - case dwarf_stmm5: return fpu_stmm5; - case dwarf_stmm6: return fpu_stmm6; - case dwarf_stmm7: return fpu_stmm7; - default: - return LLDB_INVALID_REGNUM; - } - } - - if (kind == eRegisterKindGDB) - { - switch (num) - { - case gdb_eax : return gpr_eax; - case gdb_ebx : return gpr_ebx; - case gdb_ecx : return gpr_ecx; - case gdb_edx : return gpr_edx; - case gdb_esi : return gpr_esi; - case gdb_edi : return gpr_edi; - case gdb_ebp : return gpr_ebp; - case gdb_esp : return gpr_esp; - case gdb_eip : return gpr_eip; - case gdb_eflags : return gpr_eflags; - case gdb_cs : return gpr_cs; - case gdb_ss : return gpr_ss; - case gdb_ds : return gpr_ds; - case gdb_es : return gpr_es; - case gdb_fs : return gpr_fs; - case gdb_gs : return gpr_gs; - case gdb_stmm0 : return fpu_stmm0; - case gdb_stmm1 : return fpu_stmm1; - case gdb_stmm2 : return fpu_stmm2; - case gdb_stmm3 : return fpu_stmm3; - case gdb_stmm4 : return fpu_stmm4; - case gdb_stmm5 : return fpu_stmm5; - case gdb_stmm6 : return fpu_stmm6; - case gdb_stmm7 : return fpu_stmm7; - case gdb_fcw : return fpu_fcw; - case gdb_fsw : return fpu_fsw; - case gdb_ftw : return fpu_ftw; - case gdb_fpu_cs : return fpu_cs; - case gdb_ip : return fpu_ip; - case gdb_fpu_ds : return fpu_fos; - case gdb_dp : return fpu_foo; - case gdb_fop : return fpu_fop; - case gdb_xmm0 : return fpu_xmm0; - case gdb_xmm1 : return fpu_xmm1; - case gdb_xmm2 : return fpu_xmm2; - case gdb_xmm3 : return fpu_xmm3; - case gdb_xmm4 : return fpu_xmm4; - case gdb_xmm5 : return fpu_xmm5; - case gdb_xmm6 : return fpu_xmm6; - case gdb_xmm7 : return fpu_xmm7; - case gdb_mxcsr : return fpu_mxcsr; - default: - return LLDB_INVALID_REGNUM; - } - } - else if (kind == eRegisterKindLLDB) - { - return num; - } - - return LLDB_INVALID_REGNUM; -} - -bool -RegisterContext_i386::HardwareSingleStep(bool enable) -{ - enum { TRACE_BIT = 0x100 }; - uint64_t eflags; - - if ((eflags = ReadRegisterAsUnsigned(gpr_eflags, -1UL)) == -1UL) - return false; - - if (enable) - { - if (eflags & TRACE_BIT) - return true; - - eflags |= TRACE_BIT; - } - else - { - if (!(eflags & TRACE_BIT)) - return false; - - eflags &= ~TRACE_BIT; - } - - return WriteRegisterFromUnsigned(gpr_eflags, eflags); -} - -void -RegisterContext_i386::LogGPR(const char *title) -{ - LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS)); - if (log) - { - if (title) - log->Printf ("%s", title); - for (uint32_t i=0; i<k_num_gpr_registers; i++) - { - uint32_t reg = gpr_eax + i; - log->Printf("%12s = 0x%8.8x", g_register_infos[reg].name, (&user.regs)[reg]); - } - } -} - -bool -RegisterContext_i386::ReadGPR() -{ - bool result; - - ProcessMonitor &monitor = GetMonitor(); - result = monitor.ReadGPR(&user.regs); - LogGPR("RegisterContext_i386::ReadGPR()"); - return result; -} - -bool -RegisterContext_i386::ReadFPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadFPR(&user.i387); -} diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContext_i386.h b/lldb/source/Plugins/Process/POSIX/RegisterContext_i386.h deleted file mode 100644 index 1586501a8fb1..000000000000 --- a/lldb/source/Plugins/Process/POSIX/RegisterContext_i386.h +++ /dev/null @@ -1,169 +0,0 @@ -//===-- RegisterContext_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_RegisterContext_i386_h_ -#define liblldb_RegisterContext_i386_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Log.h" -#include "RegisterContextPOSIX.h" - -class RegisterContext_i386 : public RegisterContextPOSIX -{ -public: - RegisterContext_i386(lldb_private::Thread &thread, - uint32_t concreate_frame_idx); - - ~RegisterContext_i386(); - - void - Invalidate(); - - void - InvalidateAllRegisters(); - - size_t - GetRegisterCount(); - - const lldb_private::RegisterInfo * - GetRegisterInfoAtIndex(uint32_t reg); - - size_t - GetRegisterSetCount(); - - const lldb_private::RegisterSet * - GetRegisterSet(uint32_t set); - - static unsigned - GetRegisterIndexFromOffset(unsigned offset); - - static const char * - GetRegisterName(unsigned reg); - - bool - ReadRegisterValue(uint32_t reg, lldb_private::Scalar &value); - - bool - ReadRegisterBytes(uint32_t reg, lldb_private::DataExtractor &data); - - virtual bool - ReadRegister(const lldb_private::RegisterInfo *reg_info, - lldb_private::RegisterValue &value); - - bool - ReadAllRegisterValues(lldb::DataBufferSP &data_sp); - - bool - WriteRegisterValue(uint32_t reg, const lldb_private::Scalar &value); - - bool - WriteRegisterBytes(uint32_t reg, lldb_private::DataExtractor &data, - uint32_t data_offset = 0); - - virtual bool - WriteRegister(const lldb_private::RegisterInfo *reg_info, - const lldb_private::RegisterValue &value); - - bool - WriteAllRegisterValues(const lldb::DataBufferSP &data_sp); - - uint32_t - ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num); - - bool - HardwareSingleStep(bool enable); - - bool - UpdateAfterBreakpoint(); - - struct GPR - { - uint32_t ebx; - uint32_t ecx; - uint32_t edx; - uint32_t esi; - uint32_t edi; - uint32_t ebp; - uint32_t eax; - uint32_t ds; - uint32_t es; - uint32_t fs; - uint32_t gs; - uint32_t orig_ax; - uint32_t eip; - uint32_t cs; - uint32_t eflags; - uint32_t esp; - uint32_t ss; - }; - - struct MMSReg - { - uint8_t bytes[8]; - }; - - struct XMMReg - { - uint8_t bytes[16]; - }; - - struct FPU - { - uint16_t fcw; - uint16_t fsw; - uint16_t ftw; - uint16_t fop; - uint32_t ip; - uint32_t cs; - uint32_t foo; - uint32_t fos; - uint32_t mxcsr; - uint32_t reserved; - MMSReg stmm[8]; - XMMReg xmm[8]; - uint32_t pad[56]; - }; - - // A user area like this no longer exists on FreeBSD - // making this a Linux artifact. Nonetheless, it is safe - // leaving it here while the code is being cleaned up and generalized. - - struct UserArea - { - GPR regs; // General purpose registers. - int32_t fpvalid; // True if FPU is being used. - FPU i387; // FPU registers. - uint32_t tsize; // Text segment size. - uint32_t dsize; // Data segment size. - uint32_t ssize; // Stack segment size. - uint32_t start_code; // VM address of text. - uint32_t start_stack; // VM address of stack bottom (top in rsp). - int32_t signal; // Signal causing core dump. - int32_t reserved; // Unused. - uint32_t ar0; // Location of GPR's. - FPU* fpstate; // Location of FPR's. - uint32_t magic; // Identifier for core dumps. - char u_comm[32]; // Command causing core dump. - uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7). - }; -private: - UserArea user; - - ProcessMonitor &GetMonitor(); - - void LogGPR(const char *title); - - bool ReadGPR(); - bool ReadFPR(); -}; - -#endif // #ifndef liblldb_RegisterContext_i386_h_ diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp b/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp deleted file mode 100644 index ddee82f359a9..000000000000 --- a/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp +++ /dev/null @@ -1,758 +0,0 @@ -//===-- RegisterContext_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 <cstring> -#include <errno.h> -#include <stdint.h> - -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Scalar.h" -#include "lldb/Target/Thread.h" -#include "lldb/Host/Endian.h" - -#include "ProcessPOSIX.h" -#include "ProcessMonitor.h" -#include "RegisterContext_x86_64.h" - -using namespace lldb_private; -using namespace lldb; - -// Internal codes for all x86_64 registers. -enum -{ - k_first_gpr, - gpr_rax = k_first_gpr, - gpr_rbx, - gpr_rcx, - gpr_rdx, - gpr_rdi, - gpr_rsi, - gpr_rbp, - gpr_rsp, - gpr_r8, - gpr_r9, - gpr_r10, - gpr_r11, - gpr_r12, - gpr_r13, - gpr_r14, - gpr_r15, - gpr_rip, - gpr_rflags, - gpr_cs, - gpr_fs, - gpr_gs, - gpr_ss, - gpr_ds, - gpr_es, - k_last_gpr = gpr_es, - - k_first_fpr, - fpu_fcw = k_first_fpr, - fpu_fsw, - fpu_ftw, - fpu_fop, - fpu_ip, - fpu_cs, - fpu_dp, - fpu_ds, - fpu_mxcsr, - fpu_mxcsrmask, - fpu_stmm0, - fpu_stmm1, - fpu_stmm2, - fpu_stmm3, - fpu_stmm4, - fpu_stmm5, - fpu_stmm6, - fpu_stmm7, - fpu_xmm0, - fpu_xmm1, - fpu_xmm2, - fpu_xmm3, - fpu_xmm4, - fpu_xmm5, - fpu_xmm6, - fpu_xmm7, - fpu_xmm8, - fpu_xmm9, - fpu_xmm10, - fpu_xmm11, - fpu_xmm12, - fpu_xmm13, - fpu_xmm14, - fpu_xmm15, - k_last_fpr = fpu_xmm15, - - k_num_registers, - k_num_gpr_registers = k_last_gpr - k_first_gpr + 1, - k_num_fpu_registers = k_last_fpr - k_first_fpr + 1 -}; - -// Number of register sets provided by this context. -enum -{ - k_num_register_sets = 2 -}; - -enum gcc_dwarf_regnums -{ - gcc_dwarf_gpr_rax = 0, - gcc_dwarf_gpr_rdx, - gcc_dwarf_gpr_rcx, - gcc_dwarf_gpr_rbx, - gcc_dwarf_gpr_rsi, - gcc_dwarf_gpr_rdi, - gcc_dwarf_gpr_rbp, - gcc_dwarf_gpr_rsp, - gcc_dwarf_gpr_r8, - gcc_dwarf_gpr_r9, - gcc_dwarf_gpr_r10, - gcc_dwarf_gpr_r11, - gcc_dwarf_gpr_r12, - gcc_dwarf_gpr_r13, - gcc_dwarf_gpr_r14, - gcc_dwarf_gpr_r15, - gcc_dwarf_gpr_rip, - gcc_dwarf_fpu_xmm0, - gcc_dwarf_fpu_xmm1, - gcc_dwarf_fpu_xmm2, - gcc_dwarf_fpu_xmm3, - gcc_dwarf_fpu_xmm4, - gcc_dwarf_fpu_xmm5, - gcc_dwarf_fpu_xmm6, - gcc_dwarf_fpu_xmm7, - gcc_dwarf_fpu_xmm8, - gcc_dwarf_fpu_xmm9, - gcc_dwarf_fpu_xmm10, - gcc_dwarf_fpu_xmm11, - gcc_dwarf_fpu_xmm12, - gcc_dwarf_fpu_xmm13, - gcc_dwarf_fpu_xmm14, - gcc_dwarf_fpu_xmm15, - gcc_dwarf_fpu_stmm0, - gcc_dwarf_fpu_stmm1, - gcc_dwarf_fpu_stmm2, - gcc_dwarf_fpu_stmm3, - gcc_dwarf_fpu_stmm4, - gcc_dwarf_fpu_stmm5, - gcc_dwarf_fpu_stmm6, - gcc_dwarf_fpu_stmm7 -}; - -enum gdb_regnums -{ - gdb_gpr_rax = 0, - gdb_gpr_rbx = 1, - gdb_gpr_rcx = 2, - gdb_gpr_rdx = 3, - gdb_gpr_rsi = 4, - gdb_gpr_rdi = 5, - gdb_gpr_rbp = 6, - gdb_gpr_rsp = 7, - gdb_gpr_r8 = 8, - gdb_gpr_r9 = 9, - gdb_gpr_r10 = 10, - gdb_gpr_r11 = 11, - gdb_gpr_r12 = 12, - gdb_gpr_r13 = 13, - gdb_gpr_r14 = 14, - gdb_gpr_r15 = 15, - gdb_gpr_rip = 16, - gdb_gpr_rflags = 17, - gdb_gpr_cs = 18, - gdb_gpr_ss = 19, - gdb_gpr_ds = 20, - gdb_gpr_es = 21, - gdb_gpr_fs = 22, - gdb_gpr_gs = 23, - gdb_fpu_stmm0 = 24, - gdb_fpu_stmm1 = 25, - gdb_fpu_stmm2 = 26, - gdb_fpu_stmm3 = 27, - gdb_fpu_stmm4 = 28, - gdb_fpu_stmm5 = 29, - gdb_fpu_stmm6 = 30, - gdb_fpu_stmm7 = 31, - gdb_fpu_fcw = 32, - gdb_fpu_fsw = 33, - gdb_fpu_ftw = 34, - gdb_fpu_cs = 35, - gdb_fpu_ip = 36, - gdb_fpu_ds = 37, - gdb_fpu_dp = 38, - gdb_fpu_fop = 39, - gdb_fpu_xmm0 = 40, - gdb_fpu_xmm1 = 41, - gdb_fpu_xmm2 = 42, - gdb_fpu_xmm3 = 43, - gdb_fpu_xmm4 = 44, - gdb_fpu_xmm5 = 45, - gdb_fpu_xmm6 = 46, - gdb_fpu_xmm7 = 47, - gdb_fpu_xmm8 = 48, - gdb_fpu_xmm9 = 49, - gdb_fpu_xmm10 = 50, - gdb_fpu_xmm11 = 51, - gdb_fpu_xmm12 = 52, - gdb_fpu_xmm13 = 53, - gdb_fpu_xmm14 = 54, - gdb_fpu_xmm15 = 55, - gdb_fpu_mxcsr = 56 -}; - -static const -uint32_t g_gpr_regnums[k_num_gpr_registers] = -{ - gpr_rax, - gpr_rbx, - gpr_rcx, - gpr_rdx, - gpr_rdi, - gpr_rsi, - gpr_rbp, - gpr_rsp, - gpr_r8, - gpr_r9, - gpr_r10, - gpr_r11, - gpr_r12, - gpr_r13, - gpr_r14, - gpr_r15, - gpr_rip, - gpr_rflags, - gpr_cs, - gpr_fs, - gpr_gs, - gpr_ss, - gpr_ds, - gpr_es -}; - -static const uint32_t -g_fpu_regnums[k_num_fpu_registers] = -{ - fpu_fcw, - fpu_fsw, - fpu_ftw, - fpu_fop, - fpu_ip, - fpu_cs, - fpu_dp, - fpu_ds, - fpu_mxcsr, - fpu_mxcsrmask, - fpu_stmm0, - fpu_stmm1, - fpu_stmm2, - fpu_stmm3, - fpu_stmm4, - fpu_stmm5, - fpu_stmm6, - fpu_stmm7, - fpu_xmm0, - fpu_xmm1, - fpu_xmm2, - fpu_xmm3, - fpu_xmm4, - fpu_xmm5, - fpu_xmm6, - fpu_xmm7, - fpu_xmm8, - fpu_xmm9, - fpu_xmm10, - fpu_xmm11, - fpu_xmm12, - fpu_xmm13, - fpu_xmm14, - fpu_xmm15 -}; - -static const RegisterSet -g_reg_sets[k_num_register_sets] = -{ - { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums }, - { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums } -}; - -// Computes the offset of the given GPR in the user data area. -#define GPR_OFFSET(regname) \ - (offsetof(RegisterContext_x86_64::UserArea, regs) + \ - offsetof(GPR, regname)) - -// Computes the offset of the given FPR in the user data area. -#define FPR_OFFSET(regname) \ - (offsetof(RegisterContext_x86_64::UserArea, i387) + \ - offsetof(RegisterContext_x86_64::FPU, regname)) - -// Number of bytes needed to represent a GPR. -#define GPR_SIZE(reg) sizeof(((GPR*)NULL)->reg) - -// Number of bytes needed to represent a FPR. -#define FPR_SIZE(reg) sizeof(((RegisterContext_x86_64::FPU*)NULL)->reg) - -// Number of bytes needed to represent the i'th FP register. -#define FP_SIZE sizeof(((RegisterContext_x86_64::MMSReg*)NULL)->bytes) - -// Number of bytes needed to represent an XMM register. -#define XMM_SIZE sizeof(RegisterContext_x86_64::XMMReg) - -#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ - { #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg }, NULL, NULL } - -#define DEFINE_FPR(reg, kind1, kind2, kind3, kind4) \ - { #reg, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \ - eFormatHex, { kind1, kind2, kind3, kind4, fpu_##reg }, NULL, NULL } - -#define DEFINE_FP(reg, i) \ - { #reg#i, NULL, FP_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \ - eFormatVectorOfUInt8, \ - { gcc_dwarf_fpu_##reg##i, gcc_dwarf_fpu_##reg##i, \ - LLDB_INVALID_REGNUM, gdb_fpu_##reg##i, fpu_##reg##i }, NULL, NULL } - -#define DEFINE_XMM(reg, i) \ - { #reg#i, NULL, XMM_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \ - eFormatVectorOfUInt8, \ - { gcc_dwarf_fpu_##reg##i, gcc_dwarf_fpu_##reg##i, \ - LLDB_INVALID_REGNUM, gdb_fpu_##reg##i, fpu_##reg##i }, NULL, NULL } - -#define REG_CONTEXT_SIZE (sizeof(GPR) + sizeof(RegisterContext_x86_64::FPU)) - -static RegisterInfo -g_register_infos[k_num_registers] = -{ - // General purpose registers. - DEFINE_GPR(rax, NULL, gcc_dwarf_gpr_rax, gcc_dwarf_gpr_rax, LLDB_INVALID_REGNUM, gdb_gpr_rax), - DEFINE_GPR(rbx, NULL, gcc_dwarf_gpr_rbx, gcc_dwarf_gpr_rbx, LLDB_INVALID_REGNUM, gdb_gpr_rbx), - DEFINE_GPR(rcx, NULL, gcc_dwarf_gpr_rcx, gcc_dwarf_gpr_rcx, LLDB_INVALID_REGNUM, gdb_gpr_rcx), - DEFINE_GPR(rdx, NULL, gcc_dwarf_gpr_rdx, gcc_dwarf_gpr_rdx, LLDB_INVALID_REGNUM, gdb_gpr_rdx), - DEFINE_GPR(rdi, NULL, gcc_dwarf_gpr_rdi, gcc_dwarf_gpr_rdi, LLDB_INVALID_REGNUM, gdb_gpr_rdi), - DEFINE_GPR(rsi, NULL, gcc_dwarf_gpr_rsi, gcc_dwarf_gpr_rsi, LLDB_INVALID_REGNUM, gdb_gpr_rsi), - DEFINE_GPR(rbp, "fp", gcc_dwarf_gpr_rbp, gcc_dwarf_gpr_rbp, LLDB_REGNUM_GENERIC_FP, gdb_gpr_rbp), - DEFINE_GPR(rsp, "sp", gcc_dwarf_gpr_rsp, gcc_dwarf_gpr_rsp, LLDB_REGNUM_GENERIC_SP, gdb_gpr_rsp), - DEFINE_GPR(r8, NULL, gcc_dwarf_gpr_r8, gcc_dwarf_gpr_r8, LLDB_INVALID_REGNUM, gdb_gpr_r8), - DEFINE_GPR(r9, NULL, gcc_dwarf_gpr_r9, gcc_dwarf_gpr_r9, LLDB_INVALID_REGNUM, gdb_gpr_r9), - DEFINE_GPR(r10, NULL, gcc_dwarf_gpr_r10, gcc_dwarf_gpr_r10, LLDB_INVALID_REGNUM, gdb_gpr_r10), - DEFINE_GPR(r11, NULL, gcc_dwarf_gpr_r11, gcc_dwarf_gpr_r11, LLDB_INVALID_REGNUM, gdb_gpr_r11), - DEFINE_GPR(r12, NULL, gcc_dwarf_gpr_r12, gcc_dwarf_gpr_r12, LLDB_INVALID_REGNUM, gdb_gpr_r12), - DEFINE_GPR(r13, NULL, gcc_dwarf_gpr_r13, gcc_dwarf_gpr_r13, LLDB_INVALID_REGNUM, gdb_gpr_r13), - DEFINE_GPR(r14, NULL, gcc_dwarf_gpr_r14, gcc_dwarf_gpr_r14, LLDB_INVALID_REGNUM, gdb_gpr_r14), - DEFINE_GPR(r15, NULL, gcc_dwarf_gpr_r15, gcc_dwarf_gpr_r15, LLDB_INVALID_REGNUM, gdb_gpr_r15), - DEFINE_GPR(rip, "pc", gcc_dwarf_gpr_rip, gcc_dwarf_gpr_rip, LLDB_REGNUM_GENERIC_PC, gdb_gpr_rip), - DEFINE_GPR(rflags, "flags", LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, gdb_gpr_rflags), - DEFINE_GPR(cs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_cs), - DEFINE_GPR(fs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_fs), - DEFINE_GPR(gs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_gs), - DEFINE_GPR(ss, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_ss), - DEFINE_GPR(ds, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_ds), - DEFINE_GPR(es, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_es), - - // i387 Floating point registers. - DEFINE_FPR(fcw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fcw), - DEFINE_FPR(fsw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fsw), - DEFINE_FPR(ftw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ftw), - DEFINE_FPR(fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fop), - DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ip), - // FIXME: Extract segment from ip. - DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_cs), - DEFINE_FPR(dp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_dp), - // FIXME: Extract segment from dp. - DEFINE_FPR(dp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ds), - DEFINE_FPR(mxcsr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_mxcsr), - DEFINE_FPR(mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), - - // FP registers. - DEFINE_FP(stmm, 0), - DEFINE_FP(stmm, 1), - DEFINE_FP(stmm, 2), - DEFINE_FP(stmm, 3), - DEFINE_FP(stmm, 4), - DEFINE_FP(stmm, 5), - DEFINE_FP(stmm, 6), - DEFINE_FP(stmm, 7), - - // XMM registers - DEFINE_XMM(xmm, 0), - DEFINE_XMM(xmm, 1), - DEFINE_XMM(xmm, 2), - DEFINE_XMM(xmm, 3), - DEFINE_XMM(xmm, 4), - DEFINE_XMM(xmm, 5), - DEFINE_XMM(xmm, 6), - DEFINE_XMM(xmm, 7), - DEFINE_XMM(xmm, 8), - DEFINE_XMM(xmm, 9), - DEFINE_XMM(xmm, 10), - DEFINE_XMM(xmm, 11), - DEFINE_XMM(xmm, 12), - DEFINE_XMM(xmm, 13), - DEFINE_XMM(xmm, 14), - DEFINE_XMM(xmm, 15) -}; - -static unsigned GetRegOffset(unsigned reg) -{ - assert(reg < k_num_registers && "Invalid register number."); - return g_register_infos[reg].byte_offset; -} - -static unsigned GetRegSize(unsigned reg) -{ - assert(reg < k_num_registers && "Invalid register number."); - return g_register_infos[reg].byte_size; -} - -static bool IsGPR(unsigned reg) -{ - return reg <= k_last_gpr; // GPR's come first. -} - -static bool IsFPR(unsigned reg) -{ - return (k_first_fpr <= reg && reg <= k_last_fpr); -} - -RegisterContext_x86_64::RegisterContext_x86_64(Thread &thread, - uint32_t concrete_frame_idx) - : RegisterContextPOSIX(thread, concrete_frame_idx) -{ -} - -RegisterContext_x86_64::~RegisterContext_x86_64() -{ -} - -ProcessMonitor & -RegisterContext_x86_64::GetMonitor() -{ - ProcessSP base = CalculateProcess(); - ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get()); - return process->GetMonitor(); -} - -void -RegisterContext_x86_64::Invalidate() -{ -} - -void -RegisterContext_x86_64::InvalidateAllRegisters() -{ -} - -size_t -RegisterContext_x86_64::GetRegisterCount() -{ - return k_num_registers; -} - -const RegisterInfo * -RegisterContext_x86_64::GetRegisterInfoAtIndex(uint32_t reg) -{ - if (reg < k_num_registers) - return &g_register_infos[reg]; - else - return NULL; -} - -size_t -RegisterContext_x86_64::GetRegisterSetCount() -{ - return k_num_register_sets; -} - -const RegisterSet * -RegisterContext_x86_64::GetRegisterSet(uint32_t set) -{ - if (set < k_num_register_sets) - return &g_reg_sets[set]; - else - return NULL; -} - -unsigned -RegisterContext_x86_64::GetRegisterIndexFromOffset(unsigned offset) -{ - unsigned reg; - for (reg = 0; reg < k_num_registers; reg++) - { - if (g_register_infos[reg].byte_offset == offset) - break; - } - assert(reg < k_num_registers && "Invalid register offset."); - return reg; -} - -const char * -RegisterContext_x86_64::GetRegisterName(unsigned reg) -{ - assert(reg < k_num_registers && "Invalid register offset."); - return g_register_infos[reg].name; -} - -bool -RegisterContext_x86_64::ReadRegister(const RegisterInfo *reg_info, - RegisterValue &value) -{ - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadRegisterValue(GetRegOffset(reg), GetRegSize(reg), value); -} - -bool -RegisterContext_x86_64::ReadAllRegisterValues(DataBufferSP &data_sp) -{ - data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0)); - if (data_sp && ReadGPR () && ReadFPR ()) - { - uint8_t *dst = data_sp->GetBytes(); - ::memcpy (dst, &user.regs, sizeof(user.regs)); - dst += sizeof(user.regs); - - ::memcpy (dst, &user.i387, sizeof(user.i387)); - return true; - } - return false; -} - -bool -RegisterContext_x86_64::WriteRegister(const lldb_private::RegisterInfo *reg_info, - const lldb_private::RegisterValue &value) -{ - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - ProcessMonitor &monitor = GetMonitor(); - return monitor.WriteRegisterValue(GetRegOffset(reg), value); -} - -bool -RegisterContext_x86_64::WriteAllRegisterValues(const DataBufferSP &data_sp) -{ - if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) - { - const uint8_t *src = data_sp->GetBytes(); - ::memcpy (&user.regs, src, sizeof(user.regs)); - src += sizeof(user.regs); - - ::memcpy (&user.i387, src, sizeof(user.i387)); - return WriteGPR() & WriteFPR(); - } - return false; -} - -bool -RegisterContext_x86_64::UpdateAfterBreakpoint() -{ - // PC points one byte past the int3 responsible for the breakpoint. - lldb::addr_t pc; - - if ((pc = GetPC()) == LLDB_INVALID_ADDRESS) - return false; - - SetPC(pc - 1); - return true; -} - -uint32_t -RegisterContext_x86_64::ConvertRegisterKindToRegisterNumber(uint32_t kind, - uint32_t num) -{ - if (kind == eRegisterKindGeneric) - { - switch (num) - { - case LLDB_REGNUM_GENERIC_PC: return gpr_rip; - case LLDB_REGNUM_GENERIC_SP: return gpr_rsp; - case LLDB_REGNUM_GENERIC_FP: return gpr_rbp; - case LLDB_REGNUM_GENERIC_FLAGS: return gpr_rflags; - case LLDB_REGNUM_GENERIC_RA: - default: - return LLDB_INVALID_REGNUM; - } - } - - if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF) - { - switch (num) - { - case gcc_dwarf_gpr_rax: return gpr_rax; - case gcc_dwarf_gpr_rdx: return gpr_rdx; - case gcc_dwarf_gpr_rcx: return gpr_rcx; - case gcc_dwarf_gpr_rbx: return gpr_rbx; - case gcc_dwarf_gpr_rsi: return gpr_rsi; - case gcc_dwarf_gpr_rdi: return gpr_rdi; - case gcc_dwarf_gpr_rbp: return gpr_rbp; - case gcc_dwarf_gpr_rsp: return gpr_rsp; - case gcc_dwarf_gpr_r8: return gpr_r8; - case gcc_dwarf_gpr_r9: return gpr_r9; - case gcc_dwarf_gpr_r10: return gpr_r10; - case gcc_dwarf_gpr_r11: return gpr_r11; - case gcc_dwarf_gpr_r12: return gpr_r12; - case gcc_dwarf_gpr_r13: return gpr_r13; - case gcc_dwarf_gpr_r14: return gpr_r14; - case gcc_dwarf_gpr_r15: return gpr_r15; - case gcc_dwarf_gpr_rip: return gpr_rip; - case gcc_dwarf_fpu_xmm0: return fpu_xmm0; - case gcc_dwarf_fpu_xmm1: return fpu_xmm1; - case gcc_dwarf_fpu_xmm2: return fpu_xmm2; - case gcc_dwarf_fpu_xmm3: return fpu_xmm3; - case gcc_dwarf_fpu_xmm4: return fpu_xmm4; - case gcc_dwarf_fpu_xmm5: return fpu_xmm5; - case gcc_dwarf_fpu_xmm6: return fpu_xmm6; - case gcc_dwarf_fpu_xmm7: return fpu_xmm7; - case gcc_dwarf_fpu_xmm8: return fpu_xmm8; - case gcc_dwarf_fpu_xmm9: return fpu_xmm9; - case gcc_dwarf_fpu_xmm10: return fpu_xmm10; - case gcc_dwarf_fpu_xmm11: return fpu_xmm11; - case gcc_dwarf_fpu_xmm12: return fpu_xmm12; - case gcc_dwarf_fpu_xmm13: return fpu_xmm13; - case gcc_dwarf_fpu_xmm14: return fpu_xmm14; - case gcc_dwarf_fpu_xmm15: return fpu_xmm15; - case gcc_dwarf_fpu_stmm0: return fpu_stmm0; - case gcc_dwarf_fpu_stmm1: return fpu_stmm1; - case gcc_dwarf_fpu_stmm2: return fpu_stmm2; - case gcc_dwarf_fpu_stmm3: return fpu_stmm3; - case gcc_dwarf_fpu_stmm4: return fpu_stmm4; - case gcc_dwarf_fpu_stmm5: return fpu_stmm5; - case gcc_dwarf_fpu_stmm6: return fpu_stmm6; - case gcc_dwarf_fpu_stmm7: return fpu_stmm7; - default: - return LLDB_INVALID_REGNUM; - } - } - - if (kind == eRegisterKindGDB) - { - switch (num) - { - case gdb_gpr_rax : return gpr_rax; - case gdb_gpr_rbx : return gpr_rbx; - case gdb_gpr_rcx : return gpr_rcx; - case gdb_gpr_rdx : return gpr_rdx; - case gdb_gpr_rsi : return gpr_rsi; - case gdb_gpr_rdi : return gpr_rdi; - case gdb_gpr_rbp : return gpr_rbp; - case gdb_gpr_rsp : return gpr_rsp; - case gdb_gpr_r8 : return gpr_r8; - case gdb_gpr_r9 : return gpr_r9; - case gdb_gpr_r10 : return gpr_r10; - case gdb_gpr_r11 : return gpr_r11; - case gdb_gpr_r12 : return gpr_r12; - case gdb_gpr_r13 : return gpr_r13; - case gdb_gpr_r14 : return gpr_r14; - case gdb_gpr_r15 : return gpr_r15; - case gdb_gpr_rip : return gpr_rip; - case gdb_gpr_rflags : return gpr_rflags; - case gdb_gpr_cs : return gpr_cs; - case gdb_gpr_ss : return gpr_ss; - case gdb_gpr_ds : return gpr_ds; - case gdb_gpr_es : return gpr_es; - case gdb_gpr_fs : return gpr_fs; - case gdb_gpr_gs : return gpr_gs; - case gdb_fpu_stmm0 : return fpu_stmm0; - case gdb_fpu_stmm1 : return fpu_stmm1; - case gdb_fpu_stmm2 : return fpu_stmm2; - case gdb_fpu_stmm3 : return fpu_stmm3; - case gdb_fpu_stmm4 : return fpu_stmm4; - case gdb_fpu_stmm5 : return fpu_stmm5; - case gdb_fpu_stmm6 : return fpu_stmm6; - case gdb_fpu_stmm7 : return fpu_stmm7; - case gdb_fpu_fcw : return fpu_fcw; - case gdb_fpu_fsw : return fpu_fsw; - case gdb_fpu_ftw : return fpu_ftw; - case gdb_fpu_cs : return fpu_cs; - case gdb_fpu_ip : return fpu_ip; - case gdb_fpu_ds : return fpu_ds; - case gdb_fpu_dp : return fpu_dp; - case gdb_fpu_fop : return fpu_fop; - case gdb_fpu_xmm0 : return fpu_xmm0; - case gdb_fpu_xmm1 : return fpu_xmm1; - case gdb_fpu_xmm2 : return fpu_xmm2; - case gdb_fpu_xmm3 : return fpu_xmm3; - case gdb_fpu_xmm4 : return fpu_xmm4; - case gdb_fpu_xmm5 : return fpu_xmm5; - case gdb_fpu_xmm6 : return fpu_xmm6; - case gdb_fpu_xmm7 : return fpu_xmm7; - case gdb_fpu_xmm8 : return fpu_xmm8; - case gdb_fpu_xmm9 : return fpu_xmm9; - case gdb_fpu_xmm10 : return fpu_xmm10; - case gdb_fpu_xmm11 : return fpu_xmm11; - case gdb_fpu_xmm12 : return fpu_xmm12; - case gdb_fpu_xmm13 : return fpu_xmm13; - case gdb_fpu_xmm14 : return fpu_xmm14; - case gdb_fpu_xmm15 : return fpu_xmm15; - case gdb_fpu_mxcsr : return fpu_mxcsr; - default: - return LLDB_INVALID_REGNUM; - } - } - else if (kind == eRegisterKindLLDB) - { - return num; - } - - return LLDB_INVALID_REGNUM; -} - -bool -RegisterContext_x86_64::HardwareSingleStep(bool enable) -{ - enum { TRACE_BIT = 0x100 }; - uint64_t rflags; - - if ((rflags = ReadRegisterAsUnsigned(gpr_rflags, -1UL)) == -1UL) - return false; - - if (enable) - { - if (rflags & TRACE_BIT) - return true; - - rflags |= TRACE_BIT; - } - else - { - if (!(rflags & TRACE_BIT)) - return false; - - rflags &= ~TRACE_BIT; - } - - return WriteRegisterFromUnsigned(gpr_rflags, rflags); -} - -bool -RegisterContext_x86_64::ReadGPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadGPR(&user.regs); -} - -bool -RegisterContext_x86_64::ReadFPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadFPR(&user.i387); -} - -bool -RegisterContext_x86_64::WriteGPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.WriteGPR(&user.regs); -} - -bool -RegisterContext_x86_64::WriteFPR() -{ - ProcessMonitor &monitor = GetMonitor(); - return monitor.WriteFPR(&user.i387); -} diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.h b/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.h deleted file mode 100644 index 56a1843f0624..000000000000 --- a/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.h +++ /dev/null @@ -1,143 +0,0 @@ -//===-- RegisterContext_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_RegisterContext_x86_64_H_ -#define liblldb_RegisterContext_x86_64_H_ - -#include "lldb/Core/Log.h" -#include "RegisterContextPOSIX.h" - -#ifdef __FreeBSD__ -#include "RegisterContextFreeBSD_x86_64.h" -#endif - -#ifdef __linux__ -#include "RegisterContextLinux_x86_64.h" -#endif - -class ProcessMonitor; - -class RegisterContext_x86_64 - : public RegisterContextPOSIX -{ -public: - RegisterContext_x86_64 (lldb_private::Thread &thread, - uint32_t concrete_frame_idx); - - ~RegisterContext_x86_64(); - - void - Invalidate(); - - void - InvalidateAllRegisters(); - - size_t - GetRegisterCount(); - - const lldb_private::RegisterInfo * - GetRegisterInfoAtIndex(uint32_t reg); - - size_t - GetRegisterSetCount(); - - const lldb_private::RegisterSet * - GetRegisterSet(uint32_t set); - - static unsigned - GetRegisterIndexFromOffset(unsigned offset); - - static const char * - GetRegisterName(unsigned reg); - - virtual bool - ReadRegister(const lldb_private::RegisterInfo *reg_info, - lldb_private::RegisterValue &value); - - bool - ReadAllRegisterValues(lldb::DataBufferSP &data_sp); - - virtual bool - WriteRegister(const lldb_private::RegisterInfo *reg_info, - const lldb_private::RegisterValue &value); - - bool - WriteAllRegisterValues(const lldb::DataBufferSP &data_sp); - - uint32_t - ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num); - - bool - HardwareSingleStep(bool enable); - - bool - UpdateAfterBreakpoint(); - - struct MMSReg - { - uint8_t bytes[10]; - uint8_t pad[6]; - }; - - struct XMMReg - { - uint8_t bytes[16]; - }; - - struct FPU - { - uint16_t fcw; - uint16_t fsw; - uint16_t ftw; - uint16_t fop; - uint64_t ip; - uint64_t dp; - uint32_t mxcsr; - uint32_t mxcsrmask; - MMSReg stmm[8]; - XMMReg xmm[16]; - uint32_t padding[24]; - }; - - struct UserArea - { - GPR regs; // General purpose registers. - int32_t fpvalid; // True if FPU is being used. - int32_t pad0; - FPU i387; // FPU registers. - uint64_t tsize; // Text segment size. - uint64_t dsize; // Data segment size. - uint64_t ssize; // Stack segment size. - uint64_t start_code; // VM address of text. - uint64_t start_stack; // VM address of stack bottom (top in rsp). - int64_t signal; // Signal causing core dump. - int32_t reserved; // Unused. - int32_t pad1; - uint64_t ar0; // Location of GPR's. - FPU* fpstate; // Location of FPR's. - uint64_t magic; // Identifier for core dumps. - char u_comm[32]; // Command causing core dump. - uint64_t u_debugreg[8]; // Debug registers (DR0 - DR7). - uint64_t error_code; // CPU error code. - uint64_t fault_address; // Control register CR3. - }; - -private: - UserArea user; - - ProcessMonitor &GetMonitor(); - - bool ReadGPR(); - bool ReadFPR(); - - bool WriteGPR(); - bool WriteFPR(); -}; - -#endif // #ifndef liblldb_RegisterContext_x86_64_H_ diff --git a/lldb/source/Plugins/Process/Utility/ARMDefines.h b/lldb/source/Plugins/Process/Utility/ARMDefines.h deleted file mode 100644 index 4b1f06a2f9cd..000000000000 --- a/lldb/source/Plugins/Process/Utility/ARMDefines.h +++ /dev/null @@ -1,110 +0,0 @@ -//===-- lldb_ARMDefines.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_ARMDefines_h_ -#define lldb_ARMDefines_h_ - -// Common defintions for the ARM/Thumb Instruction Set Architecture. - -namespace lldb_private { - -// ARM shifter types -typedef enum -{ - SRType_LSL, - SRType_LSR, - SRType_ASR, - SRType_ROR, - SRType_RRX, - SRType_Invalid -} ARM_ShifterType; - -// ARM conditions // Meaning (integer) Meaning (floating-point) Condition flags -#define COND_EQ 0x0 // Equal Equal Z == 1 -#define COND_NE 0x1 // Not equal Not equal, or unordered Z == 0 -#define COND_CS 0x2 // Carry set >, ==, or unordered C == 1 -#define COND_HS 0x2 -#define COND_CC 0x3 // Carry clear Less than C == 0 -#define COND_LO 0x3 -#define COND_MI 0x4 // Minus, negative Less than N == 1 -#define COND_PL 0x5 // Plus, positive or zero >, ==, or unordered N == 0 -#define COND_VS 0x6 // Overflow Unordered V == 1 -#define COND_VC 0x7 // No overflow Not unordered V == 0 -#define COND_HI 0x8 // Unsigned higher Greater than, or unordered C == 1 and Z == 0 -#define COND_LS 0x9 // Unsigned lower or same Less than or equal C == 0 or Z == 1 -#define COND_GE 0xA // Greater than or equal Greater than or equal N == V -#define COND_LT 0xB // Less than Less than, or unordered N != V -#define COND_GT 0xC // Greater than Greater than Z == 0 and N == V -#define COND_LE 0xD // Less than or equal <, ==, or unordered Z == 1 or N != V -#define COND_AL 0xE // Always (unconditional) Always (unconditional) Any -#define COND_UNCOND 0xF - -static inline const char *ARMCondCodeToString(uint32_t CC) -{ - switch (CC) { - default: assert(0 && "Unknown condition code"); - case COND_EQ: return "eq"; - case COND_NE: return "ne"; - case COND_HS: return "hs"; - case COND_LO: return "lo"; - case COND_MI: return "mi"; - case COND_PL: return "pl"; - case COND_VS: return "vs"; - case COND_VC: return "vc"; - case COND_HI: return "hi"; - case COND_LS: return "ls"; - case COND_GE: return "ge"; - case COND_LT: return "lt"; - case COND_GT: return "gt"; - case COND_LE: return "le"; - case COND_AL: return "al"; - } -} - -// Bit positions for CPSR -#define CPSR_T_POS 5 -#define CPSR_F_POS 6 -#define CPSR_I_POS 7 -#define CPSR_A_POS 8 -#define CPSR_E_POS 9 -#define CPSR_J_POS 24 -#define CPSR_Q_POS 27 -#define CPSR_V_POS 28 -#define CPSR_C_POS 29 -#define CPSR_Z_POS 30 -#define CPSR_N_POS 31 - -// CPSR mode definitions -#define CPSR_MODE_USR 0x10u -#define CPSR_MODE_FIQ 0x11u -#define CPSR_MODE_IRQ 0x12u -#define CPSR_MODE_SVC 0x13u -#define CPSR_MODE_ABT 0x17u -#define CPSR_MODE_UND 0x1bu -#define CPSR_MODE_SYS 0x1fu - -// Masks for CPSR -#define MASK_CPSR_MODE_MASK (0x0000001fu) -#define MASK_CPSR_IT_MASK (0x0600fc00u) -#define MASK_CPSR_T (1u << CPSR_T_POS) -#define MASK_CPSR_F (1u << CPSR_F_POS) -#define MASK_CPSR_I (1u << CPSR_I_POS) -#define MASK_CPSR_A (1u << CPSR_A_POS) -#define MASK_CPSR_E (1u << CPSR_E_POS) -#define MASK_CPSR_GE_MASK (0x000f0000u) -#define MASK_CPSR_J (1u << CPSR_J_POS) -#define MASK_CPSR_Q (1u << CPSR_Q_POS) -#define MASK_CPSR_V (1u << CPSR_V_POS) -#define MASK_CPSR_C (1u << CPSR_C_POS) -#define MASK_CPSR_Z (1u << CPSR_Z_POS) -#define MASK_CPSR_N (1u << CPSR_N_POS) - -} // namespace lldb_private - -#endif // lldb_ARMDefines_h_ diff --git a/lldb/source/Plugins/Process/Utility/ARMUtils.h b/lldb/source/Plugins/Process/Utility/ARMUtils.h deleted file mode 100644 index fce066d91ffc..000000000000 --- a/lldb/source/Plugins/Process/Utility/ARMUtils.h +++ /dev/null @@ -1,390 +0,0 @@ -//===-- ARMUtils.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_ARMUtils_h_ -#define lldb_ARMUtils_h_ - -#include "ARMDefines.h" -#include "InstructionUtils.h" -#include "llvm/Support/MathExtras.h" // for SignExtend64 template function - -// Common utilities for the ARM/Thumb Instruction Set Architecture. - -namespace lldb_private { - -static inline uint32_t Align(uint32_t val, uint32_t alignment) -{ - return alignment * (val / alignment); -} - -static inline uint32_t DecodeImmShift(const uint32_t type, const uint32_t imm5, ARM_ShifterType &shift_t) -{ - switch (type) { - default: - //assert(0 && "Invalid shift type"); - return UINT32_MAX; - case 0: - shift_t = SRType_LSL; - return imm5; - case 1: - shift_t = SRType_LSR; - return (imm5 == 0 ? 32 : imm5); - case 2: - shift_t = SRType_ASR; - return (imm5 == 0 ? 32 : imm5); - case 3: - if (imm5 == 0) - { - shift_t = SRType_RRX; - return 1; - } - else - { - shift_t = SRType_ROR; - return imm5; - } - } -} - -// A8.6.35 CMP (register) -- Encoding T3 -// Convenience function. -static inline uint32_t DecodeImmShiftThumb(const uint32_t opcode, ARM_ShifterType &shift_t) -{ - return DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t); -} - -// A8.6.35 CMP (register) -- Encoding A1 -// Convenience function. -static inline uint32_t DecodeImmShiftARM(const uint32_t opcode, ARM_ShifterType &shift_t) -{ - return DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t); -} - -static inline uint32_t DecodeImmShift(const ARM_ShifterType shift_t, const uint32_t imm5) -{ - ARM_ShifterType dont_care; - return DecodeImmShift(shift_t, imm5, dont_care); -} - -static inline ARM_ShifterType DecodeRegShift(const uint32_t type) -{ - switch (type) { - default: - //assert(0 && "Invalid shift type"); - return SRType_Invalid; - case 0: - return SRType_LSL; - case 1: - return SRType_LSR; - case 2: - return SRType_ASR; - case 3: - return SRType_ROR; - } -} - -static inline uint32_t LSL_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success) -{ - if (amount == 0) { - *success = false; - return 0; - } - *success = true; - carry_out = amount <= 32 ? Bit32(value, 32 - amount) : 0; - return value << amount; -} - -static inline uint32_t LSL(const uint32_t value, const uint32_t amount, bool *success) -{ - *success = true; - if (amount == 0) - return value; - uint32_t dont_care; - uint32_t result = LSL_C(value, amount, dont_care, success); - if (*success) - return result; - else - return 0; -} - -static inline uint32_t LSR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success) -{ - if (amount == 0) { - *success = false; - return 0; - } - *success = true; - carry_out = amount <= 32 ? Bit32(value, amount - 1) : 0; - return value >> amount; -} - -static inline uint32_t LSR(const uint32_t value, const uint32_t amount, bool *success) -{ - *success = true; - if (amount == 0) - return value; - uint32_t dont_care; - uint32_t result = LSR_C(value, amount, dont_care, success); - if (*success) - return result; - else - return 0; -} - -static inline uint32_t ASR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success) -{ - if (amount == 0 || amount > 32) { - *success = false; - return 0; - } - *success = true; - bool negative = BitIsSet(value, 31); - if (amount <= 32) - { - carry_out = Bit32(value, amount - 1); - int64_t extended = llvm::SignExtend64<32>(value); - return UnsignedBits(extended, amount + 31, amount); - } - else - { - carry_out = (negative ? 1 : 0); - return (negative ? 0xffffffff : 0); - } -} - -static inline uint32_t ASR(const uint32_t value, const uint32_t amount, bool *success) -{ - *success = true; - if (amount == 0) - return value; - uint32_t dont_care; - uint32_t result = ASR_C(value, amount, dont_care, success); - if (*success) - return result; - else - return 0; -} - -static inline uint32_t ROR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success) -{ - if (amount == 0) { - *success = false; - return 0; - } - *success = true; - uint32_t amt = amount % 32; - uint32_t result = Rotr32(value, amt); - carry_out = Bit32(value, 31); - return result; -} - -static inline uint32_t ROR(const uint32_t value, const uint32_t amount, bool *success) -{ - *success = true; - if (amount == 0) - return value; - uint32_t dont_care; - uint32_t result = ROR_C(value, amount, dont_care, success); - if (*success) - return result; - else - return 0; -} - -static inline uint32_t RRX_C(const uint32_t value, const uint32_t carry_in, uint32_t &carry_out, bool *success) -{ - *success = true; - carry_out = Bit32(value, 0); - return Bit32(carry_in, 0) << 31 | Bits32(value, 31, 1); -} - -static inline uint32_t RRX(const uint32_t value, const uint32_t carry_in, bool *success) -{ - *success = true; - uint32_t dont_care; - uint32_t result = RRX_C(value, carry_in, dont_care, success); - if (*success) - return result; - else - return 0; -} - -static inline uint32_t Shift_C(const uint32_t value, ARM_ShifterType type, const uint32_t amount, - const uint32_t carry_in, uint32_t &carry_out, bool *success) -{ - if (type == SRType_RRX && amount != 1) { - *success = false; - return 0; - } - *success = true; - - if (amount == 0) { - carry_out = carry_in; - return value; - } - uint32_t result; - switch (type) { - case SRType_LSL: - result = LSL_C(value, amount, carry_out, success); - break; - case SRType_LSR: - result = LSR_C(value, amount, carry_out, success); - break; - case SRType_ASR: - result = ASR_C(value, amount, carry_out, success); - break; - case SRType_ROR: - result = ROR_C(value, amount, carry_out, success); - break; - case SRType_RRX: - result = RRX_C(value, carry_in, carry_out, success); - break; - default: - *success = false; - break; - } - if (*success) - return result; - else - return 0; -} - -static inline uint32_t Shift(const uint32_t value, ARM_ShifterType type, const uint32_t amount, - const uint32_t carry_in, bool *success) -{ - // Don't care about carry out in this case. - uint32_t dont_care; - uint32_t result = Shift_C(value, type, amount, carry_in, dont_care, success); - if (*success) - return result; - else - return 0; -} - -static inline uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit) -{ - return Bits32(val, msbit, lsbit); -} - -static inline uint32_t bit(const uint32_t val, const uint32_t msbit) -{ - return bits(val, msbit, msbit); -} - -static uint32_t ror(uint32_t val, uint32_t N, uint32_t shift) -{ - uint32_t m = shift % N; - return (val >> m) | (val << (N - m)); -} - -// (imm32, carry_out) = ARMExpandImm_C(imm12, carry_in) -static inline uint32_t ARMExpandImm_C(uint32_t opcode, uint32_t carry_in, uint32_t &carry_out) -{ - uint32_t imm32; // the expanded result - uint32_t imm = bits(opcode, 7, 0); // immediate value - uint32_t amt = 2 * bits(opcode, 11, 8); // rotate amount - if (amt == 0) - { - imm32 = imm; - carry_out = carry_in; - } - else - { - imm32 = ror(imm, 32, amt); - carry_out = Bit32(imm32, 31); - } - return imm32; -} - -static inline uint32_t ARMExpandImm(uint32_t opcode) -{ - // 'carry_in' argument to following function call does not affect the imm32 result. - uint32_t carry_in = 0; - uint32_t carry_out; - return ARMExpandImm_C(opcode, carry_in, carry_out); -} - -// (imm32, carry_out) = ThumbExpandImm_C(imm12, carry_in) -static inline uint32_t ThumbExpandImm_C(uint32_t opcode, uint32_t carry_in, uint32_t &carry_out) -{ - uint32_t imm32; // the expaned result - const uint32_t i = bit(opcode, 26); - const uint32_t imm3 = bits(opcode, 14, 12); - const uint32_t abcdefgh = bits(opcode, 7, 0); - const uint32_t imm12 = i << 11 | imm3 << 8 | abcdefgh; - - if (bits(imm12, 11, 10) == 0) - { - switch (bits(imm12, 9, 8)) { - case 0: - imm32 = abcdefgh; - break; - - case 1: - imm32 = abcdefgh << 16 | abcdefgh; - break; - - case 2: - imm32 = abcdefgh << 24 | abcdefgh << 8; - break; - - case 3: - imm32 = abcdefgh << 24 | abcdefgh << 16 | abcdefgh << 8 | abcdefgh; - break; - } - carry_out = carry_in; - } - else - { - const uint32_t unrotated_value = 0x80 | bits(imm12, 6, 0); - imm32 = ror(unrotated_value, 32, bits(imm12, 11, 7)); - carry_out = Bit32(imm32, 31); - } - return imm32; -} - -static inline uint32_t ThumbExpandImm(uint32_t opcode) -{ - // 'carry_in' argument to following function call does not affect the imm32 result. - uint32_t carry_in = 0; - uint32_t carry_out; - return ThumbExpandImm_C(opcode, carry_in, carry_out); -} - -// imm32 = ZeroExtend(i:imm3:imm8, 32) -static inline uint32_t ThumbImm12(uint32_t opcode) -{ - const uint32_t i = bit(opcode, 26); - const uint32_t imm3 = bits(opcode, 14, 12); - const uint32_t imm8 = bits(opcode, 7, 0); - const uint32_t imm12 = i << 11 | imm3 << 8 | imm8; - return imm12; -} - -// imm32 = ZeroExtend(imm7:'00', 32) -static inline uint32_t ThumbImm7Scaled(uint32_t opcode) -{ - const uint32_t imm7 = bits(opcode, 6, 0); - return imm7 * 4; -} - -// imm32 = ZeroExtend(imm8:'00', 32) -static inline uint32_t ThumbImm8Scaled(uint32_t opcode) -{ - const uint32_t imm8 = bits(opcode, 7, 0); - return imm8 * 4; -} - -// This function performs the check for the register numbers 13 and 15 that are -// not permitted for many Thumb register specifiers. -static inline bool BadReg(uint32_t n) { return n == 13 || n == 15; } - -} // namespace lldb_private - -#endif // lldb_ARMUtils_h_ diff --git a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp deleted file mode 100644 index 293ebac0248b..000000000000 --- a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ /dev/null @@ -1,142 +0,0 @@ -//===-- DynamicRegisterInfo.cpp ----------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "DynamicRegisterInfo.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes - -using namespace lldb; -using namespace lldb_private; - -DynamicRegisterInfo::DynamicRegisterInfo () : - m_regs (), - m_sets (), - m_set_reg_nums (), - m_reg_names (), - m_reg_alt_names (), - m_set_names (), - m_reg_data_byte_size (0) -{ -} - -DynamicRegisterInfo::~DynamicRegisterInfo () -{ -} - -void -DynamicRegisterInfo::AddRegister (RegisterInfo ®_info, - ConstString ®_name, - ConstString ®_alt_name, - ConstString &set_name) -{ - const uint32_t reg_num = m_regs.size(); - m_reg_names.push_back (reg_name); - m_reg_alt_names.push_back (reg_alt_name); - reg_info.name = reg_name.AsCString(); - assert (reg_info.name); - reg_info.alt_name = reg_alt_name.AsCString(NULL); - m_regs.push_back (reg_info); - uint32_t set = GetRegisterSetIndexByName (set_name, true); - assert (set < m_sets.size()); - assert (set < m_set_reg_nums.size()); - assert (set < m_set_names.size()); - m_set_reg_nums[set].push_back(reg_num); - size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size; - if (m_reg_data_byte_size < end_reg_offset) - m_reg_data_byte_size = end_reg_offset; -} - -void -DynamicRegisterInfo::Finalize () -{ - for (uint32_t set = 0; set < m_sets.size(); ++set) - { - assert (m_sets.size() == m_set_reg_nums.size()); - m_sets[set].num_registers = m_set_reg_nums[set].size(); - m_sets[set].registers = &m_set_reg_nums[set][0]; - } -} - -size_t -DynamicRegisterInfo::GetNumRegisters() const -{ - return m_regs.size(); -} - -size_t -DynamicRegisterInfo::GetNumRegisterSets() const -{ - return m_sets.size(); -} - -size_t -DynamicRegisterInfo::GetRegisterDataByteSize() const -{ - return m_reg_data_byte_size; -} - -const RegisterInfo * -DynamicRegisterInfo::GetRegisterInfoAtIndex (uint32_t i) const -{ - if (i < m_regs.size()) - return &m_regs[i]; - return NULL; -} - -const RegisterSet * -DynamicRegisterInfo::GetRegisterSet (uint32_t i) const -{ - if (i < m_sets.size()) - return &m_sets[i]; - return NULL; -} - -uint32_t -DynamicRegisterInfo::GetRegisterSetIndexByName (ConstString &set_name, bool can_create) -{ - name_collection::iterator pos, end = m_set_names.end(); - for (pos = m_set_names.begin(); pos != end; ++pos) - { - if (*pos == set_name) - return std::distance (m_set_names.begin(), pos); - } - - m_set_names.push_back(set_name); - m_set_reg_nums.resize(m_set_reg_nums.size()+1); - RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL }; - m_sets.push_back (new_set); - return m_sets.size() - 1; -} - -uint32_t -DynamicRegisterInfo::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const -{ - reg_collection::const_iterator pos, end = m_regs.end(); - for (pos = m_regs.begin(); pos != end; ++pos) - { - if (pos->kinds[kind] == num) - return std::distance (m_regs.begin(), pos); - } - - return LLDB_INVALID_REGNUM; -} - -void -DynamicRegisterInfo::Clear() -{ - m_regs.clear(); - m_sets.clear(); - m_set_reg_nums.clear(); - m_reg_names.clear(); - m_reg_alt_names.clear(); - m_set_names.clear(); -} diff --git a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h deleted file mode 100644 index 46841a085945..000000000000 --- a/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ /dev/null @@ -1,82 +0,0 @@ -//===-- DynamicRegisterInfo.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_DynamicRegisterInfo_h_ -#define lldb_DynamicRegisterInfo_h_ - -// C Includes -// C++ Includes -#include <vector> - -// Other libraries and framework includes -// Project includes -#include "lldb/lldb-private.h" -#include "lldb/Core/ConstString.h" - -class DynamicRegisterInfo -{ -public: - DynamicRegisterInfo (); - - virtual - ~DynamicRegisterInfo (); - - void - AddRegister (lldb_private::RegisterInfo ®_info, - lldb_private::ConstString ®_name, - lldb_private::ConstString ®_alt_name, - lldb_private::ConstString &set_name); - - void - Finalize (); - - size_t - GetNumRegisters() const; - - size_t - GetNumRegisterSets() const; - - size_t - GetRegisterDataByteSize() const; - - const lldb_private::RegisterInfo * - GetRegisterInfoAtIndex (uint32_t i) const; - - const lldb_private::RegisterSet * - GetRegisterSet (uint32_t i) const; - - uint32_t - GetRegisterSetIndexByName (lldb_private::ConstString &set_name, bool can_create); - - uint32_t - ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const; - - void - Clear(); - -protected: - //------------------------------------------------------------------ - // Classes that inherit from DynamicRegisterInfo can see and modify these - //------------------------------------------------------------------ - typedef std::vector <lldb_private::RegisterInfo> reg_collection; - typedef std::vector <lldb_private::RegisterSet> set_collection; - typedef std::vector <uint32_t> reg_num_collection; - typedef std::vector <reg_num_collection> set_reg_num_collection; - typedef std::vector <lldb_private::ConstString> name_collection; - - reg_collection m_regs; - set_collection m_sets; - set_reg_num_collection m_set_reg_nums; - name_collection m_reg_names; - name_collection m_reg_alt_names; - name_collection m_set_names; - size_t m_reg_data_byte_size; // The number of bytes required to store all registers -}; - -#endif // lldb_DynamicRegisterInfo_h_ diff --git a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp deleted file mode 100644 index 376c41bc002c..000000000000 --- a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp +++ /dev/null @@ -1,190 +0,0 @@ -//===-- InferiorCallPOSIX.cpp -----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "InferiorCallPOSIX.h" -#include "lldb/Core/StreamFile.h" -#include "lldb/Core/ValueObject.h" -#include "lldb/Symbol/SymbolContext.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/ThreadPlanCallFunction.h" - -#include <sys/mman.h> - -using namespace lldb; -using namespace lldb_private; - -bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr, - addr_t addr, addr_t length, unsigned prot, - unsigned flags, addr_t fd, addr_t offset) { - Thread *thread = process->GetThreadList().GetSelectedThread().get(); - if (thread == NULL) - return false; - - const bool append = true; - const bool include_symbols = true; - const bool include_inlines = false; - SymbolContextList sc_list; - const uint32_t count - = process->GetTarget().GetImages().FindFunctions (ConstString ("mmap"), - eFunctionNameTypeFull, - include_symbols, - include_inlines, - append, - sc_list); - if (count > 0) - { - SymbolContext sc; - if (sc_list.GetContextAtIndex(0, sc)) - { - const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol; - const bool use_inline_block_range = false; - const bool stop_other_threads = true; - const bool discard_on_error = true; - const bool try_all_threads = true; - const uint32_t single_thread_timeout_usec = 500000; - - addr_t prot_arg, flags_arg = 0; - if (prot == eMmapProtNone) - prot_arg = PROT_NONE; - else { - prot_arg = 0; - if (prot & eMmapProtExec) - prot_arg |= PROT_EXEC; - if (prot & eMmapProtRead) - prot_arg |= PROT_READ; - if (prot & eMmapProtWrite) - prot_arg |= PROT_WRITE; - } - - if (flags & eMmapFlagsPrivate) - flags_arg |= MAP_PRIVATE; - if (flags & eMmapFlagsAnon) - flags_arg |= MAP_ANON; - - AddressRange mmap_range; - if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range)) - { - ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext(); - lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false); - ThreadPlanCallFunction *call_function_thread_plan - = new ThreadPlanCallFunction (*thread, - mmap_range.GetBaseAddress(), - ClangASTType (clang_ast_context->getASTContext(), clang_void_ptr_type), - stop_other_threads, - discard_on_error, - &addr, - &length, - &prot_arg, - &flags_arg, - &fd, - &offset); - lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan); - if (call_plan_sp) - { - StreamFile error_strm; - StackFrame *frame = thread->GetStackFrameAtIndex (0).get(); - if (frame) - { - ExecutionContext exe_ctx; - frame->CalculateExecutionContext (exe_ctx); - ExecutionResults result = process->RunThreadPlan (exe_ctx, - call_plan_sp, - stop_other_threads, - try_all_threads, - discard_on_error, - single_thread_timeout_usec, - error_strm); - if (result == eExecutionCompleted) - { - - allocated_addr = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); - if (process->GetAddressByteSize() == 4) - { - if (allocated_addr == UINT32_MAX) - return false; - } - return true; - } - } - } - } - } - } - - return false; -} - -bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr, - addr_t length) { - Thread *thread = process->GetThreadList().GetSelectedThread().get(); - if (thread == NULL) - return false; - - const bool append = true; - const bool include_symbols = true; - const bool include_inlines = false; - SymbolContextList sc_list; - const uint32_t count - = process->GetTarget().GetImages().FindFunctions (ConstString ("munmap"), - eFunctionNameTypeFull, - include_symbols, - include_inlines, - append, - sc_list); - if (count > 0) - { - SymbolContext sc; - if (sc_list.GetContextAtIndex(0, sc)) - { - const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol; - const bool use_inline_block_range = false; - const bool stop_other_threads = true; - const bool discard_on_error = true; - const bool try_all_threads = true; - const uint32_t single_thread_timeout_usec = 500000; - - AddressRange munmap_range; - if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range)) - { - lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread, - munmap_range.GetBaseAddress(), - ClangASTType(), - stop_other_threads, - discard_on_error, - &addr, - &length)); - if (call_plan_sp) - { - StreamFile error_strm; - StackFrame *frame = thread->GetStackFrameAtIndex (0).get(); - if (frame) - { - ExecutionContext exe_ctx; - frame->CalculateExecutionContext (exe_ctx); - ExecutionResults result = process->RunThreadPlan (exe_ctx, - call_plan_sp, - stop_other_threads, - try_all_threads, - discard_on_error, - single_thread_timeout_usec, - error_strm); - if (result == eExecutionCompleted) - { - return true; - } - } - } - } - } - } - - return false; -} diff --git a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h deleted file mode 100644 index a85db72ec036..000000000000 --- a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h +++ /dev/null @@ -1,41 +0,0 @@ -//===-- InferiorCallPOSIX.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_InferiorCallPOSIX_h_ -#define lldb_InferiorCallPOSIX_h_ - -// Inferior execution of POSIX functions. - -#include "lldb/lldb-types.h" - -namespace lldb_private { - -class Process; - -enum MmapProt { - eMmapProtNone = 0, - eMmapProtExec = 1, - eMmapProtRead = 2, - eMmapProtWrite = 4 -}; - -enum MmapFlags { - eMmapFlagsPrivate = 1, - eMmapFlagsAnon = 2 -}; - -bool InferiorCallMmap(Process *proc, lldb::addr_t &allocated_addr, - lldb::addr_t addr, lldb::addr_t length, unsigned prot, - unsigned flags, lldb::addr_t fd, lldb::addr_t offset); - -bool InferiorCallMunmap(Process *proc, lldb::addr_t addr, lldb::addr_t length); - -} // namespace lldb_private - -#endif // lldb_InferiorCallPOSIX_h_ diff --git a/lldb/source/Plugins/Process/Utility/InstructionUtils.h b/lldb/source/Plugins/Process/Utility/InstructionUtils.h deleted file mode 100644 index 4bb644e6efe6..000000000000 --- a/lldb/source/Plugins/Process/Utility/InstructionUtils.h +++ /dev/null @@ -1,136 +0,0 @@ -//===-- InstructionUtils.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_InstructionUtils_h_ -#define lldb_InstructionUtils_h_ - -// Common utilities for manipulating instruction bit fields. - -namespace lldb_private { - -// Return the bit field(s) from the most significant bit (msbit) to the -// least significant bit (lsbit) of a 64-bit unsigned value. -static inline uint64_t -Bits64 (const uint64_t bits, const uint32_t msbit, const uint32_t lsbit) -{ - assert(msbit < 64 && lsbit <= msbit); - return (bits >> lsbit) & ((1u << (msbit - lsbit + 1)) - 1); -} - -// Return the bit field(s) from the most significant bit (msbit) to the -// least significant bit (lsbit) of a 32-bit unsigned value. -static inline uint32_t -Bits32 (const uint32_t bits, const uint32_t msbit, const uint32_t lsbit) -{ - assert(msbit < 32 && lsbit <= msbit); - return (bits >> lsbit) & ((1u << (msbit - lsbit + 1)) - 1); -} - -// Return the bit value from the 'bit' position of a 32-bit unsigned value. -static inline uint32_t -Bit32 (const uint32_t bits, const uint32_t bit) -{ - return (bits >> bit) & 1u; -} - -static inline uint64_t -Bit64 (const uint64_t bits, const uint32_t bit) -{ - return (bits >> bit) & 1ull; -} - -// Set the bit field(s) from the most significant bit (msbit) to the -// least significant bit (lsbit) of a 32-bit unsigned value to 'val'. -static inline void -SetBits32(uint32_t &bits, const uint32_t msbit, const uint32_t lsbit, const uint32_t val) -{ - assert(msbit < 32 && lsbit < 32 && msbit >= lsbit); - uint32_t mask = ((1u << (msbit - lsbit + 1)) - 1); - bits &= ~(mask << lsbit); - bits |= (val & mask) << lsbit; -} - -// Set the 'bit' position of a 32-bit unsigned value to 'val'. -static inline void -SetBit32(uint32_t &bits, const uint32_t bit, const uint32_t val) -{ - SetBits32(bits, bit, bit, val); -} - -// Rotate a 32-bit unsigned value right by the specified amount. -static inline uint32_t -Rotr32 (uint32_t bits, uint32_t amt) -{ - assert(amt < 32 && "Invalid rotate amount"); - return (bits >> amt) | (bits << ((32-amt)&31)); -} - -// Rotate a 32-bit unsigned value left by the specified amount. -static inline uint32_t -Rotl32 (uint32_t bits, uint32_t amt) -{ - assert(amt < 32 && "Invalid rotate amount"); - return (bits << amt) | (bits >> ((32-amt)&31)); -} - -// Create a mask that starts at bit zero and includes "bit" -static inline uint64_t -MaskUpToBit (const uint64_t bit) -{ - return (1ull << (bit + 1ull)) - 1ull; -} - -// Return an integer result equal to the number of bits of x that are ones. -static inline uint32_t -BitCount (uint64_t x) -{ - // c accumulates the total bits set in x - uint32_t c; - for (c = 0; x; ++c) - { - x &= x - 1; // clear the least significant bit set - } - return c; -} - -static inline bool -BitIsSet (const uint64_t value, const uint64_t bit) -{ - return (value & (1ull << bit)) != 0; -} - -static inline bool -BitIsClear (const uint64_t value, const uint64_t bit) -{ - return (value & (1ull << bit)) == 0; -} - -static inline uint64_t -UnsignedBits (const uint64_t value, const uint64_t msbit, const uint64_t lsbit) -{ - uint64_t result = value >> lsbit; - result &= MaskUpToBit (msbit - lsbit); - return result; -} - -static inline int64_t -SignedBits (const uint64_t value, const uint64_t msbit, const uint64_t lsbit) -{ - uint64_t result = UnsignedBits (value, msbit, lsbit); - if (BitIsSet(value, msbit)) - { - // Sign extend - result |= ~MaskUpToBit (msbit - lsbit); - } - return result; -} - -} // namespace lldb_private - -#endif // lldb_InstructionUtils_h_ diff --git a/lldb/source/Plugins/Process/Utility/Makefile b/lldb/source/Plugins/Process/Utility/Makefile deleted file mode 100644 index f82fa88eddb7..000000000000 --- a/lldb/source/Plugins/Process/Utility/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -##===- source/Plugins/Utility/Makefile ---------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLDB_LEVEL := ../../../.. -LIBRARYNAME := lldbPluginUtility -BUILD_ARCHIVE = 1 - -include $(LLDB_LEVEL)/Makefile diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp deleted file mode 100644 index eacdef1fe1db..000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp +++ /dev/null @@ -1,1226 +0,0 @@ -//===-- RegisterContextDarwin_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(__APPLE__) - -#include "RegisterContextDarwin_arm.h" - -// C Includes -#include <mach/mach_types.h> -#include <mach/thread_act.h> - -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" -#include "lldb/Host/Endian.h" -#include "llvm/Support/Compiler.h" - -#include "Plugins/Process/Utility/InstructionUtils.h" - -// Support building against older versions of LLVM, this macro was added -// recently. -#ifndef LLVM_EXTENSION -#define LLVM_EXTENSION -#endif - -// Project includes -#include "ARM_GCC_Registers.h" -#include "ARM_DWARF_Registers.h" - -using namespace lldb; -using namespace lldb_private; - -enum -{ - gpr_r0 = 0, - gpr_r1, - gpr_r2, - gpr_r3, - gpr_r4, - gpr_r5, - gpr_r6, - gpr_r7, - gpr_r8, - gpr_r9, - gpr_r10, - gpr_r11, - gpr_r12, - gpr_r13, gpr_sp = gpr_r13, - gpr_r14, gpr_lr = gpr_r14, - gpr_r15, gpr_pc = gpr_r15, - gpr_cpsr, - - fpu_s0, - fpu_s1, - fpu_s2, - fpu_s3, - fpu_s4, - fpu_s5, - fpu_s6, - fpu_s7, - fpu_s8, - fpu_s9, - fpu_s10, - fpu_s11, - fpu_s12, - fpu_s13, - fpu_s14, - fpu_s15, - fpu_s16, - fpu_s17, - fpu_s18, - fpu_s19, - fpu_s20, - fpu_s21, - fpu_s22, - fpu_s23, - fpu_s24, - fpu_s25, - fpu_s26, - fpu_s27, - fpu_s28, - fpu_s29, - fpu_s30, - fpu_s31, - fpu_fpscr, - - exc_exception, - exc_fsr, - exc_far, - - dbg_bvr0, - dbg_bvr1, - dbg_bvr2, - dbg_bvr3, - dbg_bvr4, - dbg_bvr5, - dbg_bvr6, - dbg_bvr7, - dbg_bvr8, - dbg_bvr9, - dbg_bvr10, - dbg_bvr11, - dbg_bvr12, - dbg_bvr13, - dbg_bvr14, - dbg_bvr15, - - dbg_bcr0, - dbg_bcr1, - dbg_bcr2, - dbg_bcr3, - dbg_bcr4, - dbg_bcr5, - dbg_bcr6, - dbg_bcr7, - dbg_bcr8, - dbg_bcr9, - dbg_bcr10, - dbg_bcr11, - dbg_bcr12, - dbg_bcr13, - dbg_bcr14, - dbg_bcr15, - - dbg_wvr0, - dbg_wvr1, - dbg_wvr2, - dbg_wvr3, - dbg_wvr4, - dbg_wvr5, - dbg_wvr6, - dbg_wvr7, - dbg_wvr8, - dbg_wvr9, - dbg_wvr10, - dbg_wvr11, - dbg_wvr12, - dbg_wvr13, - dbg_wvr14, - dbg_wvr15, - - dbg_wcr0, - dbg_wcr1, - dbg_wcr2, - dbg_wcr3, - dbg_wcr4, - dbg_wcr5, - dbg_wcr6, - dbg_wcr7, - dbg_wcr8, - dbg_wcr9, - dbg_wcr10, - dbg_wcr11, - dbg_wcr12, - dbg_wcr13, - dbg_wcr14, - dbg_wcr15, - - k_num_registers -}; - - -RegisterContextDarwin_arm::RegisterContextDarwin_arm(Thread &thread, uint32_t concrete_frame_idx) : - RegisterContext(thread, concrete_frame_idx), - gpr(), - fpu(), - exc() -{ - uint32_t i; - for (i=0; i<kNumErrors; i++) - { - gpr_errs[i] = -1; - fpu_errs[i] = -1; - exc_errs[i] = -1; - } -} - -RegisterContextDarwin_arm::~RegisterContextDarwin_arm() -{ -} - - -#define GPR_OFFSET(idx) ((idx) * 4) -#define FPU_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextDarwin_arm::GPR)) -#define EXC_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU)) -#define DBG_OFFSET(reg) ((LLVM_EXTENSION offsetof (RegisterContextDarwin_arm::DBG, reg) + sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU) + sizeof (RegisterContextDarwin_arm::EXC))) - -#define DEFINE_DBG(reg, i) #reg, NULL, sizeof(((RegisterContextDarwin_arm::DBG *)NULL)->reg[i]), DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, dbg_##reg##i }, NULL, NULL -#define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU) + sizeof (RegisterContextDarwin_arm::EXC)) - -static RegisterInfo g_register_infos[] = { -// General purpose registers -// NAME ALT SZ OFFSET ENCODING FORMAT COMPILER DWARF GENERIC GDB LLDB NATIVE VALUE REGS INVALIDATE REGS -// ====== ======= == ============= ============= ============ =============== =============== ========================= ===================== ============= ========== =============== -{ "r0", NULL, 4, GPR_OFFSET(0), eEncodingUint, eFormatHex, { gcc_r0, dwarf_r0, LLDB_INVALID_REGNUM, gdb_arm_r0, gpr_r0 }, NULL, NULL}, -{ "r1", NULL, 4, GPR_OFFSET(1), eEncodingUint, eFormatHex, { gcc_r1, dwarf_r1, LLDB_INVALID_REGNUM, gdb_arm_r1, gpr_r1 }, NULL, NULL}, -{ "r2", NULL, 4, GPR_OFFSET(2), eEncodingUint, eFormatHex, { gcc_r2, dwarf_r2, LLDB_INVALID_REGNUM, gdb_arm_r2, gpr_r2 }, NULL, NULL}, -{ "r3", NULL, 4, GPR_OFFSET(3), eEncodingUint, eFormatHex, { gcc_r3, dwarf_r3, LLDB_INVALID_REGNUM, gdb_arm_r3, gpr_r3 }, NULL, NULL}, -{ "r4", NULL, 4, GPR_OFFSET(4), eEncodingUint, eFormatHex, { gcc_r4, dwarf_r4, LLDB_INVALID_REGNUM, gdb_arm_r4, gpr_r4 }, NULL, NULL}, -{ "r5", NULL, 4, GPR_OFFSET(5), eEncodingUint, eFormatHex, { gcc_r5, dwarf_r5, LLDB_INVALID_REGNUM, gdb_arm_r5, gpr_r5 }, NULL, NULL}, -{ "r6", NULL, 4, GPR_OFFSET(6), eEncodingUint, eFormatHex, { gcc_r6, dwarf_r6, LLDB_INVALID_REGNUM, gdb_arm_r6, gpr_r6 }, NULL, NULL}, -{ "r7", NULL, 4, GPR_OFFSET(7), eEncodingUint, eFormatHex, { gcc_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, gdb_arm_r7, gpr_r7 }, NULL, NULL}, -{ "r8", NULL, 4, GPR_OFFSET(8), eEncodingUint, eFormatHex, { gcc_r8, dwarf_r8, LLDB_INVALID_REGNUM, gdb_arm_r8, gpr_r8 }, NULL, NULL}, -{ "r9", NULL, 4, GPR_OFFSET(9), eEncodingUint, eFormatHex, { gcc_r9, dwarf_r9, LLDB_INVALID_REGNUM, gdb_arm_r9, gpr_r9 }, NULL, NULL}, -{ "r10", NULL, 4, GPR_OFFSET(10), eEncodingUint, eFormatHex, { gcc_r10, dwarf_r10, LLDB_INVALID_REGNUM, gdb_arm_r10, gpr_r10 }, NULL, NULL}, -{ "r11", NULL, 4, GPR_OFFSET(11), eEncodingUint, eFormatHex, { gcc_r11, dwarf_r11, LLDB_INVALID_REGNUM, gdb_arm_r11, gpr_r11 }, NULL, NULL}, -{ "r12", NULL, 4, GPR_OFFSET(12), eEncodingUint, eFormatHex, { gcc_r12, dwarf_r12, LLDB_INVALID_REGNUM, gdb_arm_r12, gpr_r12 }, NULL, NULL}, -{ "sp", "r13", 4, GPR_OFFSET(13), eEncodingUint, eFormatHex, { gcc_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, gdb_arm_sp, gpr_sp }, NULL, NULL}, -{ "lr", "r14", 4, GPR_OFFSET(14), eEncodingUint, eFormatHex, { gcc_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, gdb_arm_lr, gpr_lr }, NULL, NULL}, -{ "pc", "r15", 4, GPR_OFFSET(15), eEncodingUint, eFormatHex, { gcc_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, gdb_arm_pc, gpr_pc }, NULL, NULL}, -{ "cpsr", "psr", 4, GPR_OFFSET(16), eEncodingUint, eFormatHex, { gcc_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, gdb_arm_cpsr, gpr_cpsr }, NULL, NULL}, - -{ "s0", NULL, 4, FPU_OFFSET(0), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, gdb_arm_s0, fpu_s0 }, NULL, NULL}, -{ "s1", NULL, 4, FPU_OFFSET(1), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, gdb_arm_s1, fpu_s1 }, NULL, NULL}, -{ "s2", NULL, 4, FPU_OFFSET(2), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, gdb_arm_s2, fpu_s2 }, NULL, NULL}, -{ "s3", NULL, 4, FPU_OFFSET(3), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, gdb_arm_s3, fpu_s3 }, NULL, NULL}, -{ "s4", NULL, 4, FPU_OFFSET(4), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, gdb_arm_s4, fpu_s4 }, NULL, NULL}, -{ "s5", NULL, 4, FPU_OFFSET(5), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, gdb_arm_s5, fpu_s5 }, NULL, NULL}, -{ "s6", NULL, 4, FPU_OFFSET(6), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, gdb_arm_s6, fpu_s6 }, NULL, NULL}, -{ "s7", NULL, 4, FPU_OFFSET(7), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, gdb_arm_s7, fpu_s7 }, NULL, NULL}, -{ "s8", NULL, 4, FPU_OFFSET(8), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, gdb_arm_s8, fpu_s8 }, NULL, NULL}, -{ "s9", NULL, 4, FPU_OFFSET(9), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, gdb_arm_s9, fpu_s9 }, NULL, NULL}, -{ "s10", NULL, 4, FPU_OFFSET(10), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, gdb_arm_s10, fpu_s10 }, NULL, NULL}, -{ "s11", NULL, 4, FPU_OFFSET(11), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, gdb_arm_s11, fpu_s11 }, NULL, NULL}, -{ "s12", NULL, 4, FPU_OFFSET(12), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, gdb_arm_s12, fpu_s12 }, NULL, NULL}, -{ "s13", NULL, 4, FPU_OFFSET(13), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, gdb_arm_s13, fpu_s13 }, NULL, NULL}, -{ "s14", NULL, 4, FPU_OFFSET(14), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, gdb_arm_s14, fpu_s14 }, NULL, NULL}, -{ "s15", NULL, 4, FPU_OFFSET(15), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, gdb_arm_s15, fpu_s15 }, NULL, NULL}, -{ "s16", NULL, 4, FPU_OFFSET(16), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, gdb_arm_s16, fpu_s16 }, NULL, NULL}, -{ "s17", NULL, 4, FPU_OFFSET(17), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, gdb_arm_s17, fpu_s17 }, NULL, NULL}, -{ "s18", NULL, 4, FPU_OFFSET(18), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, gdb_arm_s18, fpu_s18 }, NULL, NULL}, -{ "s19", NULL, 4, FPU_OFFSET(19), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, gdb_arm_s19, fpu_s19 }, NULL, NULL}, -{ "s20", NULL, 4, FPU_OFFSET(20), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, gdb_arm_s20, fpu_s20 }, NULL, NULL}, -{ "s21", NULL, 4, FPU_OFFSET(21), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, gdb_arm_s21, fpu_s21 }, NULL, NULL}, -{ "s22", NULL, 4, FPU_OFFSET(22), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, gdb_arm_s22, fpu_s22 }, NULL, NULL}, -{ "s23", NULL, 4, FPU_OFFSET(23), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, gdb_arm_s23, fpu_s23 }, NULL, NULL}, -{ "s24", NULL, 4, FPU_OFFSET(24), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, gdb_arm_s24, fpu_s24 }, NULL, NULL}, -{ "s25", NULL, 4, FPU_OFFSET(25), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, gdb_arm_s25, fpu_s25 }, NULL, NULL}, -{ "s26", NULL, 4, FPU_OFFSET(26), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, gdb_arm_s26, fpu_s26 }, NULL, NULL}, -{ "s27", NULL, 4, FPU_OFFSET(27), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, gdb_arm_s27, fpu_s27 }, NULL, NULL}, -{ "s28", NULL, 4, FPU_OFFSET(28), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, gdb_arm_s28, fpu_s28 }, NULL, NULL}, -{ "s29", NULL, 4, FPU_OFFSET(29), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, gdb_arm_s29, fpu_s29 }, NULL, NULL}, -{ "s30", NULL, 4, FPU_OFFSET(30), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, gdb_arm_s30, fpu_s30 }, NULL, NULL}, -{ "s31", NULL, 4, FPU_OFFSET(31), eEncodingIEEE754,eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, gdb_arm_s31, fpu_s31 }, NULL, NULL}, -{ "fpscr", NULL, 4, FPU_OFFSET(32), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, gdb_arm_fpscr, fpu_fpscr }, NULL, NULL}, - -{ "exception",NULL, 4, EXC_OFFSET(0), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_exception }, NULL, NULL}, -{ "fsr", NULL, 4, EXC_OFFSET(1), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_fsr }, NULL, NULL}, -{ "far", NULL, 4, EXC_OFFSET(2), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_far }, NULL, NULL}, - -{ DEFINE_DBG (bvr, 0) }, -{ DEFINE_DBG (bvr, 1) }, -{ DEFINE_DBG (bvr, 2) }, -{ DEFINE_DBG (bvr, 3) }, -{ DEFINE_DBG (bvr, 4) }, -{ DEFINE_DBG (bvr, 5) }, -{ DEFINE_DBG (bvr, 6) }, -{ DEFINE_DBG (bvr, 7) }, -{ DEFINE_DBG (bvr, 8) }, -{ DEFINE_DBG (bvr, 9) }, -{ DEFINE_DBG (bvr, 10) }, -{ DEFINE_DBG (bvr, 11) }, -{ DEFINE_DBG (bvr, 12) }, -{ DEFINE_DBG (bvr, 13) }, -{ DEFINE_DBG (bvr, 14) }, -{ DEFINE_DBG (bvr, 15) }, - -{ DEFINE_DBG (bcr, 0) }, -{ DEFINE_DBG (bcr, 1) }, -{ DEFINE_DBG (bcr, 2) }, -{ DEFINE_DBG (bcr, 3) }, -{ DEFINE_DBG (bcr, 4) }, -{ DEFINE_DBG (bcr, 5) }, -{ DEFINE_DBG (bcr, 6) }, -{ DEFINE_DBG (bcr, 7) }, -{ DEFINE_DBG (bcr, 8) }, -{ DEFINE_DBG (bcr, 9) }, -{ DEFINE_DBG (bcr, 10) }, -{ DEFINE_DBG (bcr, 11) }, -{ DEFINE_DBG (bcr, 12) }, -{ DEFINE_DBG (bcr, 13) }, -{ DEFINE_DBG (bcr, 14) }, -{ DEFINE_DBG (bcr, 15) }, - -{ DEFINE_DBG (wvr, 0) }, -{ DEFINE_DBG (wvr, 1) }, -{ DEFINE_DBG (wvr, 2) }, -{ DEFINE_DBG (wvr, 3) }, -{ DEFINE_DBG (wvr, 4) }, -{ DEFINE_DBG (wvr, 5) }, -{ DEFINE_DBG (wvr, 6) }, -{ DEFINE_DBG (wvr, 7) }, -{ DEFINE_DBG (wvr, 8) }, -{ DEFINE_DBG (wvr, 9) }, -{ DEFINE_DBG (wvr, 10) }, -{ DEFINE_DBG (wvr, 11) }, -{ DEFINE_DBG (wvr, 12) }, -{ DEFINE_DBG (wvr, 13) }, -{ DEFINE_DBG (wvr, 14) }, -{ DEFINE_DBG (wvr, 15) }, - -{ DEFINE_DBG (wcr, 0) }, -{ DEFINE_DBG (wcr, 1) }, -{ DEFINE_DBG (wcr, 2) }, -{ DEFINE_DBG (wcr, 3) }, -{ DEFINE_DBG (wcr, 4) }, -{ DEFINE_DBG (wcr, 5) }, -{ DEFINE_DBG (wcr, 6) }, -{ DEFINE_DBG (wcr, 7) }, -{ DEFINE_DBG (wcr, 8) }, -{ DEFINE_DBG (wcr, 9) }, -{ DEFINE_DBG (wcr, 10) }, -{ DEFINE_DBG (wcr, 11) }, -{ DEFINE_DBG (wcr, 12) }, -{ DEFINE_DBG (wcr, 13) }, -{ DEFINE_DBG (wcr, 14) }, -{ DEFINE_DBG (wcr, 15) } -}; - -// General purpose registers -static uint32_t -g_gpr_regnums[] = -{ - gpr_r0, - gpr_r1, - gpr_r2, - gpr_r3, - gpr_r4, - gpr_r5, - gpr_r6, - gpr_r7, - gpr_r8, - gpr_r9, - gpr_r10, - gpr_r11, - gpr_r12, - gpr_sp, - gpr_lr, - gpr_pc, - gpr_cpsr -}; - -// Floating point registers -static uint32_t -g_fpu_regnums[] = -{ - fpu_s0, - fpu_s1, - fpu_s2, - fpu_s3, - fpu_s4, - fpu_s5, - fpu_s6, - fpu_s7, - fpu_s8, - fpu_s9, - fpu_s10, - fpu_s11, - fpu_s12, - fpu_s13, - fpu_s14, - fpu_s15, - fpu_s16, - fpu_s17, - fpu_s18, - fpu_s19, - fpu_s20, - fpu_s21, - fpu_s22, - fpu_s23, - fpu_s24, - fpu_s25, - fpu_s26, - fpu_s27, - fpu_s28, - fpu_s29, - fpu_s30, - fpu_s31, - fpu_fpscr, -}; - -// Exception registers - -static uint32_t -g_exc_regnums[] = -{ - exc_exception, - exc_fsr, - exc_far, -}; - -static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo)); - -void -RegisterContextDarwin_arm::InvalidateAllRegisters () -{ - InvalidateAllRegisterStates(); -} - - -size_t -RegisterContextDarwin_arm::GetRegisterCount () -{ - assert(k_num_register_infos == k_num_registers); - return k_num_registers; -} - -const RegisterInfo * -RegisterContextDarwin_arm::GetRegisterInfoAtIndex (uint32_t reg) -{ - assert(k_num_register_infos == k_num_registers); - if (reg < k_num_registers) - return &g_register_infos[reg]; - return NULL; -} - -size_t -RegisterContextDarwin_arm::GetRegisterInfosCount () -{ - return k_num_register_infos; -} - -const RegisterInfo * -RegisterContextDarwin_arm::GetRegisterInfos () -{ - return g_register_infos; -} - - -// Number of registers in each register set -const size_t k_num_gpr_registers = sizeof(g_gpr_regnums) / sizeof(uint32_t); -const size_t k_num_fpu_registers = sizeof(g_fpu_regnums) / sizeof(uint32_t); -const size_t k_num_exc_registers = sizeof(g_exc_regnums) / sizeof(uint32_t); - -//---------------------------------------------------------------------- -// Register set definitions. The first definitions at register set index -// of zero is for all registers, followed by other registers sets. The -// register information for the all register set need not be filled in. -//---------------------------------------------------------------------- -static const RegisterSet g_reg_sets[] = -{ - { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, }, - { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums }, - { "Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums } -}; - -const size_t k_num_regsets = sizeof(g_reg_sets) / sizeof(RegisterSet); - - -size_t -RegisterContextDarwin_arm::GetRegisterSetCount () -{ - return k_num_regsets; -} - -const RegisterSet * -RegisterContextDarwin_arm::GetRegisterSet (uint32_t reg_set) -{ - if (reg_set < k_num_regsets) - return &g_reg_sets[reg_set]; - return NULL; -} - - -//---------------------------------------------------------------------- -// Register information defintions for 32 bit i386. -//---------------------------------------------------------------------- -int -RegisterContextDarwin_arm::GetSetForNativeRegNum (int reg) -{ - if (reg < fpu_s0) - return GPRRegSet; - else if (reg < exc_exception) - return FPURegSet; - else if (reg < k_num_registers) - return EXCRegSet; - return -1; -} - -int -RegisterContextDarwin_arm::ReadGPR (bool force) -{ - int set = GPRRegSet; - if (force || !RegisterSetIsCached(set)) - { - SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr)); - } - return GetError(GPRRegSet, Read); -} - -int -RegisterContextDarwin_arm::ReadFPU (bool force) -{ - int set = FPURegSet; - if (force || !RegisterSetIsCached(set)) - { - SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu)); - } - return GetError(FPURegSet, Read); -} - -int -RegisterContextDarwin_arm::ReadEXC (bool force) -{ - int set = EXCRegSet; - if (force || !RegisterSetIsCached(set)) - { - SetError(set, Read, DoReadEXC(GetThreadID(), set, exc)); - } - return GetError(EXCRegSet, Read); -} - -int -RegisterContextDarwin_arm::ReadDBG (bool force) -{ - int set = DBGRegSet; - if (force || !RegisterSetIsCached(set)) - { - SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg)); - } - return GetError(DBGRegSet, Read); -} - -int -RegisterContextDarwin_arm::WriteGPR () -{ - int set = GPRRegSet; - if (!RegisterSetIsCached(set)) - { - SetError (set, Write, -1); - return KERN_INVALID_ARGUMENT; - } - SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr)); - SetError (set, Read, -1); - return GetError(GPRRegSet, Write); -} - -int -RegisterContextDarwin_arm::WriteFPU () -{ - int set = FPURegSet; - if (!RegisterSetIsCached(set)) - { - SetError (set, Write, -1); - return KERN_INVALID_ARGUMENT; - } - SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu)); - SetError (set, Read, -1); - return GetError(FPURegSet, Write); -} - -int -RegisterContextDarwin_arm::WriteEXC () -{ - int set = EXCRegSet; - if (!RegisterSetIsCached(set)) - { - SetError (set, Write, -1); - return KERN_INVALID_ARGUMENT; - } - SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc)); - SetError (set, Read, -1); - return GetError(EXCRegSet, Write); -} - -int -RegisterContextDarwin_arm::WriteDBG () -{ - int set = DBGRegSet; - if (!RegisterSetIsCached(set)) - { - SetError (set, Write, -1); - return KERN_INVALID_ARGUMENT; - } - SetError (set, Write, DoWriteDBG(GetThreadID(), set, dbg)); - SetError (set, Read, -1); - return GetError(DBGRegSet, Write); -} - - -int -RegisterContextDarwin_arm::ReadRegisterSet (uint32_t set, bool force) -{ - switch (set) - { - case GPRRegSet: return ReadGPR(force); - case FPURegSet: return ReadFPU(force); - case EXCRegSet: return ReadEXC(force); - case DBGRegSet: return ReadDBG(force); - default: break; - } - return KERN_INVALID_ARGUMENT; -} - -int -RegisterContextDarwin_arm::WriteRegisterSet (uint32_t set) -{ - // Make sure we have a valid context to set. - if (RegisterSetIsCached(set)) - { - switch (set) - { - case GPRRegSet: return WriteGPR(); - case FPURegSet: return WriteFPU(); - case EXCRegSet: return WriteEXC(); - case DBGRegSet: return WriteDBG(); - default: break; - } - } - return KERN_INVALID_ARGUMENT; -} - -void -RegisterContextDarwin_arm::LogDBGRegisters (Log *log, const DBG& dbg) -{ - if (log) - { - for (uint32_t i=0; i<16; i++) - log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { 0x%8.8x, 0x%8.8x }", - i, i, dbg.bvr[i], dbg.bcr[i], - i, i, dbg.wvr[i], dbg.wcr[i]); - } -} - - -bool -RegisterContextDarwin_arm::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) -{ - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - int set = RegisterContextDarwin_arm::GetSetForNativeRegNum (reg); - - if (set == -1) - return false; - - if (ReadRegisterSet(set, false) != KERN_SUCCESS) - return false; - - switch (reg) - { - case gpr_r0: - case gpr_r1: - case gpr_r2: - case gpr_r3: - case gpr_r4: - case gpr_r5: - case gpr_r6: - case gpr_r7: - case gpr_r8: - case gpr_r9: - case gpr_r10: - case gpr_r11: - case gpr_r12: - case gpr_sp: - case gpr_lr: - case gpr_pc: - case gpr_cpsr: - value.SetUInt32 (gpr.r[reg - gpr_r0]); - break; - - case fpu_s0: - case fpu_s1: - case fpu_s2: - case fpu_s3: - case fpu_s4: - case fpu_s5: - case fpu_s6: - case fpu_s7: - case fpu_s8: - case fpu_s9: - case fpu_s10: - case fpu_s11: - case fpu_s12: - case fpu_s13: - case fpu_s14: - case fpu_s15: - case fpu_s16: - case fpu_s17: - case fpu_s18: - case fpu_s19: - case fpu_s20: - case fpu_s21: - case fpu_s22: - case fpu_s23: - case fpu_s24: - case fpu_s25: - case fpu_s26: - case fpu_s27: - case fpu_s28: - case fpu_s29: - case fpu_s30: - case fpu_s31: - value.SetUInt32 (fpu.floats.s[reg], RegisterValue::eTypeFloat); - break; - - case fpu_fpscr: - value.SetUInt32 (fpu.fpscr); - break; - - case exc_exception: - value.SetUInt32 (exc.exception); - break; - case exc_fsr: - value.SetUInt32 (exc.fsr); - break; - case exc_far: - value.SetUInt32 (exc.far); - break; - - default: - value.SetValueToInvalid(); - return false; - - } - return true; -} - - -bool -RegisterContextDarwin_arm::WriteRegister (const RegisterInfo *reg_info, - const RegisterValue &value) -{ - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - int set = GetSetForNativeRegNum (reg); - - if (set == -1) - return false; - - if (ReadRegisterSet(set, false) != KERN_SUCCESS) - return false; - - switch (reg) - { - case gpr_r0: - case gpr_r1: - case gpr_r2: - case gpr_r3: - case gpr_r4: - case gpr_r5: - case gpr_r6: - case gpr_r7: - case gpr_r8: - case gpr_r9: - case gpr_r10: - case gpr_r11: - case gpr_r12: - case gpr_sp: - case gpr_lr: - case gpr_pc: - case gpr_cpsr: - gpr.r[reg - gpr_r0] = value.GetAsUInt32(); - break; - - case fpu_s0: - case fpu_s1: - case fpu_s2: - case fpu_s3: - case fpu_s4: - case fpu_s5: - case fpu_s6: - case fpu_s7: - case fpu_s8: - case fpu_s9: - case fpu_s10: - case fpu_s11: - case fpu_s12: - case fpu_s13: - case fpu_s14: - case fpu_s15: - case fpu_s16: - case fpu_s17: - case fpu_s18: - case fpu_s19: - case fpu_s20: - case fpu_s21: - case fpu_s22: - case fpu_s23: - case fpu_s24: - case fpu_s25: - case fpu_s26: - case fpu_s27: - case fpu_s28: - case fpu_s29: - case fpu_s30: - case fpu_s31: - fpu.floats.s[reg] = value.GetAsUInt32(); - break; - - case fpu_fpscr: - fpu.fpscr = value.GetAsUInt32(); - break; - - case exc_exception: - exc.exception = value.GetAsUInt32(); - break; - case exc_fsr: - exc.fsr = value.GetAsUInt32(); - break; - case exc_far: - exc.far = value.GetAsUInt32(); - break; - - default: - return false; - - } - return WriteRegisterSet(set) == KERN_SUCCESS; -} - -bool -RegisterContextDarwin_arm::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) -{ - data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0)); - if (data_sp && - ReadGPR (false) == KERN_SUCCESS && - ReadFPU (false) == KERN_SUCCESS && - ReadEXC (false) == KERN_SUCCESS) - { - uint8_t *dst = data_sp->GetBytes(); - ::memcpy (dst, &gpr, sizeof(gpr)); - dst += sizeof(gpr); - - ::memcpy (dst, &fpu, sizeof(fpu)); - dst += sizeof(gpr); - - ::memcpy (dst, &exc, sizeof(exc)); - return true; - } - return false; -} - -bool -RegisterContextDarwin_arm::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) -{ - if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) - { - const uint8_t *src = data_sp->GetBytes(); - ::memcpy (&gpr, src, sizeof(gpr)); - src += sizeof(gpr); - - ::memcpy (&fpu, src, sizeof(fpu)); - src += sizeof(gpr); - - ::memcpy (&exc, src, sizeof(exc)); - uint32_t success_count = 0; - if (WriteGPR() == KERN_SUCCESS) - ++success_count; - if (WriteFPU() == KERN_SUCCESS) - ++success_count; - if (WriteEXC() == KERN_SUCCESS) - ++success_count; - return success_count == 3; - } - return false; -} - -uint32_t -RegisterContextDarwin_arm::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t reg) -{ - if (kind == eRegisterKindGeneric) - { - switch (reg) - { - case LLDB_REGNUM_GENERIC_PC: return gpr_pc; - case LLDB_REGNUM_GENERIC_SP: return gpr_sp; - case LLDB_REGNUM_GENERIC_FP: return gpr_r7; - case LLDB_REGNUM_GENERIC_RA: return gpr_lr; - case LLDB_REGNUM_GENERIC_FLAGS: return gpr_cpsr; - default: - break; - } - } - else if (kind == eRegisterKindDWARF) - { - switch (reg) - { - case dwarf_r0: return gpr_r0; - case dwarf_r1: return gpr_r1; - case dwarf_r2: return gpr_r2; - case dwarf_r3: return gpr_r3; - case dwarf_r4: return gpr_r4; - case dwarf_r5: return gpr_r5; - case dwarf_r6: return gpr_r6; - case dwarf_r7: return gpr_r7; - case dwarf_r8: return gpr_r8; - case dwarf_r9: return gpr_r9; - case dwarf_r10: return gpr_r10; - case dwarf_r11: return gpr_r11; - case dwarf_r12: return gpr_r12; - case dwarf_sp: return gpr_sp; - case dwarf_lr: return gpr_lr; - case dwarf_pc: return gpr_pc; - case dwarf_spsr: return gpr_cpsr; - - case dwarf_s0: return fpu_s0; - case dwarf_s1: return fpu_s1; - case dwarf_s2: return fpu_s2; - case dwarf_s3: return fpu_s3; - case dwarf_s4: return fpu_s4; - case dwarf_s5: return fpu_s5; - case dwarf_s6: return fpu_s6; - case dwarf_s7: return fpu_s7; - case dwarf_s8: return fpu_s8; - case dwarf_s9: return fpu_s9; - case dwarf_s10: return fpu_s10; - case dwarf_s11: return fpu_s11; - case dwarf_s12: return fpu_s12; - case dwarf_s13: return fpu_s13; - case dwarf_s14: return fpu_s14; - case dwarf_s15: return fpu_s15; - case dwarf_s16: return fpu_s16; - case dwarf_s17: return fpu_s17; - case dwarf_s18: return fpu_s18; - case dwarf_s19: return fpu_s19; - case dwarf_s20: return fpu_s20; - case dwarf_s21: return fpu_s21; - case dwarf_s22: return fpu_s22; - case dwarf_s23: return fpu_s23; - case dwarf_s24: return fpu_s24; - case dwarf_s25: return fpu_s25; - case dwarf_s26: return fpu_s26; - case dwarf_s27: return fpu_s27; - case dwarf_s28: return fpu_s28; - case dwarf_s29: return fpu_s29; - case dwarf_s30: return fpu_s30; - case dwarf_s31: return fpu_s31; - - default: - break; - } - } - else if (kind == eRegisterKindGCC) - { - switch (reg) - { - case gcc_r0: return gpr_r0; - case gcc_r1: return gpr_r1; - case gcc_r2: return gpr_r2; - case gcc_r3: return gpr_r3; - case gcc_r4: return gpr_r4; - case gcc_r5: return gpr_r5; - case gcc_r6: return gpr_r6; - case gcc_r7: return gpr_r7; - case gcc_r8: return gpr_r8; - case gcc_r9: return gpr_r9; - case gcc_r10: return gpr_r10; - case gcc_r11: return gpr_r11; - case gcc_r12: return gpr_r12; - case gcc_sp: return gpr_sp; - case gcc_lr: return gpr_lr; - case gcc_pc: return gpr_pc; - case gcc_cpsr: return gpr_cpsr; - } - } - else if (kind == eRegisterKindLLDB) - { - return reg; - } - return LLDB_INVALID_REGNUM; -} - - -uint32_t -RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints () -{ -#if defined (__arm__) - // Set the init value to something that will let us know that we need to - // autodetect how many breakpoints are supported dynamically... - static uint32_t g_num_supported_hw_breakpoints = UINT32_MAX; - if (g_num_supported_hw_breakpoints == UINT32_MAX) - { - // Set this to zero in case we can't tell if there are any HW breakpoints - g_num_supported_hw_breakpoints = 0; - - uint32_t register_DBGDIDR; - - asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR)); - g_num_supported_hw_breakpoints = Bits32 (register_DBGDIDR, 27, 24); - // Zero is reserved for the BRP count, so don't increment it if it is zero - if (g_num_supported_hw_breakpoints > 0) - g_num_supported_hw_breakpoints++; -// if (log) log->Printf ("DBGDIDR=0x%8.8x (number BRP pairs = %u)", register_DBGDIDR, g_num_supported_hw_breakpoints); - - } - return g_num_supported_hw_breakpoints; -#else - // TODO: figure out remote case here! - return 6; -#endif -} - -uint32_t -RegisterContextDarwin_arm::SetHardwareBreakpoint (lldb::addr_t addr, size_t size) -{ - // Make sure our address isn't bogus - if (addr & 1) - return LLDB_INVALID_INDEX32; - - int kret = ReadDBG (false); - - if (kret == KERN_SUCCESS) - { - const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints(); - uint32_t i; - for (i=0; i<num_hw_breakpoints; ++i) - { - if ((dbg.bcr[i] & BCR_ENABLE) == 0) - break; // We found an available hw breakpoint slot (in i) - } - - // See if we found an available hw breakpoint slot above - if (i < num_hw_breakpoints) - { - // Make sure bits 1:0 are clear in our address - dbg.bvr[i] = addr & ~((lldb::addr_t)3); - - if (size == 2 || addr & 2) - { - uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1; - - // We have a thumb breakpoint - // We have an ARM breakpoint - dbg.bcr[i] = BCR_M_IMVA_MATCH | // Stop on address mismatch - byte_addr_select | // Set the correct byte address select so we only trigger on the correct opcode - S_USER | // Which modes should this breakpoint stop in? - BCR_ENABLE; // Enable this hardware breakpoint -// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (Thumb)", -// addr, -// size, -// i, -// i, -// dbg.bvr[i], -// dbg.bcr[i]); - } - else if (size == 4) - { - // We have an ARM breakpoint - dbg.bcr[i] = BCR_M_IMVA_MATCH | // Stop on address mismatch - BAS_IMVA_ALL | // Stop on any of the four bytes following the IMVA - S_USER | // Which modes should this breakpoint stop in? - BCR_ENABLE; // Enable this hardware breakpoint -// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (ARM)", -// addr, -// size, -// i, -// i, -// dbg.bvr[i], -// dbg.bcr[i]); - } - - kret = WriteDBG(); -// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint() WriteDBG() => 0x%8.8x.", kret); - - if (kret == KERN_SUCCESS) - return i; - } -// else -// { -// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(addr = %8.8p, size = %u) => all hardware breakpoint resources are being used.", addr, size); -// } - } - - return LLDB_INVALID_INDEX32; -} - -bool -RegisterContextDarwin_arm::ClearHardwareBreakpoint (uint32_t hw_index) -{ - int kret = ReadDBG (false); - - const uint32_t num_hw_points = NumSupportedHardwareBreakpoints(); - if (kret == KERN_SUCCESS) - { - if (hw_index < num_hw_points) - { - dbg.bcr[hw_index] = 0; -// if (log) log->Printf ("RegisterContextDarwin_arm::SetHardwareBreakpoint( %u ) - BVR%u = 0x%8.8x BCR%u = 0x%8.8x", -// hw_index, -// hw_index, -// dbg.bvr[hw_index], -// hw_index, -// dbg.bcr[hw_index]); - - kret = WriteDBG(); - - if (kret == KERN_SUCCESS) - return true; - } - } - return false; -} - -uint32_t -RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints () -{ -#if defined (__arm__) - // Set the init value to something that will let us know that we need to - // autodetect how many watchpoints are supported dynamically... - static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX; - if (g_num_supported_hw_watchpoints == UINT32_MAX) - { - // Set this to zero in case we can't tell if there are any HW breakpoints - g_num_supported_hw_watchpoints = 0; - - uint32_t register_DBGDIDR; - asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR)); - g_num_supported_hw_watchpoints = Bits32 (register_DBGDIDR, 31, 28) + 1; -// if (log) log->Printf ("DBGDIDR=0x%8.8x (number WRP pairs = %u)", register_DBGDIDR, g_num_supported_hw_watchpoints); - } - return g_num_supported_hw_watchpoints; -#else - // TODO: figure out remote case here! - return 2; -#endif -} - - -uint32_t -RegisterContextDarwin_arm::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write) -{ -// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(addr = %8.8p, size = %u, read = %u, write = %u)", addr, size, read, write); - - const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); - - // Can't watch zero bytes - if (size == 0) - return LLDB_INVALID_INDEX32; - - // We must watch for either read or write - if (read == false && write == false) - return LLDB_INVALID_INDEX32; - - // Can't watch more than 4 bytes per WVR/WCR pair - if (size > 4) - return LLDB_INVALID_INDEX32; - - // We can only watch up to four bytes that follow a 4 byte aligned address - // per watchpoint register pair. Since we have at most so we can only watch - // until the next 4 byte boundary and we need to make sure we can properly - // encode this. - uint32_t addr_word_offset = addr % 4; -// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset); - - uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset; -// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask); - if (byte_mask > 0xfu) - return LLDB_INVALID_INDEX32; - - // Read the debug state - int kret = ReadDBG (false); - - if (kret == KERN_SUCCESS) - { - // Check to make sure we have the needed hardware support - uint32_t i = 0; - - for (i=0; i<num_hw_watchpoints; ++i) - { - if ((dbg.wcr[i] & WCR_ENABLE) == 0) - break; // We found an available hw breakpoint slot (in i) - } - - // See if we found an available hw breakpoint slot above - if (i < num_hw_watchpoints) - { - // Make the byte_mask into a valid Byte Address Select mask - uint32_t byte_address_select = byte_mask << 5; - // Make sure bits 1:0 are clear in our address - dbg.wvr[i] = addr & ~((lldb::addr_t)3); - dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA that we will watch - S_USER | // Stop only in user mode - (read ? WCR_LOAD : 0) | // Stop on read access? - (write ? WCR_STORE : 0) | // Stop on write access? - WCR_ENABLE; // Enable this watchpoint; - - kret = WriteDBG(); -// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() WriteDBG() => 0x%8.8x.", kret); - - if (kret == KERN_SUCCESS) - return i; - } - else - { -// if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints); - } - } - return LLDB_INVALID_INDEX32; -} - -bool -RegisterContextDarwin_arm::ClearHardwareWatchpoint (uint32_t hw_index) -{ - int kret = ReadDBG (false); - - const uint32_t num_hw_points = NumSupportedHardwareWatchpoints(); - if (kret == KERN_SUCCESS) - { - if (hw_index < num_hw_points) - { - dbg.wcr[hw_index] = 0; -// if (log) log->Printf ("RegisterContextDarwin_arm::ClearHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x WCR%u = 0x%8.8x", -// hw_index, -// hw_index, -// dbg.wvr[hw_index], -// hw_index, -// dbg.wcr[hw_index]); - - kret = WriteDBG(); - - if (kret == KERN_SUCCESS) - return true; - } - } - return false; -} - -#endif diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h deleted file mode 100644 index eba341c13cc1..000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h +++ /dev/null @@ -1,348 +0,0 @@ -//===-- RegisterContextDarwin_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_RegisterContextDarwin_arm_h_ -#define liblldb_RegisterContextDarwin_arm_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/lldb-private.h" -#include "lldb/Target/RegisterContext.h" - -// BCR address match type -#define BCR_M_IMVA_MATCH ((uint32_t)(0u << 21)) -#define BCR_M_CONTEXT_ID_MATCH ((uint32_t)(1u << 21)) -#define BCR_M_IMVA_MISMATCH ((uint32_t)(2u << 21)) -#define BCR_M_RESERVED ((uint32_t)(3u << 21)) - -// Link a BVR/BCR or WVR/WCR pair to another -#define E_ENABLE_LINKING ((uint32_t)(1u << 20)) - -// Byte Address Select -#define BAS_IMVA_PLUS_0 ((uint32_t)(1u << 5)) -#define BAS_IMVA_PLUS_1 ((uint32_t)(1u << 6)) -#define BAS_IMVA_PLUS_2 ((uint32_t)(1u << 7)) -#define BAS_IMVA_PLUS_3 ((uint32_t)(1u << 8)) -#define BAS_IMVA_0_1 ((uint32_t)(3u << 5)) -#define BAS_IMVA_2_3 ((uint32_t)(3u << 7)) -#define BAS_IMVA_ALL ((uint32_t)(0xfu << 5)) - -// Break only in privileged or user mode -#define S_RSVD ((uint32_t)(0u << 1)) -#define S_PRIV ((uint32_t)(1u << 1)) -#define S_USER ((uint32_t)(2u << 1)) -#define S_PRIV_USER ((S_PRIV) | (S_USER)) - -#define BCR_ENABLE ((uint32_t)(1u)) -#define WCR_ENABLE ((uint32_t)(1u)) - -// Watchpoint load/store -#define WCR_LOAD ((uint32_t)(1u << 3)) -#define WCR_STORE ((uint32_t)(1u << 4)) - -class RegisterContextDarwin_arm : public lldb_private::RegisterContext -{ -public: - - RegisterContextDarwin_arm(lldb_private::Thread &thread, uint32_t concrete_frame_idx); - - virtual - ~RegisterContextDarwin_arm(); - - virtual void - InvalidateAllRegisters (); - - virtual size_t - GetRegisterCount (); - - virtual const lldb_private::RegisterInfo * - GetRegisterInfoAtIndex (uint32_t reg); - - virtual size_t - GetRegisterSetCount (); - - virtual const lldb_private::RegisterSet * - GetRegisterSet (uint32_t set); - - virtual bool - ReadRegister (const lldb_private::RegisterInfo *reg_info, - lldb_private::RegisterValue ®_value); - - virtual bool - WriteRegister (const lldb_private::RegisterInfo *reg_info, - const lldb_private::RegisterValue ®_value); - - virtual bool - ReadAllRegisterValues (lldb::DataBufferSP &data_sp); - - virtual bool - WriteAllRegisterValues (const lldb::DataBufferSP &data_sp); - - virtual uint32_t - ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num); - - virtual uint32_t - NumSupportedHardwareBreakpoints (); - - virtual uint32_t - SetHardwareBreakpoint (lldb::addr_t addr, size_t size); - - virtual bool - ClearHardwareBreakpoint (uint32_t hw_idx); - - virtual uint32_t - NumSupportedHardwareWatchpoints (); - - virtual uint32_t - SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write); - - virtual bool - ClearHardwareWatchpoint (uint32_t hw_index); - - struct GPR - { - uint32_t r[16]; // R0-R15 - uint32_t cpsr; // CPSR - }; - - - struct FPU - { - union { - uint32_t s[32]; - uint64_t d[16]; - } floats; - uint32_t fpscr; - }; - -// struct NeonReg -// { -// uint8_t bytes[16]; -// }; -// -// struct VFPv3 -// { -// union { -// uint32_t s[32]; -// uint64_t d[32]; -// NeonReg q[16]; -// } v3; -// uint32_t fpscr; -// }; - - struct EXC - { - uint32_t exception; - uint32_t fsr; /* Fault status */ - uint32_t far; /* Virtual Fault Address */ - }; - - struct DBG - { - uint32_t bvr[16]; - uint32_t bcr[16]; - uint32_t wvr[16]; - uint32_t wcr[16]; - }; - - static void - LogDBGRegisters (lldb_private::Log *log, const DBG& dbg); - -protected: - - enum - { - GPRRegSet = 1, - FPURegSet = 2, - EXCRegSet = 3, - DBGRegSet = 4 - }; - - enum - { - GPRWordCount = sizeof(GPR)/sizeof(uint32_t), - FPUWordCount = sizeof(FPU)/sizeof(uint32_t), - EXCWordCount = sizeof(EXC)/sizeof(uint32_t), - DBGWordCount = sizeof(DBG)/sizeof(uint32_t) - }; - - enum - { - Read = 0, - Write = 1, - kNumErrors = 2 - }; - - GPR gpr; - FPU fpu; - EXC exc; - DBG dbg; - int gpr_errs[2]; // Read/Write errors - int fpu_errs[2]; // Read/Write errors - int exc_errs[2]; // Read/Write errors - int dbg_errs[2]; // Read/Write errors - - void - InvalidateAllRegisterStates() - { - SetError (GPRRegSet, Read, -1); - SetError (FPURegSet, Read, -1); - SetError (EXCRegSet, Read, -1); - } - - int - GetError (int flavor, uint32_t err_idx) const - { - if (err_idx < kNumErrors) - { - switch (flavor) - { - // When getting all errors, just OR all values together to see if - // we got any kind of error. - case GPRRegSet: return gpr_errs[err_idx]; - case FPURegSet: return fpu_errs[err_idx]; - case EXCRegSet: return exc_errs[err_idx]; - case DBGRegSet: return dbg_errs[err_idx]; - default: break; - } - } - return -1; - } - - bool - SetError (int flavor, uint32_t err_idx, int err) - { - if (err_idx < kNumErrors) - { - switch (flavor) - { - case GPRRegSet: - gpr_errs[err_idx] = err; - return true; - - case FPURegSet: - fpu_errs[err_idx] = err; - return true; - - case EXCRegSet: - exc_errs[err_idx] = err; - return true; - - case DBGRegSet: - exc_errs[err_idx] = err; - return true; - - default: break; - } - } - return false; - } - - bool - RegisterSetIsCached (int set) const - { - return GetError(set, Read) == 0; - } - - int - ReadGPR (bool force); - - int - ReadFPU (bool force); - - int - ReadEXC (bool force); - - int - ReadDBG (bool force); - - int - WriteGPR (); - - int - WriteFPU (); - - int - WriteEXC (); - - int - WriteDBG (); - - - // Subclasses override these to do the actual reading. - virtual int - DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr) - { - return -1; - } - - int - DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) - { - return -1; - } - - int - DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) - { - return -1; - } - - int - DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg) - { - return -1; - } - - int - DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) - { - return -1; - } - - int - DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) - { - return -1; - } - - int - DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) - { - return -1; - } - - int - DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg) - { - return -1; - } - - int - ReadRegisterSet (uint32_t set, bool force); - - int - WriteRegisterSet (uint32_t set); - - static uint32_t - GetRegisterNumber (uint32_t reg_kind, uint32_t reg_num); - - static int - GetSetForNativeRegNum (int reg_num); - - static size_t - GetRegisterInfosCount (); - - static const lldb_private::RegisterInfo * - GetRegisterInfos (); -}; - -#endif // liblldb_RegisterContextDarwin_arm_h_ diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp deleted file mode 100644 index f07dbffd1fff..000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp +++ /dev/null @@ -1,980 +0,0 @@ -//===-- RegisterContextDarwin_i386.cpp --------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - - -// C Includes -#include <stddef.h> // offsetof - -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" -#include "lldb/Host/Endian.h" -#include "llvm/Support/Compiler.h" - -// Support building against older versions of LLVM, this macro was added -// recently. -#ifndef LLVM_EXTENSION -#define LLVM_EXTENSION -#endif - -// Project includes -#include "RegisterContextDarwin_i386.h" - -using namespace lldb; -using namespace lldb_private; - -enum -{ - gpr_eax = 0, - gpr_ebx, - gpr_ecx, - gpr_edx, - gpr_edi, - gpr_esi, - gpr_ebp, - gpr_esp, - gpr_ss, - gpr_eflags, - gpr_eip, - gpr_cs, - gpr_ds, - gpr_es, - gpr_fs, - gpr_gs, - - fpu_fcw, - fpu_fsw, - fpu_ftw, - fpu_fop, - fpu_ip, - fpu_cs, - fpu_dp, - fpu_ds, - fpu_mxcsr, - fpu_mxcsrmask, - fpu_stmm0, - fpu_stmm1, - fpu_stmm2, - fpu_stmm3, - fpu_stmm4, - fpu_stmm5, - fpu_stmm6, - fpu_stmm7, - fpu_xmm0, - fpu_xmm1, - fpu_xmm2, - fpu_xmm3, - fpu_xmm4, - fpu_xmm5, - fpu_xmm6, - fpu_xmm7, - - exc_trapno, - exc_err, - exc_faultvaddr, - - k_num_registers, - - // Aliases - fpu_fctrl = fpu_fcw, - fpu_fstat = fpu_fsw, - fpu_ftag = fpu_ftw, - fpu_fiseg = fpu_cs, - fpu_fioff = fpu_ip, - fpu_foseg = fpu_ds, - fpu_fooff = fpu_dp -}; - -enum -{ - gcc_eax = 0, - gcc_ecx, - gcc_edx, - gcc_ebx, - gcc_ebp, - gcc_esp, - gcc_esi, - gcc_edi, - gcc_eip, - gcc_eflags -}; - -enum -{ - dwarf_eax = 0, - dwarf_ecx, - dwarf_edx, - dwarf_ebx, - dwarf_esp, - dwarf_ebp, - dwarf_esi, - dwarf_edi, - dwarf_eip, - dwarf_eflags, - dwarf_stmm0 = 11, - dwarf_stmm1, - dwarf_stmm2, - dwarf_stmm3, - dwarf_stmm4, - dwarf_stmm5, - dwarf_stmm6, - dwarf_stmm7, - dwarf_xmm0 = 21, - dwarf_xmm1, - dwarf_xmm2, - dwarf_xmm3, - dwarf_xmm4, - dwarf_xmm5, - dwarf_xmm6, - dwarf_xmm7 -}; - -enum -{ - gdb_eax = 0, - gdb_ecx = 1, - gdb_edx = 2, - gdb_ebx = 3, - gdb_esp = 4, - gdb_ebp = 5, - gdb_esi = 6, - gdb_edi = 7, - gdb_eip = 8, - gdb_eflags = 9, - gdb_cs = 10, - gdb_ss = 11, - gdb_ds = 12, - gdb_es = 13, - gdb_fs = 14, - gdb_gs = 15, - gdb_stmm0 = 16, - gdb_stmm1 = 17, - gdb_stmm2 = 18, - gdb_stmm3 = 19, - gdb_stmm4 = 20, - gdb_stmm5 = 21, - gdb_stmm6 = 22, - gdb_stmm7 = 23, - gdb_fctrl = 24, gdb_fcw = gdb_fctrl, - gdb_fstat = 25, gdb_fsw = gdb_fstat, - gdb_ftag = 26, gdb_ftw = gdb_ftag, - gdb_fiseg = 27, gdb_fpu_cs = gdb_fiseg, - gdb_fioff = 28, gdb_ip = gdb_fioff, - gdb_foseg = 29, gdb_fpu_ds = gdb_foseg, - gdb_fooff = 30, gdb_dp = gdb_fooff, - gdb_fop = 31, - gdb_xmm0 = 32, - gdb_xmm1 = 33, - gdb_xmm2 = 34, - gdb_xmm3 = 35, - gdb_xmm4 = 36, - gdb_xmm5 = 37, - gdb_xmm6 = 38, - gdb_xmm7 = 39, - gdb_mxcsr = 40, - gdb_mm0 = 41, - gdb_mm1 = 42, - gdb_mm2 = 43, - gdb_mm3 = 44, - gdb_mm4 = 45, - gdb_mm5 = 46, - gdb_mm6 = 47, - gdb_mm7 = 48 -}; - -RegisterContextDarwin_i386::RegisterContextDarwin_i386 (Thread &thread, uint32_t concrete_frame_idx) : - RegisterContext(thread, concrete_frame_idx), - gpr(), - fpu(), - exc() -{ - uint32_t i; - for (i=0; i<kNumErrors; i++) - { - gpr_errs[i] = -1; - fpu_errs[i] = -1; - exc_errs[i] = -1; - } -} - -RegisterContextDarwin_i386::~RegisterContextDarwin_i386() -{ -} - - - -#define GPR_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_i386::GPR, reg)) -#define FPU_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_i386::FPU, reg) + sizeof (RegisterContextDarwin_i386::GPR)) -#define EXC_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_i386::EXC, reg) + sizeof (RegisterContextDarwin_i386::GPR) + sizeof (RegisterContextDarwin_i386::FPU)) - -// These macros will auto define the register name, alt name, register size, -// register offset, encoding, format and native register. This ensures that -// the register state structures are defined correctly and have the correct -// sizes and offsets. -#define DEFINE_GPR(reg, alt) #reg, alt, sizeof(((RegisterContextDarwin_i386::GPR *)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, eFormatHex -#define DEFINE_FPU_UINT(reg) #reg, NULL, sizeof(((RegisterContextDarwin_i386::FPU *)NULL)->reg), FPU_OFFSET(reg), eEncodingUint, eFormatHex -#define DEFINE_FPU_VECT(reg, i) #reg#i, NULL, sizeof(((RegisterContextDarwin_i386::FPU *)NULL)->reg[i].bytes), FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_##reg##i, LLDB_INVALID_REGNUM, gdb_##reg##i, fpu_##reg##i }, NULL, NULL - -#define DEFINE_EXC(reg) #reg, NULL, sizeof(((RegisterContextDarwin_i386::EXC *)NULL)->reg), EXC_OFFSET(reg), eEncodingUint, eFormatHex -#define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_i386::GPR) + sizeof (RegisterContextDarwin_i386::FPU) + sizeof (RegisterContextDarwin_i386::EXC)) - -static RegisterInfo g_register_infos[] = -{ -// Macro auto defines most stuff GCC DWARF GENERIC GDB LLDB VALUE REGS INVALIDATE REGS -// =============================== ======================= =================== ========================= ================== ================= ========== =============== - { DEFINE_GPR(eax , NULL) , { gcc_eax , dwarf_eax , LLDB_INVALID_REGNUM , gdb_eax , gpr_eax }, NULL, NULL}, - { DEFINE_GPR(ebx , NULL) , { gcc_ebx , dwarf_ebx , LLDB_INVALID_REGNUM , gdb_ebx , gpr_ebx }, NULL, NULL}, - { DEFINE_GPR(ecx , NULL) , { gcc_ecx , dwarf_ecx , LLDB_INVALID_REGNUM , gdb_ecx , gpr_ecx }, NULL, NULL}, - { DEFINE_GPR(edx , NULL) , { gcc_edx , dwarf_edx , LLDB_INVALID_REGNUM , gdb_edx , gpr_edx }, NULL, NULL}, - { DEFINE_GPR(edi , NULL) , { gcc_edi , dwarf_edi , LLDB_INVALID_REGNUM , gdb_edi , gpr_edi }, NULL, NULL}, - { DEFINE_GPR(esi , NULL) , { gcc_esi , dwarf_esi , LLDB_INVALID_REGNUM , gdb_esi , gpr_esi }, NULL, NULL}, - { DEFINE_GPR(ebp , "fp") , { gcc_ebp , dwarf_ebp , LLDB_REGNUM_GENERIC_FP , gdb_ebp , gpr_ebp }, NULL, NULL}, - { DEFINE_GPR(esp , "sp") , { gcc_esp , dwarf_esp , LLDB_REGNUM_GENERIC_SP , gdb_esp , gpr_esp }, NULL, NULL}, - { DEFINE_GPR(ss , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_ss , gpr_ss }, NULL, NULL}, - { DEFINE_GPR(eflags , "flags") , { gcc_eflags , dwarf_eflags , LLDB_REGNUM_GENERIC_FLAGS , gdb_eflags , gpr_eflags }, NULL, NULL}, - { DEFINE_GPR(eip , "pc") , { gcc_eip , dwarf_eip , LLDB_REGNUM_GENERIC_PC , gdb_eip , gpr_eip }, NULL, NULL}, - { DEFINE_GPR(cs , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_cs , gpr_cs }, NULL, NULL}, - { DEFINE_GPR(ds , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_ds , gpr_ds }, NULL, NULL}, - { DEFINE_GPR(es , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_es , gpr_es }, NULL, NULL}, - { DEFINE_GPR(fs , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_fs , gpr_fs }, NULL, NULL}, - { DEFINE_GPR(gs , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_gs , gpr_gs }, NULL, NULL}, - - { DEFINE_FPU_UINT(fcw) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_fcw , fpu_fcw }, NULL, NULL}, - { DEFINE_FPU_UINT(fsw) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_fsw , fpu_fsw }, NULL, NULL}, - { DEFINE_FPU_UINT(ftw) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_ftw , fpu_ftw }, NULL, NULL}, - { DEFINE_FPU_UINT(fop) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_fop , fpu_fop }, NULL, NULL}, - { DEFINE_FPU_UINT(ip) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_ip , fpu_ip }, NULL, NULL}, - { DEFINE_FPU_UINT(cs) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_cs , fpu_cs }, NULL, NULL}, - { DEFINE_FPU_UINT(dp) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_dp , fpu_dp }, NULL, NULL}, - { DEFINE_FPU_UINT(ds) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_ds , fpu_ds }, NULL, NULL}, - { DEFINE_FPU_UINT(mxcsr) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_mxcsr , fpu_mxcsr }, NULL, NULL}, - { DEFINE_FPU_UINT(mxcsrmask) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_mxcsrmask}, NULL, NULL}, - { DEFINE_FPU_VECT(stmm,0) }, - { DEFINE_FPU_VECT(stmm,1) }, - { DEFINE_FPU_VECT(stmm,2) }, - { DEFINE_FPU_VECT(stmm,3) }, - { DEFINE_FPU_VECT(stmm,4) }, - { DEFINE_FPU_VECT(stmm,5) }, - { DEFINE_FPU_VECT(stmm,6) }, - { DEFINE_FPU_VECT(stmm,7) }, - { DEFINE_FPU_VECT(xmm,0) }, - { DEFINE_FPU_VECT(xmm,1) }, - { DEFINE_FPU_VECT(xmm,2) }, - { DEFINE_FPU_VECT(xmm,3) }, - { DEFINE_FPU_VECT(xmm,4) }, - { DEFINE_FPU_VECT(xmm,5) }, - { DEFINE_FPU_VECT(xmm,6) }, - { DEFINE_FPU_VECT(xmm,7) }, - - { DEFINE_EXC(trapno) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_trapno }, NULL, NULL}, - { DEFINE_EXC(err) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_err }, NULL, NULL}, - { DEFINE_EXC(faultvaddr) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_faultvaddr }, NULL, NULL} -}; - -static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo)); - -void -RegisterContextDarwin_i386::InvalidateAllRegisters () -{ - InvalidateAllRegisterStates(); -} - - -size_t -RegisterContextDarwin_i386::GetRegisterCount () -{ - assert(k_num_register_infos == k_num_registers); - return k_num_registers; -} - -const RegisterInfo * -RegisterContextDarwin_i386::GetRegisterInfoAtIndex (uint32_t reg) -{ - assert(k_num_register_infos == k_num_registers); - if (reg < k_num_registers) - return &g_register_infos[reg]; - return NULL; -} - -size_t -RegisterContextDarwin_i386::GetRegisterInfosCount () -{ - return k_num_register_infos; -} - -const RegisterInfo * -RegisterContextDarwin_i386::GetRegisterInfos () -{ - return g_register_infos; -} - - -// General purpose registers -static uint32_t -g_gpr_regnums[] = -{ - gpr_eax, - gpr_ebx, - gpr_ecx, - gpr_edx, - gpr_edi, - gpr_esi, - gpr_ebp, - gpr_esp, - gpr_ss, - gpr_eflags, - gpr_eip, - gpr_cs, - gpr_ds, - gpr_es, - gpr_fs, - gpr_gs -}; - -// Floating point registers -static uint32_t -g_fpu_regnums[] = -{ - fpu_fcw, - fpu_fsw, - fpu_ftw, - fpu_fop, - fpu_ip, - fpu_cs, - fpu_dp, - fpu_ds, - fpu_mxcsr, - fpu_mxcsrmask, - fpu_stmm0, - fpu_stmm1, - fpu_stmm2, - fpu_stmm3, - fpu_stmm4, - fpu_stmm5, - fpu_stmm6, - fpu_stmm7, - fpu_xmm0, - fpu_xmm1, - fpu_xmm2, - fpu_xmm3, - fpu_xmm4, - fpu_xmm5, - fpu_xmm6, - fpu_xmm7 -}; - -// Exception registers - -static uint32_t -g_exc_regnums[] = -{ - exc_trapno, - exc_err, - exc_faultvaddr -}; - -// Number of registers in each register set -const size_t k_num_gpr_registers = sizeof(g_gpr_regnums) / sizeof(uint32_t); -const size_t k_num_fpu_registers = sizeof(g_fpu_regnums) / sizeof(uint32_t); -const size_t k_num_exc_registers = sizeof(g_exc_regnums) / sizeof(uint32_t); - -//---------------------------------------------------------------------- -// Register set definitions. The first definitions at register set index -// of zero is for all registers, followed by other registers sets. The -// register information for the all register set need not be filled in. -//---------------------------------------------------------------------- -static const RegisterSet g_reg_sets[] = -{ - { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, }, - { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums }, - { "Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums } -}; - -const size_t k_num_regsets = sizeof(g_reg_sets) / sizeof(RegisterSet); - - -size_t -RegisterContextDarwin_i386::GetRegisterSetCount () -{ - return k_num_regsets; -} - -const RegisterSet * -RegisterContextDarwin_i386::GetRegisterSet (uint32_t reg_set) -{ - if (reg_set < k_num_regsets) - return &g_reg_sets[reg_set]; - return NULL; -} - - -//---------------------------------------------------------------------- -// Register information definitions for 32 bit i386. -//---------------------------------------------------------------------- -int -RegisterContextDarwin_i386::GetSetForNativeRegNum (int reg_num) -{ - if (reg_num < fpu_fcw) - return GPRRegSet; - else if (reg_num < exc_trapno) - return FPURegSet; - else if (reg_num < k_num_registers) - return EXCRegSet; - return -1; -} - - -void -RegisterContextDarwin_i386::LogGPR(Log *log, const char *title) -{ - if (log) - { - if (title) - log->Printf ("%s", title); - for (uint32_t i=0; i<k_num_gpr_registers; i++) - { - uint32_t reg = gpr_eax + i; - log->Printf("%12s = 0x%8.8x", g_register_infos[reg].name, (&gpr.eax)[reg]); - } - } -} - - - -int -RegisterContextDarwin_i386::ReadGPR (bool force) -{ - int set = GPRRegSet; - if (force || !RegisterSetIsCached(set)) - { - SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr)); - } - return GetError(set, Read); -} - -int -RegisterContextDarwin_i386::ReadFPU (bool force) -{ - int set = FPURegSet; - if (force || !RegisterSetIsCached(set)) - { - SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu)); - } - return GetError(set, Read); -} - -int -RegisterContextDarwin_i386::ReadEXC (bool force) -{ - int set = EXCRegSet; - if (force || !RegisterSetIsCached(set)) - { - SetError(set, Read, DoReadEXC(GetThreadID(), set, exc)); - } - return GetError(set, Read); -} - -int -RegisterContextDarwin_i386::WriteGPR () -{ - int set = GPRRegSet; - if (!RegisterSetIsCached(set)) - { - SetError (set, Write, -1); - return -1; - } - SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr)); - SetError (set, Read, -1); - return GetError(set, Write); -} - -int -RegisterContextDarwin_i386::WriteFPU () -{ - int set = FPURegSet; - if (!RegisterSetIsCached(set)) - { - SetError (set, Write, -1); - return -1; - } - SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu)); - SetError (set, Read, -1); - return GetError(set, Write); -} - -int -RegisterContextDarwin_i386::WriteEXC () -{ - int set = EXCRegSet; - if (!RegisterSetIsCached(set)) - { - SetError (set, Write, -1); - return -1; - } - SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc)); - SetError (set, Read, -1); - return GetError(set, Write); -} - -int -RegisterContextDarwin_i386::ReadRegisterSet (uint32_t set, bool force) -{ - switch (set) - { - case GPRRegSet: return ReadGPR(force); - case FPURegSet: return ReadFPU(force); - case EXCRegSet: return ReadEXC(force); - default: break; - } - return -1; -} - -int -RegisterContextDarwin_i386::WriteRegisterSet (uint32_t set) -{ - // Make sure we have a valid context to set. - if (RegisterSetIsCached(set)) - { - switch (set) - { - case GPRRegSet: return WriteGPR(); - case FPURegSet: return WriteFPU(); - case EXCRegSet: return WriteEXC(); - default: break; - } - } - return -1; -} - -bool -RegisterContextDarwin_i386::ReadRegister (const RegisterInfo *reg_info, - RegisterValue &value) -{ - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - int set = RegisterContextDarwin_i386::GetSetForNativeRegNum (reg); - - if (set == -1) - return false; - - if (ReadRegisterSet(set, false) != 0) - return false; - - switch (reg) - { - case gpr_eax: - case gpr_ebx: - case gpr_ecx: - case gpr_edx: - case gpr_edi: - case gpr_esi: - case gpr_ebp: - case gpr_esp: - case gpr_ss: - case gpr_eflags: - case gpr_eip: - case gpr_cs: - case gpr_ds: - case gpr_es: - case gpr_fs: - case gpr_gs: - value = (&gpr.eax)[reg - gpr_eax]; - break; - - case fpu_fcw: - value = fpu.fcw; - break; - - case fpu_fsw: - value = fpu.fsw; - break; - - case fpu_ftw: - value = fpu.ftw; - break; - - case fpu_fop: - value = fpu.fop; - break; - - case fpu_ip: - value = fpu.ip; - break; - - case fpu_cs: - value = fpu.cs; - break; - - case fpu_dp: - value = fpu.dp; - break; - - case fpu_ds: - value = fpu.ds; - break; - - case fpu_mxcsr: - value = fpu.mxcsr; - break; - - case fpu_mxcsrmask: - value = fpu.mxcsrmask; - break; - - case fpu_stmm0: - case fpu_stmm1: - case fpu_stmm2: - case fpu_stmm3: - case fpu_stmm4: - case fpu_stmm5: - case fpu_stmm6: - case fpu_stmm7: - // These values don't fit into scalar types, - // RegisterContext::ReadRegisterBytes() must be used for these - // registers - //::memcpy (reg_value.value.vector.uint8, fpu.stmm[reg - fpu_stmm0].bytes, 10); - return false; - - case fpu_xmm0: - case fpu_xmm1: - case fpu_xmm2: - case fpu_xmm3: - case fpu_xmm4: - case fpu_xmm5: - case fpu_xmm6: - case fpu_xmm7: - // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes() - // must be used for these registers - //::memcpy (reg_value.value.vector.uint8, fpu.xmm[reg - fpu_xmm0].bytes, 16); - return false; - - case exc_trapno: - value = exc.trapno; - break; - - case exc_err: - value = exc.err; - break; - - case exc_faultvaddr: - value = exc.faultvaddr; - break; - - default: - return false; - } - return true; -} - - -bool -RegisterContextDarwin_i386::WriteRegister (const RegisterInfo *reg_info, - const RegisterValue &value) -{ - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - int set = GetSetForNativeRegNum (reg); - - if (set == -1) - return false; - - if (ReadRegisterSet(set, false) != 0) - return false; - - switch (reg) - { - case gpr_eax: - case gpr_ebx: - case gpr_ecx: - case gpr_edx: - case gpr_edi: - case gpr_esi: - case gpr_ebp: - case gpr_esp: - case gpr_ss: - case gpr_eflags: - case gpr_eip: - case gpr_cs: - case gpr_ds: - case gpr_es: - case gpr_fs: - case gpr_gs: - (&gpr.eax)[reg - gpr_eax] = value.GetAsUInt32(); - break; - - case fpu_fcw: - fpu.fcw = value.GetAsUInt16(); - break; - - case fpu_fsw: - fpu.fsw = value.GetAsUInt16(); - break; - - case fpu_ftw: - fpu.ftw = value.GetAsUInt8(); - break; - - case fpu_fop: - fpu.fop = value.GetAsUInt16(); - break; - - case fpu_ip: - fpu.ip = value.GetAsUInt32(); - break; - - case fpu_cs: - fpu.cs = value.GetAsUInt16(); - break; - - case fpu_dp: - fpu.dp = value.GetAsUInt32(); - break; - - case fpu_ds: - fpu.ds = value.GetAsUInt16(); - break; - - case fpu_mxcsr: - fpu.mxcsr = value.GetAsUInt32(); - break; - - case fpu_mxcsrmask: - fpu.mxcsrmask = value.GetAsUInt32(); - break; - - case fpu_stmm0: - case fpu_stmm1: - case fpu_stmm2: - case fpu_stmm3: - case fpu_stmm4: - case fpu_stmm5: - case fpu_stmm6: - case fpu_stmm7: - // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes() - // must be used for these registers - ::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize()); - return false; - - case fpu_xmm0: - case fpu_xmm1: - case fpu_xmm2: - case fpu_xmm3: - case fpu_xmm4: - case fpu_xmm5: - case fpu_xmm6: - case fpu_xmm7: - // These values don't fit into scalar types, RegisterContext::ReadRegisterBytes() - // must be used for these registers - ::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize()); - return false; - - case exc_trapno: - exc.trapno = value.GetAsUInt32(); - break; - - case exc_err: - exc.err = value.GetAsUInt32(); - break; - - case exc_faultvaddr: - exc.faultvaddr = value.GetAsUInt32(); - break; - - default: - return false; - } - return WriteRegisterSet(set) == 0; -} - -bool -RegisterContextDarwin_i386::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) -{ - data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0)); - if (data_sp && - ReadGPR (false) == 0 && - ReadFPU (false) == 0 && - ReadEXC (false) == 0) - { - uint8_t *dst = data_sp->GetBytes(); - ::memcpy (dst, &gpr, sizeof(gpr)); - dst += sizeof(gpr); - - ::memcpy (dst, &fpu, sizeof(fpu)); - dst += sizeof(gpr); - - ::memcpy (dst, &exc, sizeof(exc)); - return true; - } - return false; -} - -bool -RegisterContextDarwin_i386::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) -{ - if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) - { - const uint8_t *src = data_sp->GetBytes(); - ::memcpy (&gpr, src, sizeof(gpr)); - src += sizeof(gpr); - - ::memcpy (&fpu, src, sizeof(fpu)); - src += sizeof(gpr); - - ::memcpy (&exc, src, sizeof(exc)); - uint32_t success_count = 0; - if (WriteGPR() == 0) - ++success_count; - if (WriteFPU() == 0) - ++success_count; - if (WriteEXC() == 0) - ++success_count; - return success_count == 3; - } - return false; -} - - -uint32_t -RegisterContextDarwin_i386::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t reg) -{ - if (kind == eRegisterKindGeneric) - { - switch (reg) - { - case LLDB_REGNUM_GENERIC_PC: return gpr_eip; - case LLDB_REGNUM_GENERIC_SP: return gpr_esp; - case LLDB_REGNUM_GENERIC_FP: return gpr_ebp; - case LLDB_REGNUM_GENERIC_FLAGS: return gpr_eflags; - case LLDB_REGNUM_GENERIC_RA: - default: - break; - } - } - else if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF) - { - switch (reg) - { - case dwarf_eax: return gpr_eax; - case dwarf_ecx: return gpr_ecx; - case dwarf_edx: return gpr_edx; - case dwarf_ebx: return gpr_ebx; - case dwarf_esp: return gpr_esp; - case dwarf_ebp: return gpr_ebp; - case dwarf_esi: return gpr_esi; - case dwarf_edi: return gpr_edi; - case dwarf_eip: return gpr_eip; - case dwarf_eflags: return gpr_eflags; - case dwarf_stmm0: return fpu_stmm0; - case dwarf_stmm1: return fpu_stmm1; - case dwarf_stmm2: return fpu_stmm2; - case dwarf_stmm3: return fpu_stmm3; - case dwarf_stmm4: return fpu_stmm4; - case dwarf_stmm5: return fpu_stmm5; - case dwarf_stmm6: return fpu_stmm6; - case dwarf_stmm7: return fpu_stmm7; - case dwarf_xmm0: return fpu_xmm0; - case dwarf_xmm1: return fpu_xmm1; - case dwarf_xmm2: return fpu_xmm2; - case dwarf_xmm3: return fpu_xmm3; - case dwarf_xmm4: return fpu_xmm4; - case dwarf_xmm5: return fpu_xmm5; - case dwarf_xmm6: return fpu_xmm6; - case dwarf_xmm7: return fpu_xmm7; - default: - break; - } - } - else if (kind == eRegisterKindGDB) - { - switch (reg) - { - case gdb_eax : return gpr_eax; - case gdb_ebx : return gpr_ebx; - case gdb_ecx : return gpr_ecx; - case gdb_edx : return gpr_edx; - case gdb_esi : return gpr_esi; - case gdb_edi : return gpr_edi; - case gdb_ebp : return gpr_ebp; - case gdb_esp : return gpr_esp; - case gdb_eip : return gpr_eip; - case gdb_eflags : return gpr_eflags; - case gdb_cs : return gpr_cs; - case gdb_ss : return gpr_ss; - case gdb_ds : return gpr_ds; - case gdb_es : return gpr_es; - case gdb_fs : return gpr_fs; - case gdb_gs : return gpr_gs; - case gdb_stmm0 : return fpu_stmm0; - case gdb_stmm1 : return fpu_stmm1; - case gdb_stmm2 : return fpu_stmm2; - case gdb_stmm3 : return fpu_stmm3; - case gdb_stmm4 : return fpu_stmm4; - case gdb_stmm5 : return fpu_stmm5; - case gdb_stmm6 : return fpu_stmm6; - case gdb_stmm7 : return fpu_stmm7; - case gdb_fctrl : return fpu_fctrl; - case gdb_fstat : return fpu_fstat; - case gdb_ftag : return fpu_ftag; - case gdb_fiseg : return fpu_fiseg; - case gdb_fioff : return fpu_fioff; - case gdb_foseg : return fpu_foseg; - case gdb_fooff : return fpu_fooff; - case gdb_fop : return fpu_fop; - case gdb_xmm0 : return fpu_xmm0; - case gdb_xmm1 : return fpu_xmm1; - case gdb_xmm2 : return fpu_xmm2; - case gdb_xmm3 : return fpu_xmm3; - case gdb_xmm4 : return fpu_xmm4; - case gdb_xmm5 : return fpu_xmm5; - case gdb_xmm6 : return fpu_xmm6; - case gdb_xmm7 : return fpu_xmm7; - case gdb_mxcsr : return fpu_mxcsr; - default: - break; - } - } - else if (kind == eRegisterKindLLDB) - { - return reg; - } - return LLDB_INVALID_REGNUM; -} - - -bool -RegisterContextDarwin_i386::HardwareSingleStep (bool enable) -{ - if (ReadGPR(false) != 0) - return false; - - const uint32_t trace_bit = 0x100u; - if (enable) - { - // If the trace bit is already set, there is nothing to do - if (gpr.eflags & trace_bit) - return true; - else - gpr.eflags |= trace_bit; - } - else - { - // If the trace bit is already cleared, there is nothing to do - if (gpr.eflags & trace_bit) - gpr.eflags &= ~trace_bit; - else - return true; - } - - return WriteGPR() == 0; -} - - - diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h deleted file mode 100644 index 773aa627cd8e..000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h +++ /dev/null @@ -1,287 +0,0 @@ -//===-- RegisterContextDarwin_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_RegisterContextDarwin_i386_h_ -#define liblldb_RegisterContextDarwin_i386_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/lldb-private.h" -#include "lldb/Target/RegisterContext.h" - -class RegisterContextDarwin_i386 : public lldb_private::RegisterContext -{ -public: - - RegisterContextDarwin_i386(lldb_private::Thread &thread, - uint32_t concrete_frame_idx); - - virtual - ~RegisterContextDarwin_i386(); - - virtual void - InvalidateAllRegisters (); - - virtual size_t - GetRegisterCount (); - - virtual const lldb_private::RegisterInfo * - GetRegisterInfoAtIndex (uint32_t reg); - - virtual size_t - GetRegisterSetCount (); - - virtual const lldb_private::RegisterSet * - GetRegisterSet (uint32_t set); - - virtual bool - ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value); - - virtual bool - WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value); - - virtual bool - ReadAllRegisterValues (lldb::DataBufferSP &data_sp); - - virtual bool - WriteAllRegisterValues (const lldb::DataBufferSP &data_sp); - - virtual uint32_t - ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num); - - virtual bool - HardwareSingleStep (bool enable); - - struct GPR - { - uint32_t eax; - uint32_t ebx; - uint32_t ecx; - uint32_t edx; - uint32_t edi; - uint32_t esi; - uint32_t ebp; - uint32_t esp; - uint32_t ss; - uint32_t eflags; - uint32_t eip; - uint32_t cs; - uint32_t ds; - uint32_t es; - uint32_t fs; - uint32_t gs; - }; - - struct MMSReg - { - uint8_t bytes[10]; - uint8_t pad[6]; - }; - - struct XMMReg - { - uint8_t bytes[16]; - }; - - struct FPU - { - uint32_t pad[2]; - uint16_t fcw; - uint16_t fsw; - uint8_t ftw; - uint8_t pad1; - uint16_t fop; - uint32_t ip; - uint16_t cs; - uint16_t pad2; - uint32_t dp; - uint16_t ds; - uint16_t pad3; - uint32_t mxcsr; - uint32_t mxcsrmask; - MMSReg stmm[8]; - XMMReg xmm[8]; - uint8_t pad4[14*16]; - int pad5; - }; - - struct EXC - { - uint32_t trapno; - uint32_t err; - uint32_t faultvaddr; - }; - -protected: - - enum - { - GPRRegSet = 1, - FPURegSet = 2, - EXCRegSet = 3 - }; - - enum - { - GPRWordCount = sizeof(GPR)/sizeof(uint32_t), - FPUWordCount = sizeof(FPU)/sizeof(uint32_t), - EXCWordCount = sizeof(EXC)/sizeof(uint32_t) - }; - - enum - { - Read = 0, - Write = 1, - kNumErrors = 2 - }; - - GPR gpr; - FPU fpu; - EXC exc; - int gpr_errs[2]; // Read/Write errors - int fpu_errs[2]; // Read/Write errors - int exc_errs[2]; // Read/Write errors - - void - InvalidateAllRegisterStates() - { - SetError (GPRRegSet, Read, -1); - SetError (FPURegSet, Read, -1); - SetError (EXCRegSet, Read, -1); - } - - int - GetError (int flavor, uint32_t err_idx) const - { - if (err_idx < kNumErrors) - { - switch (flavor) - { - // When getting all errors, just OR all values together to see if - // we got any kind of error. - case GPRRegSet: return gpr_errs[err_idx]; - case FPURegSet: return fpu_errs[err_idx]; - case EXCRegSet: return exc_errs[err_idx]; - default: break; - } - } - return -1; - } - - bool - SetError (int flavor, uint32_t err_idx, int err) - { - if (err_idx < kNumErrors) - { - switch (flavor) - { - case GPRRegSet: - gpr_errs[err_idx] = err; - return true; - - case FPURegSet: - fpu_errs[err_idx] = err; - return true; - - case EXCRegSet: - exc_errs[err_idx] = err; - return true; - - default: break; - } - } - return false; - } - - bool - RegisterSetIsCached (int set) const - { - return GetError(set, Read) == 0; - } - - void - LogGPR (lldb_private::Log *log, const char *title); - - int - ReadGPR (bool force); - - int - ReadFPU (bool force); - - int - ReadEXC (bool force); - - int - WriteGPR (); - - int - WriteFPU (); - - int - WriteEXC (); - - // Subclasses override these to do the actual reading. - virtual int - DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr) - { - return -1; - } - - int - DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) - { - return -1; - } - - int - DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) - { - return -1; - } - - int - DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) - { - return -1; - } - - int - DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) - { - return -1; - } - - int - DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) - { - return -1; - } - - int - ReadRegisterSet (uint32_t set, bool force); - - int - WriteRegisterSet (uint32_t set); - - static uint32_t - GetRegisterNumber (uint32_t reg_kind, uint32_t reg_num); - - static int - GetSetForNativeRegNum (int reg_num); - - static size_t - GetRegisterInfosCount (); - - static const lldb_private::RegisterInfo * - GetRegisterInfos (); -}; - -#endif // liblldb_RegisterContextDarwin_i386_h_ diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp deleted file mode 100644 index 773154b16026..000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp +++ /dev/null @@ -1,1066 +0,0 @@ -//===-- RegisterContextDarwin_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. -// -//===----------------------------------------------------------------------===// - - -// C Includes -#include <stdarg.h> -#include <stddef.h> // offsetof - -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" -#include "lldb/Host/Endian.h" -#include "llvm/Support/Compiler.h" - -// Support building against older versions of LLVM, this macro was added -// recently. -#ifndef LLVM_EXTENSION -#define LLVM_EXTENSION -#endif - -// Project includes -#include "RegisterContextDarwin_x86_64.h" - -using namespace lldb; -using namespace lldb_private; - -enum -{ - gpr_rax = 0, - gpr_rbx, - gpr_rcx, - gpr_rdx, - gpr_rdi, - gpr_rsi, - gpr_rbp, - gpr_rsp, - gpr_r8, - gpr_r9, - gpr_r10, - gpr_r11, - gpr_r12, - gpr_r13, - gpr_r14, - gpr_r15, - gpr_rip, - gpr_rflags, - gpr_cs, - gpr_fs, - gpr_gs, - - fpu_fcw, - fpu_fsw, - fpu_ftw, - fpu_fop, - fpu_ip, - fpu_cs, - fpu_dp, - fpu_ds, - fpu_mxcsr, - fpu_mxcsrmask, - fpu_stmm0, - fpu_stmm1, - fpu_stmm2, - fpu_stmm3, - fpu_stmm4, - fpu_stmm5, - fpu_stmm6, - fpu_stmm7, - fpu_xmm0, - fpu_xmm1, - fpu_xmm2, - fpu_xmm3, - fpu_xmm4, - fpu_xmm5, - fpu_xmm6, - fpu_xmm7, - fpu_xmm8, - fpu_xmm9, - fpu_xmm10, - fpu_xmm11, - fpu_xmm12, - fpu_xmm13, - fpu_xmm14, - fpu_xmm15, - - exc_trapno, - exc_err, - exc_faultvaddr, - - k_num_registers, - - // Aliases - fpu_fctrl = fpu_fcw, - fpu_fstat = fpu_fsw, - fpu_ftag = fpu_ftw, - fpu_fiseg = fpu_cs, - fpu_fioff = fpu_ip, - fpu_foseg = fpu_ds, - fpu_fooff = fpu_dp -}; - -enum gcc_dwarf_regnums -{ - gcc_dwarf_gpr_rax = 0, - gcc_dwarf_gpr_rdx, - gcc_dwarf_gpr_rcx, - gcc_dwarf_gpr_rbx, - gcc_dwarf_gpr_rsi, - gcc_dwarf_gpr_rdi, - gcc_dwarf_gpr_rbp, - gcc_dwarf_gpr_rsp, - gcc_dwarf_gpr_r8, - gcc_dwarf_gpr_r9, - gcc_dwarf_gpr_r10, - gcc_dwarf_gpr_r11, - gcc_dwarf_gpr_r12, - gcc_dwarf_gpr_r13, - gcc_dwarf_gpr_r14, - gcc_dwarf_gpr_r15, - gcc_dwarf_gpr_rip, - gcc_dwarf_fpu_xmm0, - gcc_dwarf_fpu_xmm1, - gcc_dwarf_fpu_xmm2, - gcc_dwarf_fpu_xmm3, - gcc_dwarf_fpu_xmm4, - gcc_dwarf_fpu_xmm5, - gcc_dwarf_fpu_xmm6, - gcc_dwarf_fpu_xmm7, - gcc_dwarf_fpu_xmm8, - gcc_dwarf_fpu_xmm9, - gcc_dwarf_fpu_xmm10, - gcc_dwarf_fpu_xmm11, - gcc_dwarf_fpu_xmm12, - gcc_dwarf_fpu_xmm13, - gcc_dwarf_fpu_xmm14, - gcc_dwarf_fpu_xmm15, - gcc_dwarf_fpu_stmm0, - gcc_dwarf_fpu_stmm1, - gcc_dwarf_fpu_stmm2, - gcc_dwarf_fpu_stmm3, - gcc_dwarf_fpu_stmm4, - gcc_dwarf_fpu_stmm5, - gcc_dwarf_fpu_stmm6, - gcc_dwarf_fpu_stmm7 - -}; - -enum gdb_regnums -{ - gdb_gpr_rax = 0, - gdb_gpr_rbx = 1, - gdb_gpr_rcx = 2, - gdb_gpr_rdx = 3, - gdb_gpr_rsi = 4, - gdb_gpr_rdi = 5, - gdb_gpr_rbp = 6, - gdb_gpr_rsp = 7, - gdb_gpr_r8 = 8, - gdb_gpr_r9 = 9, - gdb_gpr_r10 = 10, - gdb_gpr_r11 = 11, - gdb_gpr_r12 = 12, - gdb_gpr_r13 = 13, - gdb_gpr_r14 = 14, - gdb_gpr_r15 = 15, - gdb_gpr_rip = 16, - gdb_gpr_rflags = 17, - gdb_gpr_cs = 18, - gdb_gpr_ss = 19, - gdb_gpr_ds = 20, - gdb_gpr_es = 21, - gdb_gpr_fs = 22, - gdb_gpr_gs = 23, - gdb_fpu_stmm0 = 24, - gdb_fpu_stmm1 = 25, - gdb_fpu_stmm2 = 26, - gdb_fpu_stmm3 = 27, - gdb_fpu_stmm4 = 28, - gdb_fpu_stmm5 = 29, - gdb_fpu_stmm6 = 30, - gdb_fpu_stmm7 = 31, - gdb_fpu_fctrl = 32, gdb_fpu_fcw = gdb_fpu_fctrl, - gdb_fpu_fstat = 33, gdb_fpu_fsw = gdb_fpu_fstat, - gdb_fpu_ftag = 34, gdb_fpu_ftw = gdb_fpu_ftag, - gdb_fpu_fiseg = 35, gdb_fpu_cs = gdb_fpu_fiseg, - gdb_fpu_fioff = 36, gdb_fpu_ip = gdb_fpu_fioff, - gdb_fpu_foseg = 37, gdb_fpu_ds = gdb_fpu_foseg, - gdb_fpu_fooff = 38, gdb_fpu_dp = gdb_fpu_fooff, - gdb_fpu_fop = 39, - gdb_fpu_xmm0 = 40, - gdb_fpu_xmm1 = 41, - gdb_fpu_xmm2 = 42, - gdb_fpu_xmm3 = 43, - gdb_fpu_xmm4 = 44, - gdb_fpu_xmm5 = 45, - gdb_fpu_xmm6 = 46, - gdb_fpu_xmm7 = 47, - gdb_fpu_xmm8 = 48, - gdb_fpu_xmm9 = 49, - gdb_fpu_xmm10 = 50, - gdb_fpu_xmm11 = 51, - gdb_fpu_xmm12 = 52, - gdb_fpu_xmm13 = 53, - gdb_fpu_xmm14 = 54, - gdb_fpu_xmm15 = 55, - gdb_fpu_mxcsr = 56 -}; - -RegisterContextDarwin_x86_64::RegisterContextDarwin_x86_64 (Thread &thread, uint32_t concrete_frame_idx) : - RegisterContext (thread, concrete_frame_idx), - gpr(), - fpu(), - exc() -{ - uint32_t i; - for (i=0; i<kNumErrors; i++) - { - gpr_errs[i] = -1; - fpu_errs[i] = -1; - exc_errs[i] = -1; - } -} - -RegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64() -{ -} - -#define GPR_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_x86_64::GPR, reg)) -#define FPU_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_x86_64::FPU, reg) + sizeof (RegisterContextDarwin_x86_64::GPR)) -#define EXC_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_x86_64::EXC, reg) + sizeof (RegisterContextDarwin_x86_64::GPR) + sizeof (RegisterContextDarwin_x86_64::FPU)) - -// These macros will auto define the register name, alt name, register size, -// register offset, encoding, format and native register. This ensures that -// the register state structures are defined correctly and have the correct -// sizes and offsets. -#define DEFINE_GPR(reg, alt) #reg, alt, sizeof(((RegisterContextDarwin_x86_64::GPR *)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, eFormatHex -#define DEFINE_FPU_UINT(reg) #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::FPU *)NULL)->reg), FPU_OFFSET(reg), eEncodingUint, eFormatHex -#define DEFINE_FPU_VECT(reg, i) #reg#i, NULL, sizeof(((RegisterContextDarwin_x86_64::FPU *)NULL)->reg[i].bytes), FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, { gcc_dwarf_fpu_##reg##i, gcc_dwarf_fpu_##reg##i, LLDB_INVALID_REGNUM, gdb_fpu_##reg##i, fpu_##reg##i }, NULL, NULL -#define DEFINE_EXC(reg) #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::EXC *)NULL)->reg), EXC_OFFSET(reg), eEncodingUint, eFormatHex - -#define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_x86_64::GPR) + sizeof (RegisterContextDarwin_x86_64::FPU) + sizeof (RegisterContextDarwin_x86_64::EXC)) - -// General purpose registers for 64 bit -static RegisterInfo g_register_infos[] = -{ -// Macro auto defines most stuff GCC DWARF GENERIC GDB LLDB VALUE REGS INVALIDATE REGS -// =============================== ====================== =================== ========================== ==================== =================== ========== =============== - { DEFINE_GPR (rax , NULL) , { gcc_dwarf_gpr_rax , gcc_dwarf_gpr_rax , LLDB_INVALID_REGNUM , gdb_gpr_rax , gpr_rax }, NULL, NULL}, - { DEFINE_GPR (rbx , NULL) , { gcc_dwarf_gpr_rbx , gcc_dwarf_gpr_rbx , LLDB_INVALID_REGNUM , gdb_gpr_rbx , gpr_rbx }, NULL, NULL}, - { DEFINE_GPR (rcx , NULL) , { gcc_dwarf_gpr_rcx , gcc_dwarf_gpr_rcx , LLDB_INVALID_REGNUM , gdb_gpr_rcx , gpr_rcx }, NULL, NULL}, - { DEFINE_GPR (rdx , NULL) , { gcc_dwarf_gpr_rdx , gcc_dwarf_gpr_rdx , LLDB_INVALID_REGNUM , gdb_gpr_rdx , gpr_rdx }, NULL, NULL}, - { DEFINE_GPR (rdi , NULL) , { gcc_dwarf_gpr_rdi , gcc_dwarf_gpr_rdi , LLDB_INVALID_REGNUM , gdb_gpr_rdi , gpr_rdi }, NULL, NULL}, - { DEFINE_GPR (rsi , NULL) , { gcc_dwarf_gpr_rsi , gcc_dwarf_gpr_rsi , LLDB_INVALID_REGNUM , gdb_gpr_rsi , gpr_rsi }, NULL, NULL}, - { DEFINE_GPR (rbp , "fp") , { gcc_dwarf_gpr_rbp , gcc_dwarf_gpr_rbp , LLDB_REGNUM_GENERIC_FP , gdb_gpr_rbp , gpr_rbp }, NULL, NULL}, - { DEFINE_GPR (rsp , "sp") , { gcc_dwarf_gpr_rsp , gcc_dwarf_gpr_rsp , LLDB_REGNUM_GENERIC_SP , gdb_gpr_rsp , gpr_rsp }, NULL, NULL}, - { DEFINE_GPR (r8 , NULL) , { gcc_dwarf_gpr_r8 , gcc_dwarf_gpr_r8 , LLDB_INVALID_REGNUM , gdb_gpr_r8 , gpr_r8 }, NULL, NULL}, - { DEFINE_GPR (r9 , NULL) , { gcc_dwarf_gpr_r9 , gcc_dwarf_gpr_r9 , LLDB_INVALID_REGNUM , gdb_gpr_r9 , gpr_r9 }, NULL, NULL}, - { DEFINE_GPR (r10 , NULL) , { gcc_dwarf_gpr_r10 , gcc_dwarf_gpr_r10 , LLDB_INVALID_REGNUM , gdb_gpr_r10 , gpr_r10 }, NULL, NULL}, - { DEFINE_GPR (r11 , NULL) , { gcc_dwarf_gpr_r11 , gcc_dwarf_gpr_r11 , LLDB_INVALID_REGNUM , gdb_gpr_r11 , gpr_r11 }, NULL, NULL}, - { DEFINE_GPR (r12 , NULL) , { gcc_dwarf_gpr_r12 , gcc_dwarf_gpr_r12 , LLDB_INVALID_REGNUM , gdb_gpr_r12 , gpr_r12 }, NULL, NULL}, - { DEFINE_GPR (r13 , NULL) , { gcc_dwarf_gpr_r13 , gcc_dwarf_gpr_r13 , LLDB_INVALID_REGNUM , gdb_gpr_r13 , gpr_r13 }, NULL, NULL}, - { DEFINE_GPR (r14 , NULL) , { gcc_dwarf_gpr_r14 , gcc_dwarf_gpr_r14 , LLDB_INVALID_REGNUM , gdb_gpr_r14 , gpr_r14 }, NULL, NULL}, - { DEFINE_GPR (r15 , NULL) , { gcc_dwarf_gpr_r15 , gcc_dwarf_gpr_r15 , LLDB_INVALID_REGNUM , gdb_gpr_r15 , gpr_r15 }, NULL, NULL}, - { DEFINE_GPR (rip , "pc") , { gcc_dwarf_gpr_rip , gcc_dwarf_gpr_rip , LLDB_REGNUM_GENERIC_PC , gdb_gpr_rip , gpr_rip }, NULL, NULL}, - { DEFINE_GPR (rflags, "flags") , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, gdb_gpr_rflags , gpr_rflags }, NULL, NULL}, - { DEFINE_GPR (cs , NULL) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_gpr_cs , gpr_cs }, NULL, NULL}, - { DEFINE_GPR (fs , NULL) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_gpr_fs , gpr_fs }, NULL, NULL}, - { DEFINE_GPR (gs , NULL) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_gpr_gs , gpr_gs }, NULL, NULL}, - - { DEFINE_FPU_UINT(fcw) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_fpu_fcw , fpu_fcw }, NULL, NULL}, - { DEFINE_FPU_UINT(fsw) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_fpu_fsw , fpu_fsw }, NULL, NULL}, - { DEFINE_FPU_UINT(ftw) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_fpu_ftw , fpu_ftw }, NULL, NULL}, - { DEFINE_FPU_UINT(fop) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_fpu_fop , fpu_fop }, NULL, NULL}, - { DEFINE_FPU_UINT(ip) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_fpu_ip , fpu_ip }, NULL, NULL}, - { DEFINE_FPU_UINT(cs) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_fpu_cs , fpu_cs }, NULL, NULL}, - { DEFINE_FPU_UINT(dp) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_fpu_dp , fpu_dp }, NULL, NULL}, - { DEFINE_FPU_UINT(ds) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_fpu_ds , fpu_ds }, NULL, NULL}, - { DEFINE_FPU_UINT(mxcsr) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_fpu_mxcsr , fpu_mxcsr }, NULL, NULL}, - { DEFINE_FPU_UINT(mxcsrmask) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_mxcsrmask }, NULL, NULL}, - { DEFINE_FPU_VECT(stmm,0) }, - { DEFINE_FPU_VECT(stmm,1) }, - { DEFINE_FPU_VECT(stmm,2) }, - { DEFINE_FPU_VECT(stmm,3) }, - { DEFINE_FPU_VECT(stmm,4) }, - { DEFINE_FPU_VECT(stmm,5) }, - { DEFINE_FPU_VECT(stmm,6) }, - { DEFINE_FPU_VECT(stmm,7) }, - { DEFINE_FPU_VECT(xmm,0) }, - { DEFINE_FPU_VECT(xmm,1) }, - { DEFINE_FPU_VECT(xmm,2) }, - { DEFINE_FPU_VECT(xmm,3) }, - { DEFINE_FPU_VECT(xmm,4) }, - { DEFINE_FPU_VECT(xmm,5) }, - { DEFINE_FPU_VECT(xmm,6) }, - { DEFINE_FPU_VECT(xmm,7) }, - { DEFINE_FPU_VECT(xmm,8) }, - { DEFINE_FPU_VECT(xmm,9) }, - { DEFINE_FPU_VECT(xmm,10) }, - { DEFINE_FPU_VECT(xmm,11) }, - { DEFINE_FPU_VECT(xmm,12) }, - { DEFINE_FPU_VECT(xmm,13) }, - { DEFINE_FPU_VECT(xmm,14) }, - { DEFINE_FPU_VECT(xmm,15) }, - - { DEFINE_EXC(trapno) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_trapno }, NULL, NULL}, - { DEFINE_EXC(err) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_err }, NULL, NULL}, - { DEFINE_EXC(faultvaddr) , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_faultvaddr }, NULL, NULL} -}; - -static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo)); - - -void -RegisterContextDarwin_x86_64::InvalidateAllRegisters () -{ - InvalidateAllRegisterStates(); -} - - -size_t -RegisterContextDarwin_x86_64::GetRegisterCount () -{ - assert(k_num_register_infos == k_num_registers); - return k_num_registers; -} - - -const RegisterInfo * -RegisterContextDarwin_x86_64::GetRegisterInfoAtIndex (uint32_t reg) -{ - assert(k_num_register_infos == k_num_registers); - if (reg < k_num_registers) - return &g_register_infos[reg]; - return NULL; -} - - -size_t -RegisterContextDarwin_x86_64::GetRegisterInfosCount () -{ - return k_num_register_infos; -} - -const lldb_private::RegisterInfo * -RegisterContextDarwin_x86_64::GetRegisterInfos () -{ - return g_register_infos; -} - - - -static uint32_t g_gpr_regnums[] = -{ - gpr_rax, - gpr_rbx, - gpr_rcx, - gpr_rdx, - gpr_rdi, - gpr_rsi, - gpr_rbp, - gpr_rsp, - gpr_r8, - gpr_r9, - gpr_r10, - gpr_r11, - gpr_r12, - gpr_r13, - gpr_r14, - gpr_r15, - gpr_rip, - gpr_rflags, - gpr_cs, - gpr_fs, - gpr_gs -}; - -static uint32_t g_fpu_regnums[] = -{ - fpu_fcw, - fpu_fsw, - fpu_ftw, - fpu_fop, - fpu_ip, - fpu_cs, - fpu_dp, - fpu_ds, - fpu_mxcsr, - fpu_mxcsrmask, - fpu_stmm0, - fpu_stmm1, - fpu_stmm2, - fpu_stmm3, - fpu_stmm4, - fpu_stmm5, - fpu_stmm6, - fpu_stmm7, - fpu_xmm0, - fpu_xmm1, - fpu_xmm2, - fpu_xmm3, - fpu_xmm4, - fpu_xmm5, - fpu_xmm6, - fpu_xmm7, - fpu_xmm8, - fpu_xmm9, - fpu_xmm10, - fpu_xmm11, - fpu_xmm12, - fpu_xmm13, - fpu_xmm14, - fpu_xmm15 -}; - -static uint32_t -g_exc_regnums[] = -{ - exc_trapno, - exc_err, - exc_faultvaddr -}; - -// Number of registers in each register set -const size_t k_num_gpr_registers = sizeof(g_gpr_regnums) / sizeof(uint32_t); -const size_t k_num_fpu_registers = sizeof(g_fpu_regnums) / sizeof(uint32_t); -const size_t k_num_exc_registers = sizeof(g_exc_regnums) / sizeof(uint32_t); - -//---------------------------------------------------------------------- -// Register set definitions. The first definitions at register set index -// of zero is for all registers, followed by other registers sets. The -// register information for the all register set need not be filled in. -//---------------------------------------------------------------------- -static const RegisterSet g_reg_sets[] = -{ - { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums, }, - { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums }, - { "Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums } -}; - -const size_t k_num_regsets = sizeof(g_reg_sets) / sizeof(RegisterSet); - - -size_t -RegisterContextDarwin_x86_64::GetRegisterSetCount () -{ - return k_num_regsets; -} - -const RegisterSet * -RegisterContextDarwin_x86_64::GetRegisterSet (uint32_t reg_set) -{ - if (reg_set < k_num_regsets) - return &g_reg_sets[reg_set]; - return NULL; -} - -int -RegisterContextDarwin_x86_64::GetSetForNativeRegNum (int reg_num) -{ - if (reg_num < fpu_fcw) - return GPRRegSet; - else if (reg_num < exc_trapno) - return FPURegSet; - else if (reg_num < k_num_registers) - return EXCRegSet; - return -1; -} - -void -RegisterContextDarwin_x86_64::LogGPR(Log *log, const char *format, ...) -{ - if (log) - { - if (format) - { - va_list args; - va_start (args, format); - log->VAPrintf (format, args); - va_end (args); - } - for (uint32_t i=0; i<k_num_gpr_registers; i++) - { - uint32_t reg = gpr_rax + i; - log->Printf("%12s = 0x%16.16llx", g_register_infos[reg].name, (&gpr.rax)[reg]); - } - } -} - -int -RegisterContextDarwin_x86_64::ReadGPR (bool force) -{ - int set = GPRRegSet; - if (force || !RegisterSetIsCached(set)) - { - SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr)); - } - return GetError(GPRRegSet, Read); -} - -int -RegisterContextDarwin_x86_64::ReadFPU (bool force) -{ - int set = FPURegSet; - if (force || !RegisterSetIsCached(set)) - { - SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu)); - } - return GetError(FPURegSet, Read); -} - -int -RegisterContextDarwin_x86_64::ReadEXC (bool force) -{ - int set = EXCRegSet; - if (force || !RegisterSetIsCached(set)) - { - SetError(set, Read, DoReadEXC(GetThreadID(), set, exc)); - } - return GetError(EXCRegSet, Read); -} - -int -RegisterContextDarwin_x86_64::WriteGPR () -{ - int set = GPRRegSet; - if (!RegisterSetIsCached(set)) - { - SetError (set, Write, -1); - return -1; - } - SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr)); - SetError (set, Read, -1); - return GetError (set, Write); -} - -int -RegisterContextDarwin_x86_64::WriteFPU () -{ - int set = FPURegSet; - if (!RegisterSetIsCached(set)) - { - SetError (set, Write, -1); - return -1; - } - SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu)); - SetError (set, Read, -1); - return GetError (set, Write); -} - -int -RegisterContextDarwin_x86_64::WriteEXC () -{ - int set = EXCRegSet; - if (!RegisterSetIsCached(set)) - { - SetError (set, Write, -1); - return -1; - } - SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc)); - SetError (set, Read, -1); - return GetError (set, Write); -} - -int -RegisterContextDarwin_x86_64::ReadRegisterSet(uint32_t set, bool force) -{ - switch (set) - { - case GPRRegSet: return ReadGPR (force); - case FPURegSet: return ReadFPU (force); - case EXCRegSet: return ReadEXC (force); - default: break; - } - return -1; -} - -int -RegisterContextDarwin_x86_64::WriteRegisterSet(uint32_t set) -{ - // Make sure we have a valid context to set. - switch (set) - { - case GPRRegSet: return WriteGPR (); - case FPURegSet: return WriteFPU (); - case EXCRegSet: return WriteEXC (); - default: break; - } - return -1; -} - - -bool -RegisterContextDarwin_x86_64::ReadRegister (const RegisterInfo *reg_info, - RegisterValue &value) -{ - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum (reg); - if (set == -1) - return false; - - if (ReadRegisterSet(set, false) != 0) - return false; - - switch (reg) - { - case gpr_rax: - case gpr_rbx: - case gpr_rcx: - case gpr_rdx: - case gpr_rdi: - case gpr_rsi: - case gpr_rbp: - case gpr_rsp: - case gpr_r8: - case gpr_r9: - case gpr_r10: - case gpr_r11: - case gpr_r12: - case gpr_r13: - case gpr_r14: - case gpr_r15: - case gpr_rip: - case gpr_rflags: - case gpr_cs: - case gpr_fs: - case gpr_gs: - value = (&gpr.rax)[reg - gpr_rax]; - break; - - case fpu_fcw: - value = fpu.fcw; - break; - - case fpu_fsw: - value = fpu.fsw; - break; - - case fpu_ftw: - value = fpu.ftw; - break; - - case fpu_fop: - value = fpu.fop; - break; - - case fpu_ip: - value = fpu.ip; - break; - - case fpu_cs: - value = fpu.cs; - break; - - case fpu_dp: - value = fpu.dp; - break; - - case fpu_ds: - value = fpu.ds; - break; - - case fpu_mxcsr: - value = fpu.mxcsr; - break; - - case fpu_mxcsrmask: - value = fpu.mxcsrmask; - break; - - case fpu_stmm0: - case fpu_stmm1: - case fpu_stmm2: - case fpu_stmm3: - case fpu_stmm4: - case fpu_stmm5: - case fpu_stmm6: - case fpu_stmm7: - value.SetBytes(fpu.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case fpu_xmm0: - case fpu_xmm1: - case fpu_xmm2: - case fpu_xmm3: - case fpu_xmm4: - case fpu_xmm5: - case fpu_xmm6: - case fpu_xmm7: - case fpu_xmm8: - case fpu_xmm9: - case fpu_xmm10: - case fpu_xmm11: - case fpu_xmm12: - case fpu_xmm13: - case fpu_xmm14: - case fpu_xmm15: - value.SetBytes(fpu.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder()); - break; - - case exc_trapno: - value = exc.trapno; - break; - - case exc_err: - value = exc.err; - break; - - case exc_faultvaddr: - value = exc.faultvaddr; - break; - - default: - return false; - } - return true; -} - - -bool -RegisterContextDarwin_x86_64::WriteRegister (const RegisterInfo *reg_info, - const RegisterValue &value) -{ - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum (reg); - - if (set == -1) - return false; - - if (ReadRegisterSet(set, false) != 0) - return false; - - switch (reg) - { - case gpr_rax: - case gpr_rbx: - case gpr_rcx: - case gpr_rdx: - case gpr_rdi: - case gpr_rsi: - case gpr_rbp: - case gpr_rsp: - case gpr_r8: - case gpr_r9: - case gpr_r10: - case gpr_r11: - case gpr_r12: - case gpr_r13: - case gpr_r14: - case gpr_r15: - case gpr_rip: - case gpr_rflags: - case gpr_cs: - case gpr_fs: - case gpr_gs: - (&gpr.rax)[reg - gpr_rax] = value.GetAsUInt64(); - break; - - case fpu_fcw: - fpu.fcw = value.GetAsUInt16(); - break; - - case fpu_fsw: - fpu.fsw = value.GetAsUInt16(); - break; - - case fpu_ftw: - fpu.ftw = value.GetAsUInt8(); - break; - - case fpu_fop: - fpu.fop = value.GetAsUInt16(); - break; - - case fpu_ip: - fpu.ip = value.GetAsUInt32(); - break; - - case fpu_cs: - fpu.cs = value.GetAsUInt16(); - break; - - case fpu_dp: - fpu.dp = value.GetAsUInt32(); - break; - - case fpu_ds: - fpu.ds = value.GetAsUInt16(); - break; - - case fpu_mxcsr: - fpu.mxcsr = value.GetAsUInt32(); - break; - - case fpu_mxcsrmask: - fpu.mxcsrmask = value.GetAsUInt32(); - break; - - case fpu_stmm0: - case fpu_stmm1: - case fpu_stmm2: - case fpu_stmm3: - case fpu_stmm4: - case fpu_stmm5: - case fpu_stmm6: - case fpu_stmm7: - ::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize()); - break; - - case fpu_xmm0: - case fpu_xmm1: - case fpu_xmm2: - case fpu_xmm3: - case fpu_xmm4: - case fpu_xmm5: - case fpu_xmm6: - case fpu_xmm7: - case fpu_xmm8: - case fpu_xmm9: - case fpu_xmm10: - case fpu_xmm11: - case fpu_xmm12: - case fpu_xmm13: - case fpu_xmm14: - case fpu_xmm15: - ::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize()); - return false; - - case exc_trapno: - exc.trapno = value.GetAsUInt32(); - break; - - case exc_err: - exc.err = value.GetAsUInt32(); - break; - - case exc_faultvaddr: - exc.faultvaddr = value.GetAsUInt64(); - break; - - default: - return false; - } - return WriteRegisterSet(set) == 0; -} - -bool -RegisterContextDarwin_x86_64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) -{ - data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0)); - if (data_sp && - ReadGPR (false) == 0 && - ReadFPU (false) == 0 && - ReadEXC (false) == 0) - { - uint8_t *dst = data_sp->GetBytes(); - ::memcpy (dst, &gpr, sizeof(gpr)); - dst += sizeof(gpr); - - ::memcpy (dst, &fpu, sizeof(fpu)); - dst += sizeof(gpr); - - ::memcpy (dst, &exc, sizeof(exc)); - return true; - } - return false; -} - -bool -RegisterContextDarwin_x86_64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) -{ - if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) - { - const uint8_t *src = data_sp->GetBytes(); - ::memcpy (&gpr, src, sizeof(gpr)); - src += sizeof(gpr); - - ::memcpy (&fpu, src, sizeof(fpu)); - src += sizeof(gpr); - - ::memcpy (&exc, src, sizeof(exc)); - uint32_t success_count = 0; - if (WriteGPR() == 0) - ++success_count; - if (WriteFPU() == 0) - ++success_count; - if (WriteEXC() == 0) - ++success_count; - return success_count == 3; - } - return false; -} - - -uint32_t -RegisterContextDarwin_x86_64::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t reg) -{ - if (kind == eRegisterKindGeneric) - { - switch (reg) - { - case LLDB_REGNUM_GENERIC_PC: return gpr_rip; - case LLDB_REGNUM_GENERIC_SP: return gpr_rsp; - case LLDB_REGNUM_GENERIC_FP: return gpr_rbp; - case LLDB_REGNUM_GENERIC_FLAGS: return gpr_rflags; - case LLDB_REGNUM_GENERIC_RA: - default: - break; - } - } - else if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF) - { - switch (reg) - { - case gcc_dwarf_gpr_rax: return gpr_rax; - case gcc_dwarf_gpr_rdx: return gpr_rdx; - case gcc_dwarf_gpr_rcx: return gpr_rcx; - case gcc_dwarf_gpr_rbx: return gpr_rbx; - case gcc_dwarf_gpr_rsi: return gpr_rsi; - case gcc_dwarf_gpr_rdi: return gpr_rdi; - case gcc_dwarf_gpr_rbp: return gpr_rbp; - case gcc_dwarf_gpr_rsp: return gpr_rsp; - case gcc_dwarf_gpr_r8: return gpr_r8; - case gcc_dwarf_gpr_r9: return gpr_r9; - case gcc_dwarf_gpr_r10: return gpr_r10; - case gcc_dwarf_gpr_r11: return gpr_r11; - case gcc_dwarf_gpr_r12: return gpr_r12; - case gcc_dwarf_gpr_r13: return gpr_r13; - case gcc_dwarf_gpr_r14: return gpr_r14; - case gcc_dwarf_gpr_r15: return gpr_r15; - case gcc_dwarf_gpr_rip: return gpr_rip; - case gcc_dwarf_fpu_xmm0: return fpu_xmm0; - case gcc_dwarf_fpu_xmm1: return fpu_xmm1; - case gcc_dwarf_fpu_xmm2: return fpu_xmm2; - case gcc_dwarf_fpu_xmm3: return fpu_xmm3; - case gcc_dwarf_fpu_xmm4: return fpu_xmm4; - case gcc_dwarf_fpu_xmm5: return fpu_xmm5; - case gcc_dwarf_fpu_xmm6: return fpu_xmm6; - case gcc_dwarf_fpu_xmm7: return fpu_xmm7; - case gcc_dwarf_fpu_xmm8: return fpu_xmm8; - case gcc_dwarf_fpu_xmm9: return fpu_xmm9; - case gcc_dwarf_fpu_xmm10: return fpu_xmm10; - case gcc_dwarf_fpu_xmm11: return fpu_xmm11; - case gcc_dwarf_fpu_xmm12: return fpu_xmm12; - case gcc_dwarf_fpu_xmm13: return fpu_xmm13; - case gcc_dwarf_fpu_xmm14: return fpu_xmm14; - case gcc_dwarf_fpu_xmm15: return fpu_xmm15; - case gcc_dwarf_fpu_stmm0: return fpu_stmm0; - case gcc_dwarf_fpu_stmm1: return fpu_stmm1; - case gcc_dwarf_fpu_stmm2: return fpu_stmm2; - case gcc_dwarf_fpu_stmm3: return fpu_stmm3; - case gcc_dwarf_fpu_stmm4: return fpu_stmm4; - case gcc_dwarf_fpu_stmm5: return fpu_stmm5; - case gcc_dwarf_fpu_stmm6: return fpu_stmm6; - case gcc_dwarf_fpu_stmm7: return fpu_stmm7; - default: - break; - } - } - else if (kind == eRegisterKindGDB) - { - switch (reg) - { - case gdb_gpr_rax : return gpr_rax; - case gdb_gpr_rbx : return gpr_rbx; - case gdb_gpr_rcx : return gpr_rcx; - case gdb_gpr_rdx : return gpr_rdx; - case gdb_gpr_rsi : return gpr_rsi; - case gdb_gpr_rdi : return gpr_rdi; - case gdb_gpr_rbp : return gpr_rbp; - case gdb_gpr_rsp : return gpr_rsp; - case gdb_gpr_r8 : return gpr_r8; - case gdb_gpr_r9 : return gpr_r9; - case gdb_gpr_r10 : return gpr_r10; - case gdb_gpr_r11 : return gpr_r11; - case gdb_gpr_r12 : return gpr_r12; - case gdb_gpr_r13 : return gpr_r13; - case gdb_gpr_r14 : return gpr_r14; - case gdb_gpr_r15 : return gpr_r15; - case gdb_gpr_rip : return gpr_rip; - case gdb_gpr_rflags : return gpr_rflags; - case gdb_gpr_cs : return gpr_cs; - case gdb_gpr_ss : return gpr_gs; // HACK: For now for "ss", just copy what is in "gs" - case gdb_gpr_ds : return gpr_gs; // HACK: For now for "ds", just copy what is in "gs" - case gdb_gpr_es : return gpr_gs; // HACK: For now for "es", just copy what is in "gs" - case gdb_gpr_fs : return gpr_fs; - case gdb_gpr_gs : return gpr_gs; - case gdb_fpu_stmm0 : return fpu_stmm0; - case gdb_fpu_stmm1 : return fpu_stmm1; - case gdb_fpu_stmm2 : return fpu_stmm2; - case gdb_fpu_stmm3 : return fpu_stmm3; - case gdb_fpu_stmm4 : return fpu_stmm4; - case gdb_fpu_stmm5 : return fpu_stmm5; - case gdb_fpu_stmm6 : return fpu_stmm6; - case gdb_fpu_stmm7 : return fpu_stmm7; - case gdb_fpu_fctrl : return fpu_fctrl; - case gdb_fpu_fstat : return fpu_fstat; - case gdb_fpu_ftag : return fpu_ftag; - case gdb_fpu_fiseg : return fpu_fiseg; - case gdb_fpu_fioff : return fpu_fioff; - case gdb_fpu_foseg : return fpu_foseg; - case gdb_fpu_fooff : return fpu_fooff; - case gdb_fpu_fop : return fpu_fop; - case gdb_fpu_xmm0 : return fpu_xmm0; - case gdb_fpu_xmm1 : return fpu_xmm1; - case gdb_fpu_xmm2 : return fpu_xmm2; - case gdb_fpu_xmm3 : return fpu_xmm3; - case gdb_fpu_xmm4 : return fpu_xmm4; - case gdb_fpu_xmm5 : return fpu_xmm5; - case gdb_fpu_xmm6 : return fpu_xmm6; - case gdb_fpu_xmm7 : return fpu_xmm7; - case gdb_fpu_xmm8 : return fpu_xmm8; - case gdb_fpu_xmm9 : return fpu_xmm9; - case gdb_fpu_xmm10 : return fpu_xmm10; - case gdb_fpu_xmm11 : return fpu_xmm11; - case gdb_fpu_xmm12 : return fpu_xmm12; - case gdb_fpu_xmm13 : return fpu_xmm13; - case gdb_fpu_xmm14 : return fpu_xmm14; - case gdb_fpu_xmm15 : return fpu_xmm15; - case gdb_fpu_mxcsr : return fpu_mxcsr; - default: - break; - } - } - else if (kind == eRegisterKindLLDB) - { - return reg; - } - return LLDB_INVALID_REGNUM; -} - -bool -RegisterContextDarwin_x86_64::HardwareSingleStep (bool enable) -{ - if (ReadGPR(true) != 0) - return false; - - const uint64_t trace_bit = 0x100ull; - if (enable) - { - - if (gpr.rflags & trace_bit) - return true; // trace bit is already set, there is nothing to do - else - gpr.rflags |= trace_bit; - } - else - { - if (gpr.rflags & trace_bit) - gpr.rflags &= ~trace_bit; - else - return true; // trace bit is clear, there is nothing to do - } - - return WriteGPR() == 0; -} - diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h deleted file mode 100644 index 8160cd0cc0ab..000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h +++ /dev/null @@ -1,292 +0,0 @@ -//===-- RegisterContextDarwin_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_RegisterContextDarwin_x86_64_h_ -#define liblldb_RegisterContextDarwin_x86_64_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/lldb-private.h" -#include "lldb/Target/RegisterContext.h" - -class RegisterContextDarwin_x86_64 : public lldb_private::RegisterContext -{ -public: - RegisterContextDarwin_x86_64 (lldb_private::Thread &thread, - uint32_t concrete_frame_idx); - - virtual - ~RegisterContextDarwin_x86_64(); - - virtual void - InvalidateAllRegisters (); - - virtual size_t - GetRegisterCount (); - - virtual const lldb_private::RegisterInfo * - GetRegisterInfoAtIndex (uint32_t reg); - - virtual size_t - GetRegisterSetCount (); - - virtual const lldb_private::RegisterSet * - GetRegisterSet (uint32_t set); - - virtual bool - ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value); - - virtual bool - WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value); - - virtual bool - ReadAllRegisterValues (lldb::DataBufferSP &data_sp); - - virtual bool - WriteAllRegisterValues (const lldb::DataBufferSP &data_sp); - - virtual uint32_t - ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num); - - virtual bool - HardwareSingleStep (bool enable); - - struct GPR - { - uint64_t rax; - uint64_t rbx; - uint64_t rcx; - uint64_t rdx; - uint64_t rdi; - uint64_t rsi; - uint64_t rbp; - uint64_t rsp; - uint64_t r8; - uint64_t r9; - uint64_t r10; - uint64_t r11; - uint64_t r12; - uint64_t r13; - uint64_t r14; - uint64_t r15; - uint64_t rip; - uint64_t rflags; - uint64_t cs; - uint64_t fs; - uint64_t gs; - }; - - struct MMSReg - { - uint8_t bytes[10]; - uint8_t pad[6]; - }; - - struct XMMReg - { - uint8_t bytes[16]; - }; - - struct FPU - { - uint32_t pad[2]; - uint16_t fcw; // "fctrl" - uint16_t fsw; // "fstat" - uint8_t ftw; // "ftag" - uint8_t pad1; - uint16_t fop; // "fop" - uint32_t ip; // "fioff" - uint16_t cs; // "fiseg" - uint16_t pad2; - uint32_t dp; // "fooff" - uint16_t ds; // "foseg" - uint16_t pad3; - uint32_t mxcsr; - uint32_t mxcsrmask; - MMSReg stmm[8]; - XMMReg xmm[16]; - uint8_t pad4[6*16]; - int pad5; - }; - - struct EXC - { - uint32_t trapno; - uint32_t err; - uint64_t faultvaddr; - }; - -protected: - - enum - { - GPRRegSet = 4, - FPURegSet = 5, - EXCRegSet = 6 - }; - - enum - { - GPRWordCount = sizeof(GPR)/sizeof(uint32_t), - FPUWordCount = sizeof(FPU)/sizeof(uint32_t), - EXCWordCount = sizeof(EXC)/sizeof(uint32_t) - }; - - enum - { - Read = 0, - Write = 1, - kNumErrors = 2 - }; - - GPR gpr; - FPU fpu; - EXC exc; - int gpr_errs[2]; // Read/Write errors - int fpu_errs[2]; // Read/Write errors - int exc_errs[2]; // Read/Write errors - - void - InvalidateAllRegisterStates() - { - SetError (GPRRegSet, Read, -1); - SetError (FPURegSet, Read, -1); - SetError (EXCRegSet, Read, -1); - } - - int - GetError (int flavor, uint32_t err_idx) const - { - if (err_idx < kNumErrors) - { - switch (flavor) - { - // When getting all errors, just OR all values together to see if - // we got any kind of error. - case GPRRegSet: return gpr_errs[err_idx]; - case FPURegSet: return fpu_errs[err_idx]; - case EXCRegSet: return exc_errs[err_idx]; - default: break; - } - } - return -1; - } - - bool - SetError (int flavor, uint32_t err_idx, int err) - { - if (err_idx < kNumErrors) - { - switch (flavor) - { - case GPRRegSet: - gpr_errs[err_idx] = err; - return true; - - case FPURegSet: - fpu_errs[err_idx] = err; - return true; - - case EXCRegSet: - exc_errs[err_idx] = err; - return true; - - default: break; - } - } - return false; - } - - bool - RegisterSetIsCached (int set) const - { - return GetError(set, Read) == 0; - } - - void - LogGPR (lldb_private::Log *log, const char *format, ...); - - int - ReadGPR (bool force); - - int - ReadFPU (bool force); - - int - ReadEXC (bool force); - - int - WriteGPR (); - - int - WriteFPU (); - - int - WriteEXC (); - - // Subclasses override these to do the actual reading. - virtual int - DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr) - { - return -1; - } - - virtual int - DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) - { - return -1; - } - - virtual int - DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) - { - return -1; - } - - virtual int - DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) - { - return -1; - } - - virtual int - DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) - { - return -1; - } - - virtual int - DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) - { - return -1; - } - - int - ReadRegisterSet (uint32_t set, bool force); - - int - WriteRegisterSet (uint32_t set); - - static uint32_t - GetRegisterNumber (uint32_t reg_kind, uint32_t reg_num); - - static int - GetSetForNativeRegNum (int reg_num); - - static size_t - GetRegisterInfosCount (); - - static const lldb_private::RegisterInfo * - GetRegisterInfos (); - -}; - -#endif // liblldb_RegisterContextDarwin_x86_64_h_ diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp deleted file mode 100644 index 10053dd760a4..000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ /dev/null @@ -1,1497 +0,0 @@ -//===-- RegisterContextLLDB.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/lldb-private.h" -#include "lldb/Core/Address.h" -#include "lldb/Core/AddressRange.h" -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Value.h" -#include "lldb/Symbol/FuncUnwinders.h" -#include "lldb/Symbol/Function.h" -#include "lldb/Symbol/SymbolContext.h" -#include "lldb/Symbol/Symbol.h" -#include "lldb/Expression/DWARFExpression.h" -#include "lldb/Target/ABI.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/StackFrame.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/Thread.h" -#include "lldb/Target/DynamicLoader.h" - -#include "RegisterContextLLDB.h" - -using namespace lldb; -using namespace lldb_private; - -RegisterContextLLDB::RegisterContextLLDB -( - Thread& thread, - const SharedPtr &next_frame, - SymbolContext& sym_ctx, - uint32_t frame_number, - UnwindLLDB& unwind_lldb -) : - RegisterContext (thread, frame_number), - m_thread(thread), - m_fast_unwind_plan_sp (), - m_full_unwind_plan_sp (), - m_all_registers_available(false), - m_frame_type (-1), - m_cfa (LLDB_INVALID_ADDRESS), - m_start_pc (), - m_current_pc (), - m_current_offset (0), - m_current_offset_backed_up_one (0), - m_sym_ctx(sym_ctx), - m_sym_ctx_valid (false), - m_frame_number (frame_number), - m_registers(), - m_parent_unwind (unwind_lldb) -{ - m_sym_ctx.Clear(); - m_sym_ctx_valid = false; - - if (IsFrameZero ()) - { - InitializeZerothFrame (); - } - else - { - InitializeNonZerothFrame (); - } - - // This same code exists over in the GetFullUnwindPlanForFrame() but it may not have been executed yet - if (IsFrameZero() - || next_frame->m_frame_type == eSigtrampFrame - || next_frame->m_frame_type == eDebuggerFrame) - { - m_all_registers_available = true; - } -} - -// Initialize a RegisterContextLLDB which is the first frame of a stack -- the zeroth frame or currently -// executing frame. - -void -RegisterContextLLDB::InitializeZerothFrame() -{ - ExecutionContext exe_ctx(m_thread.shared_from_this()); - RegisterContextSP reg_ctx_sp = m_thread.GetRegisterContext(); - - LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); - - if (reg_ctx_sp.get() == NULL) - { - m_frame_type = eNotAValidFrame; - return; - } - - addr_t current_pc = reg_ctx_sp->GetPC(); - - if (current_pc == LLDB_INVALID_ADDRESS) - { - m_frame_type = eNotAValidFrame; - return; - } - - Process *process = exe_ctx.GetProcessPtr(); - - // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs - // this will strip bit zero in case we read a PC from memory or from the LR. - // (which would be a no-op in frame 0 where we get it from the register set, - // but still a good idea to make the call here for other ABIs that may exist.) - ABI *abi = process->GetABI().get(); - if (abi) - current_pc = abi->FixCodeAddress(current_pc); - - // Initialize m_current_pc, an Address object, based on current_pc, an addr_t. - process->GetTarget().GetSectionLoadList().ResolveLoadAddress (current_pc, m_current_pc); - - // If we don't have a Module for some reason, we're not going to find symbol/function information - just - // stick in some reasonable defaults and hope we can unwind past this frame. - ModuleSP pc_module_sp (m_current_pc.GetModule()); - if (!m_current_pc.IsValid() || !pc_module_sp) - { - if (log) - { - log->Printf("%*sFrame %u using architectural default unwind method", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number); - } - } - - // We require that eSymbolContextSymbol be successfully filled in or this context is of no use to us. - if (pc_module_sp.get() - && (pc_module_sp->ResolveSymbolContextForAddress (m_current_pc, eSymbolContextFunction| eSymbolContextSymbol, m_sym_ctx) & eSymbolContextSymbol) == eSymbolContextSymbol) - { - m_sym_ctx_valid = true; - } - - AddressRange addr_range; - m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, addr_range); - - static ConstString g_sigtramp_name ("_sigtramp"); - if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == g_sigtramp_name) || - (m_sym_ctx.symbol && m_sym_ctx.symbol->GetName() == g_sigtramp_name)) - { - m_frame_type = eSigtrampFrame; - } - else - { - // FIXME: Detect eDebuggerFrame here. - m_frame_type = eNormalFrame; - } - - // If we were able to find a symbol/function, set addr_range to the bounds of that symbol/function. - // else treat the current pc value as the start_pc and record no offset. - if (addr_range.GetBaseAddress().IsValid()) - { - m_start_pc = addr_range.GetBaseAddress(); - if (m_current_pc.GetSection() == m_start_pc.GetSection()) - { - m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset(); - } - else if (m_current_pc.GetModule() == m_start_pc.GetModule()) - { - // This means that whatever symbol we kicked up isn't really correct - // --- we should not cross section boundaries ... We really should NULL out - // the function/symbol in this case unless there is a bad assumption - // here due to inlined functions? - m_current_offset = m_current_pc.GetFileAddress() - m_start_pc.GetFileAddress(); - } - m_current_offset_backed_up_one = m_current_offset; - } - else - { - m_start_pc = m_current_pc; - m_current_offset = -1; - m_current_offset_backed_up_one = -1; - } - - // We've set m_frame_type and m_sym_ctx before these calls. - - m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame (); - m_full_unwind_plan_sp = GetFullUnwindPlanForFrame (); - - const UnwindPlan::Row *active_row = NULL; - int cfa_offset = 0; - int row_register_kind; - if (m_full_unwind_plan_sp && m_full_unwind_plan_sp->PlanValidAtAddress (m_current_pc)) - { - active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); - row_register_kind = m_full_unwind_plan_sp->GetRegisterKind (); - if (active_row && log) - { - StreamString active_row_strm; - active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); - log->Printf("%*sFrame %u active row: %s", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, active_row_strm.GetString().c_str()); - } - } - - if (active_row == NULL) - { - m_frame_type = eNotAValidFrame; - return; - } - - - addr_t cfa_regval; - if (!ReadGPRValue (row_register_kind, active_row->GetCFARegister(), cfa_regval)) - { - m_frame_type = eNotAValidFrame; - return; - } - else - { - } - cfa_offset = active_row->GetCFAOffset (); - - m_cfa = cfa_regval + cfa_offset; - - if (log) - { - log->Printf("%*sFrame %u cfa_regval = 0x%16.16llx (cfa_regval = 0x%16.16llx, cfa_offset = %i)", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - m_cfa, cfa_regval, cfa_offset); - } - - if (log) - { - log->Printf("%*sThread %d Frame %u initialized frame current pc is 0x%llx cfa is 0x%llx using %s UnwindPlan", - m_frame_number < 100 ? m_frame_number : 100, "", - m_thread.GetIndexID(), - m_frame_number, - (uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()), - (uint64_t) m_cfa, - m_full_unwind_plan_sp->GetSourceName().GetCString()); - } -} - -// Initialize a RegisterContextLLDB for the non-zeroth frame -- rely on the RegisterContextLLDB "below" it -// to provide things like its current pc value. - -void -RegisterContextLLDB::InitializeNonZerothFrame() -{ - LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); - - if (IsFrameZero ()) - { - m_frame_type = eNotAValidFrame; - return; - } - - if (!GetNextFrame().get() || !GetNextFrame()->IsValid()) - { - m_frame_type = eNotAValidFrame; - return; - } - if (m_thread.GetRegisterContext() == NULL) - { - m_frame_type = eNotAValidFrame; - return; - } - - addr_t pc; - if (!ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) - { - if (log) - { - log->Printf("%*sFrame %u could not get pc value", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number); - } - m_frame_type = eNotAValidFrame; - return; - } - - if (log) - { - log->Printf("%*sFrame %u pc = 0x%16.16llx", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, pc); - addr_t reg_val; - if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val)) - log->Printf("%*sFrame %u fp = 0x%16.16llx", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, reg_val); - - if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val)) - log->Printf("%*sFrame %u sp = 0x%16.16llx", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, reg_val); - } - - // A pc of 0x0 means it's the end of the stack crawl - if (pc == 0) - { - m_frame_type = eNotAValidFrame; - return; - } - - ExecutionContext exe_ctx(m_thread.shared_from_this()); - Process *process = exe_ctx.GetProcessPtr(); - // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs - // this will strip bit zero in case we read a PC from memory or from the LR. - ABI *abi = process->GetABI().get(); - if (abi) - pc = abi->FixCodeAddress(pc); - - process->GetTarget().GetSectionLoadList().ResolveLoadAddress (pc, m_current_pc); - - // If we don't have a Module for some reason, we're not going to find symbol/function information - just - // stick in some reasonable defaults and hope we can unwind past this frame. - ModuleSP pc_module_sp (m_current_pc.GetModule()); - if (!m_current_pc.IsValid() || !pc_module_sp) - { - if (log) - { - log->Printf("%*sFrame %u using architectural default unwind method", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number); - } - - // Test the pc value to see if we know it's in an unmapped/non-executable region of memory. - uint32_t permissions; - if (process->GetLoadAddressPermissions(pc, permissions) - && (permissions & ePermissionsExecutable) == 0) - { - // If this is the second frame off the stack, we may have unwound the first frame - // incorrectly. But using the architecture default unwind plan may get us back on - // track -- albeit possibly skipping a real frame. Give this frame a clearly-invalid - // pc and see if we can get any further. - if (GetNextFrame().get() && GetNextFrame()->IsValid() && GetNextFrame()->IsFrameZero()) - { - if (log) - { - log->Printf("%*sFrame %u had a pc of 0x%llx which is not in executable memory but on frame 1 -- allowing it once.", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, (uint64_t) pc); - } - m_frame_type = eSkipFrame; - } - else - { - // anywhere other than the second frame, a non-executable pc means we're off in the weeds -- stop now. - m_frame_type = eNotAValidFrame; - return; - } - } - - if (abi) - { - m_fast_unwind_plan_sp.reset (); - m_full_unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); - abi->CreateDefaultUnwindPlan(*m_full_unwind_plan_sp); - if (m_frame_type != eSkipFrame) // don't override eSkipFrame - { - m_frame_type = eNormalFrame; - } - m_all_registers_available = false; - m_current_offset = -1; - m_current_offset_backed_up_one = -1; - addr_t cfa_regval; - int row_register_kind = m_full_unwind_plan_sp->GetRegisterKind (); - const UnwindPlan::Row *row = m_full_unwind_plan_sp->GetRowForFunctionOffset(0); - if (row) - { - uint32_t cfa_regnum = row->GetCFARegister(); - int cfa_offset = row->GetCFAOffset(); - if (!ReadGPRValue (row_register_kind, cfa_regnum, cfa_regval)) - { - if (log) - { - log->Printf("%*sFrame %u failed to get cfa value", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number); - } - if (m_frame_type != eSkipFrame) // don't override eSkipFrame - { - m_frame_type = eNormalFrame; - } - return; - } - m_cfa = cfa_regval + cfa_offset; - - // A couple of sanity checks.. - if (cfa_regval == LLDB_INVALID_ADDRESS || cfa_regval == 0 || cfa_regval == 1) - { - if (log) - { - log->Printf("%*sFrame %u could not find a valid cfa address", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number); - } - m_frame_type = eNotAValidFrame; - return; - } - - // cfa_regval should point into the stack memory; if we can query memory region permissions, - // see if the memory is allocated & readable. - if (process->GetLoadAddressPermissions(cfa_regval, permissions) - && (permissions & ePermissionsReadable) == 0) - { - m_frame_type = eNotAValidFrame; - return; - } - } - else - { - if (log) - { - log->Printf("%*sFrame %u could not find a row for function offset zero", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number); - } - m_frame_type = eNotAValidFrame; - return; - } - - if (log) - { - log->Printf("%*sFrame %u initialized frame cfa is 0x%llx", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - (uint64_t) m_cfa); - } - return; - } - m_frame_type = eNotAValidFrame; - return; - } - - // We require that eSymbolContextSymbol be successfully filled in or this context is of no use to us. - if ((pc_module_sp->ResolveSymbolContextForAddress (m_current_pc, eSymbolContextFunction| eSymbolContextSymbol, m_sym_ctx) & eSymbolContextSymbol) == eSymbolContextSymbol) - { - m_sym_ctx_valid = true; - } - - AddressRange addr_range; - if (!m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, addr_range)) - { - m_sym_ctx_valid = false; - } - - bool decr_pc_and_recompute_addr_range = false; - - // If the symbol lookup failed... - if (m_sym_ctx_valid == false) - decr_pc_and_recompute_addr_range = true; - - // Or if we're in the middle of the stack (and not "above" an asynchronous event like sigtramp), - // and our "current" pc is the start of a function... - if (m_sym_ctx_valid - && GetNextFrame()->m_frame_type != eSigtrampFrame - && GetNextFrame()->m_frame_type != eDebuggerFrame - && addr_range.GetBaseAddress().IsValid() - && addr_range.GetBaseAddress().GetSection() == m_current_pc.GetSection() - && addr_range.GetBaseAddress().GetOffset() == m_current_pc.GetOffset()) - { - decr_pc_and_recompute_addr_range = true; - } - - // We need to back up the pc by 1 byte and re-search for the Symbol to handle the case where the "saved pc" - // value is pointing to the next function, e.g. if a function ends with a CALL instruction. - // FIXME this may need to be an architectural-dependent behavior; if so we'll need to add a member function - // to the ABI plugin and consult that. - if (decr_pc_and_recompute_addr_range) - { - Address temporary_pc(m_current_pc); - temporary_pc.SetOffset(m_current_pc.GetOffset() - 1); - m_sym_ctx.Clear(); - m_sym_ctx_valid = false; - if ((pc_module_sp->ResolveSymbolContextForAddress (temporary_pc, eSymbolContextFunction| eSymbolContextSymbol, m_sym_ctx) & eSymbolContextSymbol) == eSymbolContextSymbol) - { - m_sym_ctx_valid = true; - } - if (!m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, addr_range)) - { - m_sym_ctx_valid = false; - } - } - - // If we were able to find a symbol/function, set addr_range_ptr to the bounds of that symbol/function. - // else treat the current pc value as the start_pc and record no offset. - if (addr_range.GetBaseAddress().IsValid()) - { - m_start_pc = addr_range.GetBaseAddress(); - m_current_offset = m_current_pc.GetOffset() - m_start_pc.GetOffset(); - m_current_offset_backed_up_one = m_current_offset; - if (decr_pc_and_recompute_addr_range && m_current_offset_backed_up_one > 0) - m_current_offset_backed_up_one--; - } - else - { - m_start_pc = m_current_pc; - m_current_offset = -1; - m_current_offset_backed_up_one = -1; - } - - static ConstString sigtramp_name ("_sigtramp"); - if ((m_sym_ctx.function && m_sym_ctx.function->GetMangled().GetMangledName() == sigtramp_name) - || (m_sym_ctx.symbol && m_sym_ctx.symbol->GetMangled().GetMangledName() == sigtramp_name)) - { - m_frame_type = eSigtrampFrame; - } - else - { - // FIXME: Detect eDebuggerFrame here. - if (m_frame_type != eSkipFrame) // don't override eSkipFrame - { - m_frame_type = eNormalFrame; - } - } - - // We've set m_frame_type and m_sym_ctx before this call. - m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame (); - - const UnwindPlan::Row *active_row = NULL; - int cfa_offset = 0; - int row_register_kind; - - // Try to get by with just the fast UnwindPlan if possible - the full UnwindPlan may be expensive to get - // (e.g. if we have to parse the entire eh_frame section of an ObjectFile for the first time.) - - if (m_fast_unwind_plan_sp && m_fast_unwind_plan_sp->PlanValidAtAddress (m_current_pc)) - { - active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); - row_register_kind = m_fast_unwind_plan_sp->GetRegisterKind (); - if (active_row && log) - { - StreamString active_row_strm; - active_row->Dump(active_row_strm, m_fast_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); - log->Printf("%*sFrame %u active row: %s", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, active_row_strm.GetString().c_str()); - } - } - else - { - m_full_unwind_plan_sp = GetFullUnwindPlanForFrame (); - if (m_full_unwind_plan_sp && m_full_unwind_plan_sp->PlanValidAtAddress (m_current_pc)) - { - active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); - row_register_kind = m_full_unwind_plan_sp->GetRegisterKind (); - if (active_row && log) - { - StreamString active_row_strm; - active_row->Dump(active_row_strm, m_full_unwind_plan_sp.get(), &m_thread, m_start_pc.GetLoadAddress(exe_ctx.GetTargetPtr())); - log->Printf("%*sFrame %u active row: %s", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, active_row_strm.GetString().c_str()); - } - } - } - - if (active_row == NULL) - { - m_frame_type = eNotAValidFrame; - return; - } - - addr_t cfa_regval; - if (!ReadGPRValue (row_register_kind, active_row->GetCFARegister(), cfa_regval)) - { - if (log) - { - log->Printf("%*sFrame %u failed to get cfa reg %d/%d", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - row_register_kind, active_row->GetCFARegister()); - } - m_frame_type = eNotAValidFrame; - return; - } - cfa_offset = active_row->GetCFAOffset (); - - m_cfa = cfa_regval + cfa_offset; - - if (log) - { - log->Printf("%*sFrame %u cfa_regval = 0x%16.16llx (cfa_regval = 0x%16.16llx, cfa_offset = %i)", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - m_cfa, cfa_regval, cfa_offset); - } - - // A couple of sanity checks.. - if (cfa_regval == LLDB_INVALID_ADDRESS || cfa_regval == 0 || cfa_regval == 1) - { - if (log) - { - log->Printf("%*sFrame %u could not find a valid cfa address", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number); - } - m_frame_type = eNotAValidFrame; - return; - } - - // If we have a bad stack setup, we can get the same CFA value multiple times -- or even - // more devious, we can actually oscillate between two CFA values. Detect that here and - // break out to avoid a possible infinite loop in lldb trying to unwind the stack. - addr_t next_frame_cfa; - addr_t next_next_frame_cfa = LLDB_INVALID_ADDRESS; - if (GetNextFrame().get() && GetNextFrame()->GetCFA(next_frame_cfa)) - { - bool repeating_frames = false; - if (next_frame_cfa == m_cfa) - { - repeating_frames = true; - } - else - { - if (GetNextFrame()->GetNextFrame() && GetNextFrame()->GetNextFrame()->GetCFA(next_next_frame_cfa) - && next_next_frame_cfa == m_cfa) - { - repeating_frames = true; - } - } - if (repeating_frames) - { - if (log) - { - log->Printf("%*sFrame %u same CFA address as next frame, assuming the unwind is looping - stopping", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number); - } - m_frame_type = eNotAValidFrame; - return; - } - } - - if (log) - { - log->Printf("%*sFrame %u initialized frame current pc is 0x%llx cfa is 0x%llx", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - (uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()), (uint64_t) m_cfa); - } -} - - -bool -RegisterContextLLDB::IsFrameZero () const -{ - return m_frame_number == 0; -} - - -// Find a fast unwind plan for this frame, if possible. -// -// On entry to this method, -// -// 1. m_frame_type should already be set to eSigtrampFrame/eDebuggerFrame if either of those are correct, -// 2. m_sym_ctx should already be filled in, and -// 3. m_current_pc should have the current pc value for this frame -// 4. m_current_offset_backed_up_one should have the current byte offset into the function, maybe backed up by 1, -1 if unknown - -UnwindPlanSP -RegisterContextLLDB::GetFastUnwindPlanForFrame () -{ - UnwindPlanSP unwind_plan_sp; - ModuleSP pc_module_sp (m_current_pc.GetModule()); - - if (!m_current_pc.IsValid() || !pc_module_sp || pc_module_sp->GetObjectFile() == NULL) - return unwind_plan_sp; - - if (IsFrameZero ()) - return unwind_plan_sp; - - FuncUnwindersSP func_unwinders_sp (pc_module_sp->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx)); - if (!func_unwinders_sp) - return unwind_plan_sp; - - // If we're in _sigtramp(), unwinding past this frame requires special knowledge. - if (m_frame_type == eSigtrampFrame || m_frame_type == eDebuggerFrame) - return unwind_plan_sp; - - unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind (m_thread); - if (unwind_plan_sp) - { - if (unwind_plan_sp->PlanValidAtAddress (m_current_pc)) - { - LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); - if (log && log->GetVerbose()) - { - const char *has_fast = ""; - if (m_fast_unwind_plan_sp) - has_fast = ", and has a fast UnwindPlan"; - log->Printf("%*sFrame %u frame has a fast UnwindPlan", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number); - } - m_frame_type = eNormalFrame; - return unwind_plan_sp; - } - else - { - unwind_plan_sp.reset(); - } - } - return unwind_plan_sp; -} - -// On entry to this method, -// -// 1. m_frame_type should already be set to eSigtrampFrame/eDebuggerFrame if either of those are correct, -// 2. m_sym_ctx should already be filled in, and -// 3. m_current_pc should have the current pc value for this frame -// 4. m_current_offset_backed_up_one should have the current byte offset into the function, maybe backed up by 1, -1 if unknown - -UnwindPlanSP -RegisterContextLLDB::GetFullUnwindPlanForFrame () -{ - UnwindPlanSP unwind_plan_sp; - LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); - UnwindPlanSP arch_default_unwind_plan_sp; - ExecutionContext exe_ctx(m_thread.shared_from_this()); - Process *process = exe_ctx.GetProcessPtr(); - ABI *abi = process ? process->GetABI().get() : NULL; - if (abi) - { - arch_default_unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); - abi->CreateDefaultUnwindPlan(*arch_default_unwind_plan_sp); - } - - bool behaves_like_zeroth_frame = false; - if (IsFrameZero () - || GetNextFrame()->m_frame_type == eSigtrampFrame - || GetNextFrame()->m_frame_type == eDebuggerFrame) - { - behaves_like_zeroth_frame = true; - // If this frame behaves like a 0th frame (currently executing or - // interrupted asynchronously), all registers can be retrieved. - m_all_registers_available = true; - } - - // If we've done a jmp 0x0 / bl 0x0 (called through a null function pointer) so the pc is 0x0 - // in the zeroth frame, we need to use the "unwind at first instruction" arch default UnwindPlan - // Also, if this Process can report on memory region attributes, any non-executable region means - // we jumped through a bad function pointer - handle the same way as 0x0. - // Note, if the symbol context has a function for the symbol, then we don't need to do this check. - - if ((!m_sym_ctx_valid || m_sym_ctx.function == NULL) && behaves_like_zeroth_frame && m_current_pc.IsValid()) - { - uint32_t permissions; - addr_t current_pc_addr = m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()); - if (current_pc_addr == 0 - || (process->GetLoadAddressPermissions(current_pc_addr, permissions) - && (permissions & ePermissionsExecutable) == 0)) - { - unwind_plan_sp.reset (new UnwindPlan (lldb::eRegisterKindGeneric)); - abi->CreateFunctionEntryUnwindPlan(*unwind_plan_sp); - m_frame_type = eNormalFrame; - return unwind_plan_sp; - } - } - - // No Module for the current pc, try using the architecture default unwind. - ModuleSP pc_module_sp (m_current_pc.GetModule()); - if (!m_current_pc.IsValid() || !pc_module_sp || pc_module_sp->GetObjectFile() == NULL) - { - m_frame_type = eNormalFrame; - return arch_default_unwind_plan_sp; - } - - FuncUnwindersSP func_unwinders_sp; - if (m_sym_ctx_valid) - { - func_unwinders_sp = pc_module_sp->GetObjectFile()->GetUnwindTable().GetFuncUnwindersContainingAddress (m_current_pc, m_sym_ctx); - } - - // No FuncUnwinders available for this pc, try using architectural default unwind. - if (!func_unwinders_sp) - { - m_frame_type = eNormalFrame; - return arch_default_unwind_plan_sp; - } - - // If we're in _sigtramp(), unwinding past this frame requires special knowledge. On Mac OS X this knowledge - // is properly encoded in the eh_frame section, so prefer that if available. - // On other platforms we may need to provide a platform-specific UnwindPlan which encodes the details of - // how to unwind out of sigtramp. - if (m_frame_type == eSigtrampFrame) - { - m_fast_unwind_plan_sp.reset(); - unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one); - if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc)) - return unwind_plan_sp; - } - - // Ask the DynamicLoader if the eh_frame CFI should be trusted in this frame even when it's frame zero - // This comes up if we have hand-written functions in a Module and hand-written eh_frame. The assembly - // instruction inspection may fail and the eh_frame CFI were probably written with some care to do the - // right thing. It'd be nice if there was a way to ask the eh_frame directly if it is asynchronous - // (can be trusted at every instruction point) or synchronous (the normal case - only at call sites). - // But there is not. - if (process->GetDynamicLoader() && process->GetDynamicLoader()->AlwaysRelyOnEHUnwindInfo (m_sym_ctx)) - { - unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one); - if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc)) - { - if (log && log->GetVerbose()) - { - log->Printf("%*sFrame %u frame uses %s for full UnwindPlan because the DynamicLoader suggested we prefer it", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - unwind_plan_sp->GetSourceName().GetCString()); - } - return unwind_plan_sp; - } - } - - // Typically the NonCallSite UnwindPlan is the unwind created by inspecting the assembly language instructions - if (behaves_like_zeroth_frame) - { - unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (m_thread); - if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc)) - { - if (log && log->GetVerbose()) - { - log->Printf("%*sFrame %u frame uses %s for full UnwindPlan", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - unwind_plan_sp->GetSourceName().GetCString()); - } - return unwind_plan_sp; - } - } - - // Typically this is unwind info from an eh_frame section intended for exception handling; only valid at call sites - unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one); - if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc)) - { - if (log && log->GetVerbose()) - { - log->Printf("%*sFrame %u frame uses %s for full UnwindPlan", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - unwind_plan_sp->GetSourceName().GetCString()); - } - return unwind_plan_sp; - } - - // We'd prefer to use an UnwindPlan intended for call sites when we're at a call site but if we've - // struck out on that, fall back to using the non-call-site assembly inspection UnwindPlan if possible. - unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtNonCallSite (m_thread); - if (unwind_plan_sp && unwind_plan_sp->PlanValidAtAddress (m_current_pc)) - { - if (log && log->GetVerbose()) - { - log->Printf("%*sFrame %u frame uses %s for full UnwindPlan", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - unwind_plan_sp->GetSourceName().GetCString()); - } - return unwind_plan_sp; - } - - // If nothing else, use the architectural default UnwindPlan and hope that does the job. - if (log && log->GetVerbose()) - { - log->Printf("%*sFrame %u frame uses %s for full UnwindPlan", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - arch_default_unwind_plan_sp->GetSourceName().GetCString()); - } - return arch_default_unwind_plan_sp; -} - - -void -RegisterContextLLDB::InvalidateAllRegisters () -{ - m_frame_type = eNotAValidFrame; -} - -size_t -RegisterContextLLDB::GetRegisterCount () -{ - return m_thread.GetRegisterContext()->GetRegisterCount(); -} - -const RegisterInfo * -RegisterContextLLDB::GetRegisterInfoAtIndex (uint32_t reg) -{ - return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex (reg); -} - -size_t -RegisterContextLLDB::GetRegisterSetCount () -{ - return m_thread.GetRegisterContext()->GetRegisterSetCount (); -} - -const RegisterSet * -RegisterContextLLDB::GetRegisterSet (uint32_t reg_set) -{ - return m_thread.GetRegisterContext()->GetRegisterSet (reg_set); -} - -uint32_t -RegisterContextLLDB::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) -{ - return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (kind, num); -} - -bool -RegisterContextLLDB::ReadRegisterValueFromRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc, - const RegisterInfo *reg_info, - RegisterValue &value) -{ - if (!IsValid()) - return false; - bool success = false; - - switch (regloc.type) - { - case UnwindLLDB::RegisterLocation::eRegisterInRegister: - { - const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number); - if (IsFrameZero ()) - { - success = m_thread.GetRegisterContext()->ReadRegister (other_reg_info, value); - } - else - { - success = GetNextFrame()->ReadRegister (other_reg_info, value); - } - } - break; - case UnwindLLDB::RegisterLocation::eRegisterValueInferred: - success = value.SetUInt (regloc.location.inferred_value, reg_info->byte_size); - break; - - case UnwindLLDB::RegisterLocation::eRegisterNotSaved: - break; - case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation: - assert ("FIXME debugger inferior function call unwind"); - break; - case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation: - { - Error error (ReadRegisterValueFromMemory(reg_info, - regloc.location.target_memory_location, - reg_info->byte_size, - value)); - success = error.Success(); - } - break; - default: - assert ("Unknown RegisterLocation type."); - break; - } - return success; -} - -bool -RegisterContextLLDB::WriteRegisterValueToRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc, - const RegisterInfo *reg_info, - const RegisterValue &value) -{ - if (!IsValid()) - return false; - - bool success = false; - - switch (regloc.type) - { - case UnwindLLDB::RegisterLocation::eRegisterInRegister: - { - const RegisterInfo *other_reg_info = GetRegisterInfoAtIndex(regloc.location.register_number); - if (IsFrameZero ()) - { - success = m_thread.GetRegisterContext()->WriteRegister (other_reg_info, value); - } - else - { - success = GetNextFrame()->WriteRegister (other_reg_info, value); - } - } - break; - case UnwindLLDB::RegisterLocation::eRegisterValueInferred: - case UnwindLLDB::RegisterLocation::eRegisterNotSaved: - break; - case UnwindLLDB::RegisterLocation::eRegisterSavedAtHostMemoryLocation: - assert ("FIXME debugger inferior function call unwind"); - break; - case UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation: - { - Error error (WriteRegisterValueToMemory (reg_info, - regloc.location.target_memory_location, - reg_info->byte_size, - value)); - success = error.Success(); - } - break; - default: - assert ("Unknown RegisterLocation type."); - break; - } - return success; -} - - -bool -RegisterContextLLDB::IsValid () const -{ - return m_frame_type != eNotAValidFrame; -} - -// A skip frame is a bogus frame on the stack -- but one where we're likely to find a real frame farther -// up the stack if we keep looking. It's always the second frame in an unwind (i.e. the first frame after -// frame zero) where unwinding can be the trickiest. Ideally we'll mark up this frame in some way so the -// user knows we're displaying bad data and we may have skipped one frame of their real program in the -// process of getting back on track. - -bool -RegisterContextLLDB::IsSkipFrame () const -{ - return m_frame_type == eSkipFrame; -} - -// Answer the question: Where did THIS frame save the CALLER frame ("previous" frame)'s register value? - -bool -RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, bool check_next_frame) -{ - LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); - - // Have we already found this register location? - if (!m_registers.empty()) - { - std::map<uint32_t, lldb_private::UnwindLLDB::RegisterLocation>::const_iterator iterator; - iterator = m_registers.find (lldb_regnum); - if (iterator != m_registers.end()) - { - regloc = iterator->second; - return true; - } - } - - // Are we looking for the CALLER's stack pointer? The stack pointer is defined to be the same as THIS frame's - // CFA so just return the CFA value. This is true on x86-32/x86-64 at least. - uint32_t sp_regnum; - if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, eRegisterKindLLDB, sp_regnum) - && sp_regnum == lldb_regnum) - { - // make sure we won't lose precision copying an addr_t (m_cfa) into a uint64_t (.inferred_value) - assert (sizeof (addr_t) <= sizeof (uint64_t)); - regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred; - regloc.location.inferred_value = m_cfa; - m_registers[lldb_regnum] = regloc; - return true; - } - - // Look through the available UnwindPlans for the register location. - - UnwindPlan::Row::RegisterLocation unwindplan_regloc; - bool have_unwindplan_regloc = false; - RegisterKind unwindplan_registerkind = (RegisterKind)-1; - - if (m_fast_unwind_plan_sp) - { - const UnwindPlan::Row *active_row = m_fast_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); - unwindplan_registerkind = m_fast_unwind_plan_sp->GetRegisterKind (); - uint32_t row_regnum; - if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum)) - { - if (log) - { - log->Printf("%*sFrame %u could not convert lldb regnum %d into %d RegisterKind reg numbering scheme", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_regnum, (int) unwindplan_registerkind); - } - return false; - } - if (active_row->GetRegisterInfo (row_regnum, unwindplan_regloc)) - { - if (log) - { - log->Printf("%*sFrame %u supplying caller's saved reg %d's location using FastUnwindPlan", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_regnum); - } - have_unwindplan_regloc = true; - } - } - - if (!have_unwindplan_regloc) - { - // m_full_unwind_plan_sp being NULL means that we haven't tried to find a full UnwindPlan yet - if (!m_full_unwind_plan_sp) - m_full_unwind_plan_sp = GetFullUnwindPlanForFrame (); - - if (m_full_unwind_plan_sp) - { - const UnwindPlan::Row *active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset); - unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind (); - uint32_t row_regnum; - if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (eRegisterKindLLDB, lldb_regnum, unwindplan_registerkind, row_regnum)) - { - if (log) - { - if (unwindplan_registerkind == eRegisterKindGeneric) - log->Printf("%*sFrame %u could not convert lldb regnum %d into eRegisterKindGeneric reg numbering scheme", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_regnum); - else - log->Printf("%*sFrame %u could not convert lldb regnum %d into %d RegisterKind reg numbering scheme", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_regnum, (int) unwindplan_registerkind); - } - return false; - } - - if (active_row->GetRegisterInfo (row_regnum, unwindplan_regloc)) - { - have_unwindplan_regloc = true; - if (log) - { - log->Printf("%*sFrame %u supplying caller's saved reg %d's location using %s UnwindPlan", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_regnum, m_full_unwind_plan_sp->GetSourceName().GetCString()); - } - } - } - } - - - ExecutionContext exe_ctx(m_thread.shared_from_this()); - Process *process = exe_ctx.GetProcessPtr(); - if (have_unwindplan_regloc == false) - { - // If a volatile register is being requested, we don't want to forward the next frame's register contents - // up the stack -- the register is not retrievable at this frame. - ABI *abi = process ? process->GetABI().get() : NULL; - if (abi) - { - const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum); - if (reg_info && abi->RegisterIsVolatile (reg_info)) - { - if (log && log->GetVerbose ()) - { - log->Printf("%*sFrame %u did not supply reg location for %d because it is volatile", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_regnum); - } - return false; - } - } - - if (IsFrameZero ()) - { - // This is frame 0 - we should return the actual live register context value - lldb_private::UnwindLLDB::RegisterLocation new_regloc; - new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister; - new_regloc.location.register_number = lldb_regnum; - m_registers[lldb_regnum] = new_regloc; - regloc = new_regloc; - return true; - } - else - { - if (check_next_frame) - return m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1); - } - if (log) - { - log->Printf("%*sFrame %u could not supply caller's reg %d location", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_regnum); - } - return false; - } - - // unwindplan_regloc has valid contents about where to retrieve the register - if (unwindplan_regloc.IsUnspecified()) - { - lldb_private::UnwindLLDB::RegisterLocation new_regloc; - new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved; - m_registers[lldb_regnum] = new_regloc; - if (log) - { - log->Printf("%*sFrame %u could not supply caller's reg %d location", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_regnum); - } - return false; - } - - if (unwindplan_regloc.IsSame()) - { - if (IsFrameZero ()) - { - if (log) - { - log->Printf("%*sFrame %u could not supply caller's reg %d location", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_regnum); - } - return false; - } - else - { - if (check_next_frame) - return m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1); - else - return false; - } - } - - if (unwindplan_regloc.IsCFAPlusOffset()) - { - int offset = unwindplan_regloc.GetOffset(); - regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred; - regloc.location.inferred_value = m_cfa + offset; - m_registers[lldb_regnum] = regloc; - return true; - } - - if (unwindplan_regloc.IsAtCFAPlusOffset()) - { - int offset = unwindplan_regloc.GetOffset(); - regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation; - regloc.location.target_memory_location = m_cfa + offset; - m_registers[lldb_regnum] = regloc; - return true; - } - - if (unwindplan_regloc.IsInOtherRegister()) - { - uint32_t unwindplan_regnum = unwindplan_regloc.GetRegisterNumber(); - uint32_t row_regnum_in_lldb; - if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (unwindplan_registerkind, unwindplan_regnum, eRegisterKindLLDB, row_regnum_in_lldb)) - { - if (log) - { - log->Printf("%*sFrame %u could not supply caller's reg %d location", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_regnum); - } - return false; - } - regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister; - regloc.location.register_number = row_regnum_in_lldb; - m_registers[lldb_regnum] = regloc; - return true; - } - - if (unwindplan_regloc.IsDWARFExpression() || unwindplan_regloc.IsAtDWARFExpression()) - { - DataExtractor dwarfdata (unwindplan_regloc.GetDWARFExpressionBytes(), - unwindplan_regloc.GetDWARFExpressionLength(), - process->GetByteOrder(), process->GetAddressByteSize()); - DWARFExpression dwarfexpr (dwarfdata, 0, unwindplan_regloc.GetDWARFExpressionLength()); - dwarfexpr.SetRegisterKind (unwindplan_registerkind); - Value result; - Error error; - if (dwarfexpr.Evaluate (&exe_ctx, NULL, NULL, NULL, this, 0, NULL, result, &error)) - { - addr_t val; - val = result.GetScalar().ULongLong(); - if (unwindplan_regloc.IsDWARFExpression()) - { - regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred; - regloc.location.inferred_value = val; - m_registers[lldb_regnum] = regloc; - return true; - } - else - { - regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation; - regloc.location.target_memory_location = val; - m_registers[lldb_regnum] = regloc; - return true; - } - } - if (log) - { - log->Printf("%*sFrame %u tried to use IsDWARFExpression or IsAtDWARFExpression for reg %d but failed", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_regnum); - } - return false; - } - - if (log) - { - log->Printf("%*sFrame %u could not supply caller's reg %d location", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_regnum); - } - - - // assert ("UnwindPlan::Row types atDWARFExpression and isDWARFExpression are unsupported."); - return false; -} - -// Retrieve a general purpose register value for THIS from, as saved by the NEXT frame, i.e. the frame that -// this frame called. e.g. -// -// foo () { } -// bar () { foo (); } -// main () { bar (); } -// -// stopped in foo() so -// frame 0 - foo -// frame 1 - bar -// frame 2 - main -// and this RegisterContext is for frame 1 (bar) - if we want to get the pc value for frame 1, we need to ask -// where frame 0 (the "next" frame) saved that and retrieve the value. - -bool -RegisterContextLLDB::ReadGPRValue (int register_kind, uint32_t regnum, addr_t &value) -{ - if (!IsValid()) - return false; - - uint32_t lldb_regnum; - if (register_kind == eRegisterKindLLDB) - { - lldb_regnum = regnum; - } - else if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (register_kind, regnum, eRegisterKindLLDB, lldb_regnum)) - { - return false; - } - - const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum); - RegisterValue reg_value; - // if this is frame 0 (currently executing frame), get the requested reg contents from the actual thread registers - if (IsFrameZero ()) - { - if (m_thread.GetRegisterContext()->ReadRegister (reg_info, reg_value)) - { - value = reg_value.GetAsUInt64(); - return true; - } - return false; - } - - lldb_private::UnwindLLDB::RegisterLocation regloc; - if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1)) - { - return false; - } - if (ReadRegisterValueFromRegisterLocation (regloc, reg_info, reg_value)) - { - value = reg_value.GetAsUInt64(); - return true; - } - return false; -} - -// Find the value of a register in THIS frame - -bool -RegisterContextLLDB::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) -{ - LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); - if (!IsValid()) - return false; - - const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB]; - if (log && log->GetVerbose ()) - { - log->Printf("%*sFrame %u looking for register saved location for reg %d", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_regnum); - } - - // If this is the 0th frame, hand this over to the live register context - if (IsFrameZero ()) - { - if (log && log->GetVerbose ()) - { - log->Printf("%*sFrame %u passing along to the live register context for reg %d", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_regnum); - } - return m_thread.GetRegisterContext()->ReadRegister (reg_info, value); - } - - lldb_private::UnwindLLDB::RegisterLocation regloc; - // Find out where the NEXT frame saved THIS frame's register contents - if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1)) - return false; - - return ReadRegisterValueFromRegisterLocation (regloc, reg_info, value); -} - -bool -RegisterContextLLDB::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &value) -{ - LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); - if (!IsValid()) - return false; - - const uint32_t lldb_regnum = reg_info->kinds[eRegisterKindLLDB]; - if (log && log->GetVerbose ()) - { - log->Printf("%*sFrame %u looking for register saved location for reg %d", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_regnum); - } - - // If this is the 0th frame, hand this over to the live register context - if (IsFrameZero ()) - { - if (log && log->GetVerbose ()) - { - log->Printf("%*sFrame %u passing along to the live register context for reg %d", - m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number, - lldb_regnum); - } - return m_thread.GetRegisterContext()->WriteRegister (reg_info, value); - } - - lldb_private::UnwindLLDB::RegisterLocation regloc; - // Find out where the NEXT frame saved THIS frame's register contents - if (!m_parent_unwind.SearchForSavedLocationForRegister (lldb_regnum, regloc, m_frame_number - 1)) - return false; - - return WriteRegisterValueToRegisterLocation (regloc, reg_info, value); -} - -// Don't need to implement this one -bool -RegisterContextLLDB::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) -{ - return false; -} - -// Don't need to implement this one -bool -RegisterContextLLDB::WriteAllRegisterValues (const lldb::DataBufferSP& data_sp) -{ - return false; -} - -// Retrieve the pc value for THIS from - -bool -RegisterContextLLDB::GetCFA (addr_t& cfa) -{ - if (!IsValid()) - { - return false; - } - if (m_cfa == LLDB_INVALID_ADDRESS) - { - return false; - } - cfa = m_cfa; - return true; -} - - -RegisterContextLLDB::SharedPtr -RegisterContextLLDB::GetNextFrame () const -{ - RegisterContextLLDB::SharedPtr regctx; - if (m_frame_number == 0) - return regctx; - return m_parent_unwind.GetRegisterContextForFrameNum (m_frame_number - 1); -} - -RegisterContextLLDB::SharedPtr -RegisterContextLLDB::GetPrevFrame () const -{ - RegisterContextLLDB::SharedPtr regctx; - return m_parent_unwind.GetRegisterContextForFrameNum (m_frame_number + 1); -} - -// Retrieve the address of the start of the function of THIS frame - -bool -RegisterContextLLDB::GetStartPC (addr_t& start_pc) -{ - if (!IsValid()) - return false; - - if (!m_start_pc.IsValid()) - { - return ReadPC (start_pc); - } - start_pc = m_start_pc.GetLoadAddress (CalculateTarget().get()); - return true; -} - -// Retrieve the current pc value for THIS frame, as saved by the NEXT frame. - -bool -RegisterContextLLDB::ReadPC (addr_t& pc) -{ - if (!IsValid()) - return false; - - if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, pc)) - { - // A pc value of 0 or 1 is impossible in the middle of the stack -- it indicates the end of a stack walk. - // On the currently executing frame (or such a frame interrupted asynchronously by sigtramp et al) this may - // occur if code has jumped through a NULL pointer -- we want to be able to unwind past that frame to help - // find the bug. - - if (m_all_registers_available == false - && (pc == 0 || pc == 1)) - { - return false; - } - else - { - return true; - } - } - else - { - return false; - } -} diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h deleted file mode 100644 index 3a7aa67a8bbf..000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h +++ /dev/null @@ -1,208 +0,0 @@ -//===-- RegisterContextLLDB.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_RegisterContextLLDB_h_ -#define lldb_RegisterContextLLDB_h_ - -#include <vector> - -#include "lldb/lldb-private.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Symbol/UnwindPlan.h" -#include "lldb/Symbol/SymbolContext.h" -#include "UnwindLLDB.h" - -namespace lldb_private { - -class UnwindLLDB; - -class RegisterContextLLDB : public lldb_private::RegisterContext -{ -public: - typedef STD_SHARED_PTR(RegisterContextLLDB) SharedPtr; - - RegisterContextLLDB (lldb_private::Thread &thread, - const SharedPtr& next_frame, - lldb_private::SymbolContext& sym_ctx, - uint32_t frame_number, lldb_private::UnwindLLDB& unwind_lldb); - - /// - // pure virtual functions from the base class that we must implement - /// - - virtual - ~RegisterContextLLDB () { } - - virtual void - InvalidateAllRegisters (); - - virtual size_t - GetRegisterCount (); - - virtual const lldb_private::RegisterInfo * - GetRegisterInfoAtIndex (uint32_t reg); - - virtual size_t - GetRegisterSetCount (); - - virtual const lldb_private::RegisterSet * - GetRegisterSet (uint32_t reg_set); - - virtual bool - ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value); - - virtual bool - WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value); - - virtual bool - ReadAllRegisterValues (lldb::DataBufferSP &data_sp); - - virtual bool - WriteAllRegisterValues (const lldb::DataBufferSP &data_sp); - - virtual uint32_t - ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num); - - bool - IsValid () const; - - bool - GetCFA (lldb::addr_t& cfa); - - bool - GetStartPC (lldb::addr_t& start_pc); - - bool - ReadPC (lldb::addr_t& start_pc); - -private: - - enum FrameType - { - eNormalFrame, - eSigtrampFrame, - eDebuggerFrame, // a debugger inferior function call frame; we get caller's registers from debugger - eSkipFrame, // The unwind resulted in a bogus frame but may get back on track so we don't want to give up yet - eNotAValidFrame // this frame is invalid for some reason - most likely it is past the top (end) of the stack - }; - - // UnwindLLDB needs to pass around references to RegisterLocations - friend class UnwindLLDB; - - // Indicates whether this frame is frame zero -- the currently - // executing frame -- or not. - bool - IsFrameZero () const; - - void - InitializeZerothFrame (); - - void - InitializeNonZerothFrame(); - - SharedPtr - GetNextFrame () const; - - SharedPtr - GetPrevFrame () const; - - // A SkipFrame occurs when the unwind out of frame 0 didn't go right -- we've got one bogus frame at frame #1. - // There is a good chance we'll get back on track if we follow the frame pointer chain (or whatever is appropriate - // on this ABI) so we allow one invalid frame to be in the stack. Ideally we'll mark this frame specially at some - // point and indicate to the user that the unwinder had a hiccup. Often when this happens we will miss a frame of - // the program's actual stack in the unwind and we want to flag that for the user somehow. - bool - IsSkipFrame () const; - - // Provide a location for where THIS function saved the CALLER's register value - // Or a frame "below" this one saved it, i.e. a function called by this one, preserved a register that this - // function didn't modify/use. - // - // The RegisterLocation type may be set to eRegisterNotAvailable -- this will happen for a volatile register - // being queried mid-stack. Instead of floating frame 0's contents of that register up the stack (which may - // or may not be the value of that reg when the function was executing), we won't return any value. - // - // If a non-volatile register (a "preserved" register) is requested mid-stack and no frames "below" the requested - // stack have saved the register anywhere, it is safe to assume that frame 0's register values are still the same - // as the requesting frame's. - // - // NB this function takes a "check_next_frame" boolean which indicates whether it should call back to the - // containing UnwindLLDB object to iterate the search down the stack (true) or if this call should look for - // a register save for that reg in the current frame only (false). Allows UnwindLLDB to iterate through the - // RegisterContextLLDB's instead of using recursion to find saved register values. - bool - SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, bool check_next_frame); - - bool - ReadRegisterValueFromRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc, - const lldb_private::RegisterInfo *reg_info, - lldb_private::RegisterValue &value); - - bool - WriteRegisterValueToRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc, - const lldb_private::RegisterInfo *reg_info, - const lldb_private::RegisterValue &value); - - // Get the contents of a general purpose (address-size) register for this frame - // (usually retrieved from the next frame) - bool - ReadGPRValue (int register_kind, uint32_t regnum, lldb::addr_t &value); - - lldb::UnwindPlanSP - GetFastUnwindPlanForFrame (); - - lldb::UnwindPlanSP - GetFullUnwindPlanForFrame (); - - lldb_private::Thread& m_thread; - - /// - // The following tell us how to retrieve the CALLER's register values (ie the "previous" frame, aka the frame above) - // i.e. where THIS frame saved them - /// - - lldb::UnwindPlanSP m_fast_unwind_plan_sp; // may be NULL - lldb::UnwindPlanSP m_full_unwind_plan_sp; - bool m_all_registers_available; // Can we retrieve all regs or just nonvolatile regs? - int m_frame_type; // enum FrameType - - lldb::addr_t m_cfa; - lldb_private::Address m_start_pc; - lldb_private::Address m_current_pc; - - int m_current_offset; // how far into the function we've executed; -1 if unknown - // 0 if no instructions have been executed yet. - - int m_current_offset_backed_up_one; // how far into the function we've executed; -1 if unknown - // 0 if no instructions have been executed yet. - // On architectures where the return address on the stack points - // to the instruction after the CALL, this value will have 1 - // subtracted from it. Else a function that ends in a CALL will - // have an offset pointing into the next function's address range. - // m_current_pc has the actual address of the "current" pc. - - lldb_private::SymbolContext& m_sym_ctx; - bool m_sym_ctx_valid; // if ResolveSymbolContextForAddress fails, don't try to use m_sym_ctx - - uint32_t m_frame_number; // What stack frame this RegisterContext is - - std::map<uint32_t, lldb_private::UnwindLLDB::RegisterLocation> m_registers; // where to find reg values for this frame - - lldb_private::UnwindLLDB& m_parent_unwind; // The UnwindLLDB that is creating this RegisterContextLLDB - - //------------------------------------------------------------------ - // For RegisterContextLLDB only - //------------------------------------------------------------------ - - DISALLOW_COPY_AND_ASSIGN (RegisterContextLLDB); -}; - -} // namespace lldb_private - -#endif // lldb_RegisterContextLLDB_h_ diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp deleted file mode 100644 index 6cfad1eb0dd4..000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp +++ /dev/null @@ -1,206 +0,0 @@ -//===-- RegisterContextMacOSXFrameBackchain.cpp -----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "RegisterContextMacOSXFrameBackchain.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Target/Thread.h" -// Project includes -#include "Utility/StringExtractorGDBRemote.h" - -using namespace lldb; -using namespace lldb_private; - -//---------------------------------------------------------------------- -// RegisterContextMacOSXFrameBackchain constructor -//---------------------------------------------------------------------- -RegisterContextMacOSXFrameBackchain::RegisterContextMacOSXFrameBackchain -( - Thread &thread, - uint32_t concrete_frame_idx, - const UnwindMacOSXFrameBackchain::Cursor &cursor -) : - RegisterContext (thread, concrete_frame_idx), - m_cursor (cursor), - m_cursor_is_valid (true) -{ -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -RegisterContextMacOSXFrameBackchain::~RegisterContextMacOSXFrameBackchain() -{ -} - -void -RegisterContextMacOSXFrameBackchain::InvalidateAllRegisters () -{ - m_cursor_is_valid = false; -} - -size_t -RegisterContextMacOSXFrameBackchain::GetRegisterCount () -{ - return m_thread.GetRegisterContext()->GetRegisterCount(); -} - -const RegisterInfo * -RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex (uint32_t reg) -{ - return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg); -} - -size_t -RegisterContextMacOSXFrameBackchain::GetRegisterSetCount () -{ - return m_thread.GetRegisterContext()->GetRegisterSetCount(); -} - - - -const RegisterSet * -RegisterContextMacOSXFrameBackchain::GetRegisterSet (uint32_t reg_set) -{ - return m_thread.GetRegisterContext()->GetRegisterSet (reg_set); -} - - - -bool -RegisterContextMacOSXFrameBackchain::ReadRegister (const RegisterInfo *reg_info, - RegisterValue &value) -{ - if (!m_cursor_is_valid) - return false; - - uint64_t reg_value = LLDB_INVALID_ADDRESS; - - switch (reg_info->kinds[eRegisterKindGeneric]) - { - case LLDB_REGNUM_GENERIC_PC: - if (m_cursor.pc == LLDB_INVALID_ADDRESS) - return false; - reg_value = m_cursor.pc; - break; - - case LLDB_REGNUM_GENERIC_FP: - if (m_cursor.fp == LLDB_INVALID_ADDRESS) - return false; - reg_value = m_cursor.fp; - break; - - default: - return false; - } - - switch (reg_info->encoding) - { - case eEncodingInvalid: - case eEncodingVector: - break; - - case eEncodingUint: - case eEncodingSint: - value.SetUInt(reg_value, reg_info->byte_size); - return true; - - case eEncodingIEEE754: - switch (reg_info->byte_size) - { - case sizeof (float): - if (sizeof (float) == sizeof(uint32_t)) - { - value.SetUInt32(reg_value, RegisterValue::eTypeFloat); - return true; - } - else if (sizeof (float) == sizeof(uint64_t)) - { - value.SetUInt64(reg_value, RegisterValue::eTypeFloat); - return true; - } - break; - - case sizeof (double): - if (sizeof (double) == sizeof(uint32_t)) - { - value.SetUInt32(reg_value, RegisterValue::eTypeDouble); - return true; - } - else if (sizeof (double) == sizeof(uint64_t)) - { - value.SetUInt64(reg_value, RegisterValue::eTypeDouble); - return true; - } - break; - - // TOOD: need a better way to detect when "long double" types are - // the same bytes size as "double" -#if !defined(__arm__) - case sizeof (long double): - if (sizeof (long double) == sizeof(uint32_t)) - { - value.SetUInt32(reg_value, RegisterValue::eTypeLongDouble); - return true; - } - else if (sizeof (long double) == sizeof(uint64_t)) - { - value.SetUInt64(reg_value, RegisterValue::eTypeLongDouble); - return true; - } - break; -#endif - } - break; - } - return false; -} - -bool -RegisterContextMacOSXFrameBackchain::WriteRegister (const RegisterInfo *reg_info, - const RegisterValue &value) -{ - // Not supported yet. We could easily add support for this by remembering - // the address of each entry (it would need to be part of the cursor) - return false; -} - -bool -RegisterContextMacOSXFrameBackchain::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) -{ - // libunwind frames can't handle this it doesn't always have all register - // values. This call should only be called on frame zero anyway so there - // shouldn't be any problem - return false; -} - -bool -RegisterContextMacOSXFrameBackchain::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) -{ - // Since this class doesn't respond to "ReadAllRegisterValues()", it must - // not have been the one that saved all the register values. So we just let - // the thread's register context (the register context for frame zero) do - // the writing. - return m_thread.GetRegisterContext()->WriteAllRegisterValues(data_sp); -} - - -uint32_t -RegisterContextMacOSXFrameBackchain::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) -{ - return m_thread.GetRegisterContext()->ConvertRegisterKindToRegisterNumber (kind, num); -} - diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h b/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h deleted file mode 100644 index cc6cb5d5d8c0..000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h +++ /dev/null @@ -1,77 +0,0 @@ -//===-- RegisterContextMacOSXFrameBackchain.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_RegisterContextMacOSXFrameBackchain_h_ -#define lldb_RegisterContextMacOSXFrameBackchain_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/lldb-private.h" -#include "lldb/Target/RegisterContext.h" - -#include "UnwindMacOSXFrameBackchain.h" - -class RegisterContextMacOSXFrameBackchain : public lldb_private::RegisterContext -{ -public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - RegisterContextMacOSXFrameBackchain (lldb_private::Thread &thread, - uint32_t concrete_frame_idx, - const UnwindMacOSXFrameBackchain::Cursor &cursor); - - virtual - ~RegisterContextMacOSXFrameBackchain (); - - //------------------------------------------------------------------ - // Subclasses must override these functions - //------------------------------------------------------------------ - virtual void - InvalidateAllRegisters (); - - virtual size_t - GetRegisterCount (); - - virtual const lldb_private::RegisterInfo * - GetRegisterInfoAtIndex (uint32_t reg); - - virtual size_t - GetRegisterSetCount (); - - virtual const lldb_private::RegisterSet * - GetRegisterSet (uint32_t reg_set); - - virtual bool - ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value); - - virtual bool - WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value); - - virtual bool - ReadAllRegisterValues (lldb::DataBufferSP &data_sp); - - virtual bool - WriteAllRegisterValues (const lldb::DataBufferSP &data_sp); - - virtual uint32_t - ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num); - -private: - UnwindMacOSXFrameBackchain::Cursor m_cursor; - bool m_cursor_is_valid; - //------------------------------------------------------------------ - // For RegisterContextMacOSXFrameBackchain only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (RegisterContextMacOSXFrameBackchain); -}; - -#endif // lldb_RegisterContextMacOSXFrameBackchain_h_ diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp deleted file mode 100644 index 7ceb536272f4..000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp +++ /dev/null @@ -1,87 +0,0 @@ -//===-- RegisterContextMach_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(__APPLE__) - -#include "RegisterContextMach_arm.h" - -// C Includes -#include <mach/mach_types.h> -#include <mach/thread_act.h> - -// C++ Includes -// Other libraries and framework includes -// Project includes - -using namespace lldb; -using namespace lldb_private; - - -RegisterContextMach_arm::RegisterContextMach_arm(Thread &thread, uint32_t concrete_frame_idx) : - RegisterContextDarwin_arm (thread, concrete_frame_idx) -{ -} - -RegisterContextMach_arm::~RegisterContextMach_arm() -{ -} - -int -RegisterContextMach_arm::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr) -{ - mach_msg_type_number_t count = GPRWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count); -} - -int -RegisterContextMach_arm::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) -{ - mach_msg_type_number_t count = FPUWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count); -} - -int -RegisterContextMach_arm::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) -{ - mach_msg_type_number_t count = EXCWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count); -} - -int -RegisterContextMach_arm::DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg) -{ - mach_msg_type_number_t count = DBGWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&dbg, &count); -} - -int -RegisterContextMach_arm::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount); -} - -int -RegisterContextMach_arm::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount); -} - -int -RegisterContextMach_arm::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount); -} - -int -RegisterContextMach_arm::DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&dbg, DBGWordCount); -} - -#endif diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h b/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h deleted file mode 100644 index e97a4bfff2b6..000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h +++ /dev/null @@ -1,56 +0,0 @@ -//===-- RegisterContextMach_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_RegisterContextMach_arm_h_ -#define liblldb_RegisterContextMach_arm_h_ - -// C Includes - -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "RegisterContextDarwin_arm.h" - -class RegisterContextMach_arm : public RegisterContextDarwin_arm -{ -public: - - RegisterContextMach_arm(lldb_private::Thread &thread, uint32_t concrete_frame_idx); - - virtual - ~RegisterContextMach_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); -}; - -#endif // liblldb_RegisterContextMach_arm_h_ diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp deleted file mode 100644 index 3d6c9a6baca6..000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp +++ /dev/null @@ -1,72 +0,0 @@ -//===-- RegisterContextMach_i386.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(__APPLE__) - -// C Includes -#include <mach/thread_act.h> - -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "RegisterContextMach_i386.h" - -using namespace lldb; -using namespace lldb_private; - - -RegisterContextMach_i386::RegisterContextMach_i386(Thread &thread, uint32_t concrete_frame_idx) : - RegisterContextDarwin_i386 (thread, concrete_frame_idx) -{ -} - -RegisterContextMach_i386::~RegisterContextMach_i386() -{ -} - -int -RegisterContextMach_i386::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr) -{ - mach_msg_type_number_t count = GPRWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count); -} - -int -RegisterContextMach_i386::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) -{ - mach_msg_type_number_t count = FPUWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count); -} - -int -RegisterContextMach_i386::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) -{ - mach_msg_type_number_t count = EXCWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count); -} - -int -RegisterContextMach_i386::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount); -} - -int -RegisterContextMach_i386::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount); -} - -int -RegisterContextMach_i386::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount); -} - -#endif diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h b/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h deleted file mode 100644 index ad0f69d1c052..000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h +++ /dev/null @@ -1,49 +0,0 @@ -//===-- RegisterContextMach_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_RegisterContextMach_i386_h_ -#define liblldb_RegisterContextMach_i386_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "RegisterContextDarwin_i386.h" - -class RegisterContextMach_i386 : public RegisterContextDarwin_i386 -{ -public: - - RegisterContextMach_i386(lldb_private::Thread &thread, uint32_t concrete_frame_idx); - - virtual - ~RegisterContextMach_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); -}; - -#endif // liblldb_RegisterContextMach_i386_h_ diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp deleted file mode 100644 index f03685e1313f..000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp +++ /dev/null @@ -1,72 +0,0 @@ -//===-- RegisterContextMach_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(__APPLE__) - -// C Includes -#include <mach/thread_act.h> - -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "RegisterContextMach_x86_64.h" - -using namespace lldb; -using namespace lldb_private; - - -RegisterContextMach_x86_64::RegisterContextMach_x86_64(Thread &thread, uint32_t concrete_frame_idx) : - RegisterContextDarwin_x86_64 (thread, concrete_frame_idx) -{ -} - -RegisterContextMach_x86_64::~RegisterContextMach_x86_64() -{ -} - -int -RegisterContextMach_x86_64::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr) -{ - mach_msg_type_number_t count = GPRWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&gpr, &count); -} - -int -RegisterContextMach_x86_64::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu) -{ - mach_msg_type_number_t count = FPUWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&fpu, &count); -} - -int -RegisterContextMach_x86_64::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc) -{ - mach_msg_type_number_t count = EXCWordCount; - return ::thread_get_state(tid, flavor, (thread_state_t)&exc, &count); -} - -int -RegisterContextMach_x86_64::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount); -} - -int -RegisterContextMach_x86_64::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount); -} - -int -RegisterContextMach_x86_64::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc) -{ - return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount); -} - -#endif diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h b/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h deleted file mode 100644 index 9e6dfa395500..000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h +++ /dev/null @@ -1,49 +0,0 @@ -//===-- RegisterContextMach_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_RegisterContextMach_x86_64_h_ -#define liblldb_RegisterContextMach_x86_64_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "RegisterContextDarwin_x86_64.h" - -class RegisterContextMach_x86_64 : public RegisterContextDarwin_x86_64 -{ -public: - - RegisterContextMach_x86_64(lldb_private::Thread &thread, uint32_t concrete_frame_idx); - - virtual - ~RegisterContextMach_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); -}; - -#endif // liblldb_RegisterContextMach_x86_64_h_ diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp deleted file mode 100644 index 03610a2fe7cd..000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp +++ /dev/null @@ -1,166 +0,0 @@ -//===-- RegisterContextMemory.cpp -------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "RegisterContextMemory.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "DynamicRegisterInfo.h" -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/Error.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/Thread.h" - -using namespace lldb; -using namespace lldb_private; - -//---------------------------------------------------------------------- -// RegisterContextMemory constructor -//---------------------------------------------------------------------- -RegisterContextMemory::RegisterContextMemory -( - Thread &thread, - uint32_t concrete_frame_idx, - DynamicRegisterInfo ®_infos, - addr_t reg_data_addr -) : - RegisterContext (thread, concrete_frame_idx), - m_reg_infos (reg_infos), - m_reg_valid (), - m_reg_data (), - m_reg_data_addr (reg_data_addr) -{ - // Resize our vector of bools to contain one bool for every register. - // We will use these boolean values to know when a register value - // is valid in m_reg_data. - const size_t num_regs = reg_infos.GetNumRegisters(); - assert (num_regs > 0); - m_reg_valid.resize (num_regs); - - // Make a heap based buffer that is big enough to store all registers - DataBufferSP reg_data_sp(new DataBufferHeap (reg_infos.GetRegisterDataByteSize(), 0)); - m_reg_data.SetData (reg_data_sp); -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -RegisterContextMemory::~RegisterContextMemory() -{ -} - -void -RegisterContextMemory::InvalidateAllRegisters () -{ - SetAllRegisterValid (false); -} - -void -RegisterContextMemory::SetAllRegisterValid (bool b) -{ - std::vector<bool>::iterator pos, end = m_reg_valid.end(); - for (pos = m_reg_valid.begin(); pos != end; ++pos) - *pos = b; -} - -size_t -RegisterContextMemory::GetRegisterCount () -{ - return m_reg_infos.GetNumRegisters (); -} - -const RegisterInfo * -RegisterContextMemory::GetRegisterInfoAtIndex (uint32_t reg) -{ - return m_reg_infos.GetRegisterInfoAtIndex (reg); -} - -size_t -RegisterContextMemory::GetRegisterSetCount () -{ - return m_reg_infos.GetNumRegisterSets (); -} - -const RegisterSet * -RegisterContextMemory::GetRegisterSet (uint32_t reg_set) -{ - return m_reg_infos.GetRegisterSet (reg_set); -} - -uint32_t -RegisterContextMemory::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) -{ - return m_reg_infos.ConvertRegisterKindToRegisterNumber (kind, num); -} - -bool -RegisterContextMemory::ReadRegister (const RegisterInfo *reg_info, RegisterValue ®_value) -{ - const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB]; - if (!m_reg_valid[reg_num]) - { - if (!ReadAllRegisterValues(m_reg_data.GetSharedDataBuffer ())) - return false; - } - const bool partial_data_ok = false; - return reg_value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok).Success(); -} - -bool -RegisterContextMemory::WriteRegister (const RegisterInfo *reg_info, const RegisterValue ®_value) -{ - if (m_reg_data_addr != LLDB_INVALID_ADDRESS) - { - const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB]; - addr_t reg_addr = m_reg_data_addr + reg_info->byte_offset; - Error error (WriteRegisterValueToMemory(reg_info, reg_addr, reg_info->byte_size, reg_value)); - m_reg_valid[reg_num] = false; - return error.Success(); - } - return false; -} - -bool -RegisterContextMemory::ReadAllRegisterValues (DataBufferSP &data_sp) -{ - if (m_reg_data_addr != LLDB_INVALID_ADDRESS) - { - ProcessSP process_sp (CalculateProcess()); - if (process_sp) - { - Error error; - if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize()) - { - SetAllRegisterValid (true); - return true; - } - } - } - return false; -} - -bool -RegisterContextMemory::WriteAllRegisterValues (const DataBufferSP &data_sp) -{ - if (m_reg_data_addr != LLDB_INVALID_ADDRESS) - { - ProcessSP process_sp (CalculateProcess()); - if (process_sp) - { - Error error; - SetAllRegisterValid (false); - if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize()) - return true; - } - } - return false; -} diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h b/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h deleted file mode 100644 index 6914e3f36978..000000000000 --- a/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h +++ /dev/null @@ -1,100 +0,0 @@ -//===-- RegisterContextMemory.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_RegisterContextMemory_h_ -#define lldb_RegisterContextMemory_h_ - -// C Includes -// C++ Includes -#include <vector> - -// Other libraries and framework includes -// Project includes -#include "lldb/lldb-private.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Target/RegisterContext.h" - -class DynamicRegisterInfo; - -class RegisterContextMemory : public lldb_private::RegisterContext -{ -public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - RegisterContextMemory (lldb_private::Thread &thread, - uint32_t concrete_frame_idx, - DynamicRegisterInfo ®_info, - lldb::addr_t reg_data_addr); - - virtual - ~RegisterContextMemory (); - - //------------------------------------------------------------------ - // Subclasses must override these functions - //------------------------------------------------------------------ - virtual void - InvalidateAllRegisters (); - - virtual size_t - GetRegisterCount (); - - virtual const lldb_private::RegisterInfo * - GetRegisterInfoAtIndex (uint32_t reg); - - virtual size_t - GetRegisterSetCount (); - - virtual const lldb_private::RegisterSet * - GetRegisterSet (uint32_t reg_set); - - virtual uint32_t - ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num); - - - //------------------------------------------------------------------ - // If all of the thread register are in a contiguous buffer in - // memory, then the default ReadRegister/WriteRegiter and - // ReadAllRegisterValues/WriteAllRegisterValues will work. If thread - // registers are not contiguous, clients will want to subclass this - // class and modify the read/write functions as needed. - //------------------------------------------------------------------ - - virtual bool - ReadRegister (const lldb_private::RegisterInfo *reg_info, - lldb_private::RegisterValue ®_value); - - virtual bool - WriteRegister (const lldb_private::RegisterInfo *reg_info, - const lldb_private::RegisterValue ®_value); - - virtual bool - ReadAllRegisterValues (lldb::DataBufferSP &data_sp); - - virtual bool - WriteAllRegisterValues (const lldb::DataBufferSP &data_sp); - -protected: - - void - SetAllRegisterValid (bool b); - - DynamicRegisterInfo &m_reg_infos; - std::vector<bool> m_reg_valid; - lldb_private::DataExtractor m_reg_data; - lldb::addr_t m_reg_data_addr; // If this is valid, then we have a register context that is stored in memmory - -private: - //------------------------------------------------------------------ - // For RegisterContextMemory only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (RegisterContextMemory); -}; - -#endif // lldb_RegisterContextMemory_h_ diff --git a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp deleted file mode 100644 index bc313f75eb2a..000000000000 --- a/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp +++ /dev/null @@ -1,400 +0,0 @@ -//===-- StopInfoMachException.cpp -------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "StopInfoMachException.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Breakpoint/Watchpoint.h" -#include "lldb/Core/ArchSpec.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/Thread.h" -#include "lldb/Target/ThreadPlan.h" -#include "lldb/Target/UnixSignals.h" - -using namespace lldb; -using namespace lldb_private; - -const char * -StopInfoMachException::GetDescription () -{ - if (m_description.empty() && m_value != 0) - { - ExecutionContext exe_ctx (m_thread.shared_from_this()); - Target *target = exe_ctx.GetTargetPtr(); - const llvm::Triple::ArchType cpu = target ? target->GetArchitecture().GetMachine() : llvm::Triple::UnknownArch; - - const char *exc_desc = NULL; - const char *code_label = "code"; - const char *code_desc = NULL; - const char *subcode_label = "subcode"; - const char *subcode_desc = NULL; - switch (m_value) - { - case 1: // EXC_BAD_ACCESS - exc_desc = "EXC_BAD_ACCESS"; - subcode_label = "address"; - switch (cpu) - { - case llvm::Triple::arm: - switch (m_exc_code) - { - case 0x101: code_desc = "EXC_ARM_DA_ALIGN"; break; - case 0x102: code_desc = "EXC_ARM_DA_DEBUG"; break; - } - break; - - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - switch (m_exc_code) - { - case 0x101: code_desc = "EXC_PPC_VM_PROT_READ"; break; - case 0x102: code_desc = "EXC_PPC_BADSPACE"; break; - case 0x103: code_desc = "EXC_PPC_UNALIGNED"; break; - } - break; - - default: - break; - } - break; - - case 2: // EXC_BAD_INSTRUCTION - exc_desc = "EXC_BAD_INSTRUCTION"; - switch (cpu) - { - case llvm::Triple::x86: - case llvm::Triple::x86_64: - if (m_exc_code == 1) - code_desc = "EXC_I386_INVOP"; - break; - - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - switch (m_exc_code) - { - case 1: code_desc = "EXC_PPC_INVALID_SYSCALL"; break; - case 2: code_desc = "EXC_PPC_UNIPL_INST"; break; - case 3: code_desc = "EXC_PPC_PRIVINST"; break; - case 4: code_desc = "EXC_PPC_PRIVREG"; break; - case 5: code_desc = "EXC_PPC_TRACE"; break; - case 6: code_desc = "EXC_PPC_PERFMON"; break; - } - break; - - case llvm::Triple::arm: - if (m_exc_code == 1) - code_desc = "EXC_ARM_UNDEFINED"; - break; - - default: - break; - } - break; - - case 3: // EXC_ARITHMETIC - exc_desc = "EXC_ARITHMETIC"; - switch (cpu) - { - case llvm::Triple::x86: - case llvm::Triple::x86_64: - switch (m_exc_code) - { - case 1: code_desc = "EXC_I386_DIV"; break; - case 2: code_desc = "EXC_I386_INTO"; break; - case 3: code_desc = "EXC_I386_NOEXT"; break; - case 4: code_desc = "EXC_I386_EXTOVR"; break; - case 5: code_desc = "EXC_I386_EXTERR"; break; - case 6: code_desc = "EXC_I386_EMERR"; break; - case 7: code_desc = "EXC_I386_BOUND"; break; - case 8: code_desc = "EXC_I386_SSEEXTERR"; break; - } - break; - - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - switch (m_exc_code) - { - case 1: code_desc = "EXC_PPC_OVERFLOW"; break; - case 2: code_desc = "EXC_PPC_ZERO_DIVIDE"; break; - case 3: code_desc = "EXC_PPC_FLT_INEXACT"; break; - case 4: code_desc = "EXC_PPC_FLT_ZERO_DIVIDE"; break; - case 5: code_desc = "EXC_PPC_FLT_UNDERFLOW"; break; - case 6: code_desc = "EXC_PPC_FLT_OVERFLOW"; break; - case 7: code_desc = "EXC_PPC_FLT_NOT_A_NUMBER"; break; - } - break; - - default: - break; - } - break; - - case 4: // EXC_EMULATION - exc_desc = "EXC_EMULATION"; - break; - - - case 5: // EXC_SOFTWARE - exc_desc = "EXC_SOFTWARE"; - if (m_exc_code == 0x10003) - { - subcode_desc = "EXC_SOFT_SIGNAL"; - subcode_label = "signo"; - } - break; - - case 6: // EXC_BREAKPOINT - { - exc_desc = "EXC_BREAKPOINT"; - switch (cpu) - { - case llvm::Triple::x86: - case llvm::Triple::x86_64: - switch (m_exc_code) - { - case 1: code_desc = "EXC_I386_SGL"; break; - case 2: code_desc = "EXC_I386_BPT"; break; - } - break; - - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - switch (m_exc_code) - { - case 1: code_desc = "EXC_PPC_BREAKPOINT"; break; - } - break; - - case llvm::Triple::arm: - switch (m_exc_code) - { - case 0x101: code_desc = "EXC_ARM_DA_ALIGN"; break; - case 0x102: code_desc = "EXC_ARM_DA_DEBUG"; break; - case 1: code_desc = "EXC_ARM_BREAKPOINT"; break; - } - break; - - default: - break; - } - } - break; - - case 7: - exc_desc = "EXC_SYSCALL"; - break; - - case 8: - exc_desc = "EXC_MACH_SYSCALL"; - break; - - case 9: - exc_desc = "EXC_RPC_ALERT"; - break; - - case 10: - exc_desc = "EXC_CRASH"; - break; - } - - StreamString strm; - - if (exc_desc) - strm.PutCString(exc_desc); - else - strm.Printf("EXC_??? (%llu)", m_value); - - if (m_exc_data_count >= 1) - { - if (code_desc) - strm.Printf(" (%s=%s", code_label, code_desc); - else - strm.Printf(" (%s=%llu", code_label, m_exc_code); - } - - if (m_exc_data_count >= 2) - { - if (subcode_desc) - strm.Printf(", %s=%s", subcode_label, subcode_desc); - else - strm.Printf(", %s=0x%llx", subcode_label, m_exc_subcode); - } - - if (m_exc_data_count > 0) - strm.PutChar(')'); - - m_description.swap (strm.GetString()); - } - return m_description.c_str(); -} - - -StopInfoSP -StopInfoMachException::CreateStopReasonWithMachException -( - Thread &thread, - uint32_t exc_type, - uint32_t exc_data_count, - uint64_t exc_code, - uint64_t exc_sub_code, - uint64_t exc_sub_sub_code -) -{ - if (exc_type != 0) - { - ExecutionContext exe_ctx (thread.shared_from_this()); - Target *target = exe_ctx.GetTargetPtr(); - const llvm::Triple::ArchType cpu = target ? target->GetArchitecture().GetMachine() : llvm::Triple::UnknownArch; - - switch (exc_type) - { - case 1: // EXC_BAD_ACCESS - break; - - case 2: // EXC_BAD_INSTRUCTION - switch (cpu) - { - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - switch (exc_code) - { - case 1: // EXC_PPC_INVALID_SYSCALL - case 2: // EXC_PPC_UNIPL_INST - case 3: // EXC_PPC_PRIVINST - case 4: // EXC_PPC_PRIVREG - break; - case 5: // EXC_PPC_TRACE - return StopInfo::CreateStopReasonToTrace (thread); - case 6: // EXC_PPC_PERFMON - break; - } - break; - - default: - break; - } - break; - - case 3: // EXC_ARITHMETIC - case 4: // EXC_EMULATION - break; - - case 5: // EXC_SOFTWARE - if (exc_code == 0x10003) // EXC_SOFT_SIGNAL - return StopInfo::CreateStopReasonWithSignal (thread, exc_sub_code); - break; - - case 6: // EXC_BREAKPOINT - { - bool is_software_breakpoint = false; - switch (cpu) - { - case llvm::Triple::x86: - case llvm::Triple::x86_64: - if (exc_code == 1) // EXC_I386_SGL - { - if (!exc_sub_code) - return StopInfo::CreateStopReasonToTrace(thread); - - // It's a watchpoint, then. - // The exc_sub_code indicates the data break address. - lldb::WatchpointSP wp_sp; - if (target) - wp_sp = target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code); - if (wp_sp && wp_sp->IsEnabled()) - { - // Debugserver may piggyback the hardware index of the fired watchpoint in the exception data. - // Set the hardware index if that's the case. - if (exc_data_count >=3) - wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code); - return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID()); - } - } - else if (exc_code == 2) // EXC_I386_BPT - { - is_software_breakpoint = true; - } - break; - - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - is_software_breakpoint = exc_code == 1; // EXC_PPC_BREAKPOINT - break; - - case llvm::Triple::arm: - if (exc_code == 0x102) - { - // It's a watchpoint, then, if the exc_sub_code indicates a known/enabled - // data break address from our watchpoint list. - lldb::WatchpointSP wp_sp; - if (target) - wp_sp = target->GetWatchpointList().FindByAddress((lldb::addr_t)exc_sub_code); - if (wp_sp && wp_sp->IsEnabled()) - { - // Debugserver may piggyback the hardware index of the fired watchpoint in the exception data. - // Set the hardware index if that's the case. - if (exc_data_count >=3) - wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code); - return StopInfo::CreateStopReasonWithWatchpointID(thread, wp_sp->GetID()); - } - // EXC_ARM_DA_DEBUG seems to be reused for EXC_BREAKPOINT as well as EXC_BAD_ACCESS - return StopInfo::CreateStopReasonToTrace(thread); - } - else - is_software_breakpoint = exc_code == 1; // EXC_ARM_BREAKPOINT - break; - - default: - break; - } - - if (is_software_breakpoint) - { - addr_t pc = thread.GetRegisterContext()->GetPC(); - ProcessSP process_sp (thread.CalculateProcess()); - - lldb::BreakpointSiteSP bp_site_sp; - if (process_sp) - bp_site_sp = process_sp->GetBreakpointSiteList().FindByAddress(pc); - if (bp_site_sp) - { - // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread, - // we can just report no reason. We don't need to worry about stepping over the breakpoint here, that - // will be taken care of when the thread resumes and notices that there's a breakpoint under the pc. - if (bp_site_sp->ValidForThisThread (&thread)) - return StopInfo::CreateStopReasonWithBreakpointSiteID (thread, bp_site_sp->GetID()); - else - return StopInfoSP(); - } - else if (cpu == llvm::Triple::arm) - { - return StopInfo::CreateStopReasonToTrace (thread); - } - } - } - break; - - case 7: // EXC_SYSCALL - case 8: // EXC_MACH_SYSCALL - case 9: // EXC_RPC_ALERT - case 10: // EXC_CRASH - break; - } - - return StopInfoSP(new StopInfoMachException (thread, exc_type, exc_data_count, exc_code, exc_sub_code)); - } - return StopInfoSP(); -} diff --git a/lldb/source/Plugins/Process/Utility/StopInfoMachException.h b/lldb/source/Plugins/Process/Utility/StopInfoMachException.h deleted file mode 100644 index a40bd71a91ad..000000000000 --- a/lldb/source/Plugins/Process/Utility/StopInfoMachException.h +++ /dev/null @@ -1,75 +0,0 @@ -//===-- StopInfoMachException.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_StopInfoMachException_h_ -#define liblldb_StopInfoMachException_h_ - -// C Includes -// C++ Includes -#include <string> - -// Other libraries and framework includes -// Project includes -#include "lldb/Target/StopInfo.h" - -namespace lldb_private { - -class StopInfoMachException : public StopInfo -{ -public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - StopInfoMachException (Thread &thread, - uint32_t exc_type, - uint32_t exc_data_count, - uint64_t exc_code, - uint64_t exc_subcode) : - StopInfo (thread, exc_type), - m_exc_data_count (exc_data_count), - m_exc_code (exc_code), - m_exc_subcode (exc_subcode) - { - } - - virtual ~StopInfoMachException() - { - } - - - virtual lldb::StopReason - GetStopReason () const - { - return lldb::eStopReasonException; - } - - virtual const char * - GetDescription (); - - // Since some mach exceptions will be reported as breakpoints, signals, - // or trace, we use this static accessor which will translate the mach - // exception into the correct StopInfo. - static lldb::StopInfoSP - CreateStopReasonWithMachException (Thread &thread, - uint32_t exc_type, - uint32_t exc_data_count, - uint64_t exc_code, - uint64_t exc_sub_code, - uint64_t exc_sub_sub_code); - -protected: - uint32_t m_exc_data_count; - uint64_t m_exc_code; - uint64_t m_exc_subcode; -}; - - -} // namespace lldb_private - -#endif // liblldb_StopInfoMachException_h_ diff --git a/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp b/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp deleted file mode 100644 index dfcc2b04f24f..000000000000 --- a/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp +++ /dev/null @@ -1,121 +0,0 @@ -//===-- ThreadMemory.cpp ----------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "Plugins/Process/Utility/ThreadMemory.h" -#include "lldb/Target/OperatingSystem.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/StopInfo.h" -#include "lldb/Target/Unwind.h" - -using namespace lldb; -using namespace lldb_private; - -ThreadMemory::ThreadMemory (const ProcessSP &process_sp, - tid_t tid, - const ValueObjectSP &thread_info_valobj_sp) : - Thread (process_sp, tid), - m_thread_info_valobj_sp (thread_info_valobj_sp) -{ -} - - -ThreadMemory::~ThreadMemory() -{ - DestroyThread(); -} - -bool -ThreadMemory::WillResume (StateType resume_state) -{ - ClearStackFrames(); - // Call the Thread::WillResume first. If we stop at a signal, the stop info - // class for signal will set the resume signal that we need below. The signal - // stuff obeys the Process::UnixSignal defaults. - Thread::WillResume(resume_state); - return true; -} - -RegisterContextSP -ThreadMemory::GetRegisterContext () -{ - if (!m_reg_context_sp) - { - ProcessSP process_sp (GetProcess()); - if (process_sp) - { - OperatingSystem *os = process_sp->GetOperatingSystem (); - if (os) - m_reg_context_sp = os->CreateRegisterContextForThread (this); - } - } - return m_reg_context_sp; -} - -RegisterContextSP -ThreadMemory::CreateRegisterContextForFrame (StackFrame *frame) -{ - RegisterContextSP reg_ctx_sp; - uint32_t concrete_frame_idx = 0; - - if (frame) - concrete_frame_idx = frame->GetConcreteFrameIndex (); - - if (concrete_frame_idx == 0) - { - reg_ctx_sp = GetRegisterContext (); - } - else if (m_unwinder_ap.get()) - { - reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame); - } - return reg_ctx_sp; -} - -lldb::StopInfoSP -ThreadMemory::GetPrivateStopReason () -{ - ProcessSP process_sp (GetProcess()); - - if (process_sp) - { - const uint32_t process_stop_id = process_sp->GetStopID(); - if (m_thread_stop_reason_stop_id != process_stop_id || - (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid())) - { - // If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason - // for this thread, then m_actual_stop_info_sp will not ever contain - // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false" - // check will never be able to tell us if we have the correct stop info - // for this thread and we will continually send qThreadStopInfo packets - // down to the remote GDB server, so we need to keep our own notion - // of the stop ID that m_actual_stop_info_sp is valid for (even if it - // contains nothing). We use m_thread_stop_reason_stop_id for this below. - m_thread_stop_reason_stop_id = process_stop_id; - m_actual_stop_info_sp.reset(); - - OperatingSystem *os = process_sp->GetOperatingSystem (); - if (os) - m_actual_stop_info_sp = os->CreateThreadStopReason (this); - } - } - return m_actual_stop_info_sp; - -} - -void -ThreadMemory::RefreshStateAfterStop() -{ - RegisterContextSP reg_ctx_sp(GetRegisterContext()); - if (reg_ctx_sp) - { - const bool force = true; - reg_ctx_sp->InvalidateIfNeeded (force); - } -} diff --git a/lldb/source/Plugins/Process/Utility/ThreadMemory.h b/lldb/source/Plugins/Process/Utility/ThreadMemory.h deleted file mode 100644 index 96b40a081435..000000000000 --- a/lldb/source/Plugins/Process/Utility/ThreadMemory.h +++ /dev/null @@ -1,64 +0,0 @@ -//===-- ThreadMemory.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_ThreadMemory_h_ -#define liblldb_ThreadMemory_h_ - -#include "lldb/Target/Thread.h" - -class ThreadMemory : - public lldb_private::Thread -{ -public: - - ThreadMemory (const lldb::ProcessSP &process_sp, - lldb::tid_t tid, - const lldb::ValueObjectSP &thread_info_valobj_sp); - - virtual - ~ThreadMemory(); - - //------------------------------------------------------------------ - // lldb_private::Thread methods - //------------------------------------------------------------------ - virtual void - RefreshStateAfterStop(); - - virtual lldb::RegisterContextSP - GetRegisterContext (); - - virtual lldb::RegisterContextSP - CreateRegisterContextForFrame (lldb_private::StackFrame *frame); - - virtual lldb::StopInfoSP - GetPrivateStopReason (); - - virtual bool - WillResume (lldb::StateType resume_state); - - lldb::ValueObjectSP & - GetValueObject () - { - return m_thread_info_valobj_sp; - } - -protected: - //------------------------------------------------------------------ - // For ThreadMemory and subclasses - //------------------------------------------------------------------ - lldb::ValueObjectSP m_thread_info_valobj_sp; - -private: - //------------------------------------------------------------------ - // For ThreadMemory only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (ThreadMemory); -}; - -#endif // liblldb_ThreadMemory_h_ diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp deleted file mode 100644 index b993c95325c8..000000000000 --- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp +++ /dev/null @@ -1,277 +0,0 @@ -//===-- UnwindLLDB.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/Core/Module.h" -#include "lldb/Core/Log.h" -#include "lldb/Symbol/FuncUnwinders.h" -#include "lldb/Symbol/Function.h" -#include "lldb/Symbol/UnwindPlan.h" -#include "lldb/Target/Thread.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/RegisterContext.h" - -#include "UnwindLLDB.h" -#include "RegisterContextLLDB.h" - -using namespace lldb; -using namespace lldb_private; - -UnwindLLDB::UnwindLLDB (Thread &thread) : - Unwind (thread), - m_frames(), - m_unwind_complete(false) -{ -} - -uint32_t -UnwindLLDB::DoGetFrameCount() -{ - if (!m_unwind_complete) - { -//#define DEBUG_FRAME_SPEED 1 -#if DEBUG_FRAME_SPEED -#define FRAME_COUNT 10000 - TimeValue time_value (TimeValue::Now()); -#endif - if (!AddFirstFrame ()) - return 0; - - ProcessSP process_sp (m_thread.GetProcess()); - ABI *abi = process_sp ? process_sp->GetABI().get() : NULL; - - while (AddOneMoreFrame (abi)) - { -#if DEBUG_FRAME_SPEED - if ((m_frames.size() % FRAME_COUNT) == 0) - { - TimeValue now(TimeValue::Now()); - uint64_t delta_t = now - time_value; - printf ("%u frames in %llu.%09llu ms (%g frames/sec)\n", - FRAME_COUNT, - delta_t / TimeValue::NanoSecPerSec, - delta_t % TimeValue::NanoSecPerSec, - (float)FRAME_COUNT / ((float)delta_t / (float)TimeValue::NanoSecPerSec)); - time_value = now; - } -#endif - } - } - return m_frames.size (); -} - -bool -UnwindLLDB::AddFirstFrame () -{ - if (m_frames.size() > 0) - return true; - - // First, set up the 0th (initial) frame - CursorSP first_cursor_sp(new Cursor ()); - RegisterContextLLDBSP reg_ctx_sp (new RegisterContextLLDB (m_thread, - RegisterContextLLDBSP(), - first_cursor_sp->sctx, - 0, *this)); - if (reg_ctx_sp.get() == NULL) - goto unwind_done; - - if (!reg_ctx_sp->IsValid()) - goto unwind_done; - - if (!reg_ctx_sp->GetCFA (first_cursor_sp->cfa)) - goto unwind_done; - - if (!reg_ctx_sp->ReadPC (first_cursor_sp->start_pc)) - goto unwind_done; - - // Everything checks out, so release the auto pointer value and let the - // cursor own it in its shared pointer - first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; - m_frames.push_back (first_cursor_sp); - return true; -unwind_done: - m_unwind_complete = true; - return false; -} - -// For adding a non-zero stack frame to m_frames. -bool -UnwindLLDB::AddOneMoreFrame (ABI *abi) -{ - // If we've already gotten to the end of the stack, don't bother to try again... - if (m_unwind_complete) - return false; - - LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); - CursorSP cursor_sp(new Cursor ()); - - // Frame zero is a little different - if (m_frames.size() == 0) - return false; - - uint32_t cur_idx = m_frames.size (); - RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB (m_thread, - m_frames[cur_idx - 1]->reg_ctx_lldb_sp, - cursor_sp->sctx, - cur_idx, - *this)); - if (reg_ctx_sp.get() == NULL) - goto unwind_done; - - if (!reg_ctx_sp->IsValid()) - { - if (log) - { - log->Printf("%*sFrame %d invalid RegisterContext for this frame, stopping stack walk", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); - } - goto unwind_done; - } - if (!reg_ctx_sp->GetCFA (cursor_sp->cfa)) - { - if (log) - { - log->Printf("%*sFrame %d did not get CFA for this frame, stopping stack walk", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); - } - goto unwind_done; - } - if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) - { - if (log) - { - log->Printf("%*sFrame %d did not get a valid CFA for this frame, stopping stack walk", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); - } - goto unwind_done; - } - if (!reg_ctx_sp->ReadPC (cursor_sp->start_pc)) - { - if (log) - { - log->Printf("%*sFrame %d did not get PC for this frame, stopping stack walk", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); - } - goto unwind_done; - } - if (abi && !abi->CodeAddressIsValid (cursor_sp->start_pc)) - { - if (log) - { - log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk", - cur_idx < 100 ? cur_idx : 100, "", cur_idx); - } - goto unwind_done; - } - if (!m_frames.empty()) - { - if (m_frames.back()->start_pc == cursor_sp->start_pc) - { - if (m_frames.back()->cfa == cursor_sp->cfa) - goto unwind_done; // Infinite loop where the current cursor is the same as the previous one... - else if (abi->StackUsesFrames()) - { - // We might have a CFA that is not using the frame pointer and - // we want to validate that the frame pointer is valid. - if (reg_ctx_sp->GetFP() == 0) - goto unwind_done; - } - } - } - cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; - m_frames.push_back (cursor_sp); - return true; - -unwind_done: - m_unwind_complete = true; - return false; -} - -bool -UnwindLLDB::DoGetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr_t& pc) -{ - if (m_frames.size() == 0) - { - if (!AddFirstFrame()) - return false; - } - - ProcessSP process_sp (m_thread.GetProcess()); - ABI *abi = process_sp ? process_sp->GetABI().get() : NULL; - - while (idx >= m_frames.size() && AddOneMoreFrame (abi)) - ; - - if (idx < m_frames.size ()) - { - cfa = m_frames[idx]->cfa; - pc = m_frames[idx]->start_pc; - return true; - } - return false; -} - -lldb::RegisterContextSP -UnwindLLDB::DoCreateRegisterContextForFrame (StackFrame *frame) -{ - lldb::RegisterContextSP reg_ctx_sp; - uint32_t idx = frame->GetConcreteFrameIndex (); - - if (idx == 0) - { - return m_thread.GetRegisterContext(); - } - - if (m_frames.size() == 0) - { - if (!AddFirstFrame()) - return reg_ctx_sp; - } - - ProcessSP process_sp (m_thread.GetProcess()); - ABI *abi = process_sp ? process_sp->GetABI().get() : NULL; - - while (idx >= m_frames.size()) - { - if (!AddOneMoreFrame (abi)) - break; - } - - const uint32_t num_frames = m_frames.size(); - if (idx < num_frames) - { - Cursor *frame_cursor = m_frames[idx].get(); - reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp; - } - return reg_ctx_sp; -} - -UnwindLLDB::RegisterContextLLDBSP -UnwindLLDB::GetRegisterContextForFrameNum (uint32_t frame_num) -{ - RegisterContextLLDBSP reg_ctx_sp; - if (frame_num < m_frames.size()) - reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp; - return reg_ctx_sp; -} - -bool -UnwindLLDB::SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, uint32_t starting_frame_num) -{ - int64_t frame_num = starting_frame_num; - if (frame_num >= m_frames.size()) - return false; - while (frame_num >= 0) - { - if (m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc, false)) - return true; - frame_num--; - } - return false; -} diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h deleted file mode 100644 index 7d1c8a1f1466..000000000000 --- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h +++ /dev/null @@ -1,118 +0,0 @@ -//===-- UnwindLLDB.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_UnwindLLDB_h_ -#define lldb_UnwindLLDB_h_ - -#include <vector> - -#include "lldb/lldb-public.h" -#include "lldb/Symbol/FuncUnwinders.h" -#include "lldb/Symbol/UnwindPlan.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Target/Unwind.h" - -namespace lldb_private { - -class RegisterContextLLDB; - -class UnwindLLDB : public lldb_private::Unwind -{ -public: - UnwindLLDB (lldb_private::Thread &thread); - - virtual - ~UnwindLLDB() { } - -protected: - friend class lldb_private::RegisterContextLLDB; - - struct RegisterLocation { - enum RegisterLocationTypes - { - eRegisterNotSaved = 0, // register was not preserved by callee. If volatile reg, is unavailable - eRegisterSavedAtMemoryLocation, // register is saved at a specific word of target mem (target_memory_location) - eRegisterInRegister, // register is available in a (possible other) register (register_number) - eRegisterSavedAtHostMemoryLocation, // register is saved at a word in lldb's address space - eRegisterValueInferred // register val was computed (and is in inferred_value) - }; - int type; - union - { - lldb::addr_t target_memory_location; - uint32_t register_number; // in eRegisterKindLLDB register numbering system - void* host_memory_location; - uint64_t inferred_value; // eRegisterValueInferred - e.g. stack pointer == cfa + offset - } location; - }; - - void - DoClear() - { - m_frames.clear(); - m_unwind_complete = false; - } - - virtual uint32_t - DoGetFrameCount(); - - bool - DoGetFrameInfoAtIndex (uint32_t frame_idx, - lldb::addr_t& cfa, - lldb::addr_t& start_pc); - - lldb::RegisterContextSP - DoCreateRegisterContextForFrame (lldb_private::StackFrame *frame); - - typedef STD_SHARED_PTR(RegisterContextLLDB) RegisterContextLLDBSP; - - // Needed to retrieve the "next" frame (e.g. frame 2 needs to retrieve frame 1's RegisterContextLLDB) - // The RegisterContext for frame_num must already exist or this returns an empty shared pointer. - RegisterContextLLDBSP - GetRegisterContextForFrameNum (uint32_t frame_num); - - // Iterate over the RegisterContextLLDB's in our m_frames vector, look for the first one that - // has a saved location for this reg. - bool - SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, uint32_t starting_frame_num); - - -private: - - struct Cursor - { - lldb::addr_t start_pc; // The start address of the function/symbol for this frame - current pc if unknown - lldb::addr_t cfa; // The canonical frame address for this stack frame - lldb_private::SymbolContext sctx; // A symbol context we'll contribute to & provide to the StackFrame creation - RegisterContextLLDBSP reg_ctx_lldb_sp; // These are all RegisterContextLLDB's - - Cursor () : start_pc (LLDB_INVALID_ADDRESS), cfa (LLDB_INVALID_ADDRESS), sctx(), reg_ctx_lldb_sp() { } - private: - DISALLOW_COPY_AND_ASSIGN (Cursor); - }; - - typedef STD_SHARED_PTR(Cursor) CursorSP; - std::vector<CursorSP> m_frames; - bool m_unwind_complete; // If this is true, we've enumerated all the frames in the stack, and m_frames.size() is the - // number of frames, etc. Otherwise we've only gone as far as directly asked, and m_frames.size() - // is how far we've currently gone. - - - bool AddOneMoreFrame (ABI *abi); - bool AddFirstFrame (); - - //------------------------------------------------------------------ - // For UnwindLLDB only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (UnwindLLDB); -}; - -} // namespace lldb_private - -#endif // lldb_UnwindLLDB_h_ diff --git a/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp b/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp deleted file mode 100644 index 90913b961d5f..000000000000 --- a/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp +++ /dev/null @@ -1,272 +0,0 @@ -//===-- UnwindMacOSXFrameBackchain.cpp --------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/ArchSpec.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/Thread.h" - -#include "RegisterContextMacOSXFrameBackchain.h" - -using namespace lldb; -using namespace lldb_private; - -UnwindMacOSXFrameBackchain::UnwindMacOSXFrameBackchain (Thread &thread) : - Unwind (thread), - m_cursors() -{ -} - -uint32_t -UnwindMacOSXFrameBackchain::DoGetFrameCount() -{ - if (m_cursors.empty()) - { - ExecutionContext exe_ctx (m_thread.shared_from_this()); - Target *target = exe_ctx.GetTargetPtr(); - if (target) - { - const ArchSpec& target_arch = target->GetArchitecture (); - // Frame zero should always be supplied by the thread... - exe_ctx.SetFrameSP (m_thread.GetStackFrameAtIndex (0)); - - if (target_arch.GetAddressByteSize() == 8) - GetStackFrameData_x86_64 (exe_ctx); - else - GetStackFrameData_i386 (exe_ctx); - } - } - return m_cursors.size(); -} - -bool -UnwindMacOSXFrameBackchain::DoGetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr_t& pc) -{ - const uint32_t frame_count = GetFrameCount(); - if (idx < frame_count) - { - if (m_cursors[idx].pc == LLDB_INVALID_ADDRESS) - return false; - if (m_cursors[idx].fp == LLDB_INVALID_ADDRESS) - return false; - - pc = m_cursors[idx].pc; - cfa = m_cursors[idx].fp; - - return true; - } - return false; -} - -lldb::RegisterContextSP -UnwindMacOSXFrameBackchain::DoCreateRegisterContextForFrame (StackFrame *frame) -{ - lldb::RegisterContextSP reg_ctx_sp; - uint32_t concrete_idx = frame->GetConcreteFrameIndex (); - const uint32_t frame_count = GetFrameCount(); - if (concrete_idx < frame_count) - reg_ctx_sp.reset (new RegisterContextMacOSXFrameBackchain (m_thread, concrete_idx, m_cursors[concrete_idx])); - return reg_ctx_sp; -} - -size_t -UnwindMacOSXFrameBackchain::GetStackFrameData_i386 (const ExecutionContext &exe_ctx) -{ - m_cursors.clear(); - - StackFrame *first_frame = exe_ctx.GetFramePtr(); - - Process *process = exe_ctx.GetProcessPtr(); - if (process == NULL) - return 0; - - std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair; - - struct Frame_i386 - { - uint32_t fp; - uint32_t pc; - }; - - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); - assert (reg_ctx); - - Cursor cursor; - cursor.pc = reg_ctx->GetPC (LLDB_INVALID_ADDRESS); - cursor.fp = reg_ctx->GetFP (0); - - Frame_i386 frame = { static_cast<uint32_t>(cursor.fp), static_cast<uint32_t>(cursor.pc) }; - - m_cursors.push_back(cursor); - - const size_t k_frame_size = sizeof(frame); - Error error; - while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0)) - { - // Read both the FP and PC (8 bytes) - if (process->ReadMemory (frame.fp, &frame.fp, k_frame_size, error) != k_frame_size) - break; - if (frame.pc >= 0x1000) - { - cursor.pc = frame.pc; - cursor.fp = frame.fp; - m_cursors.push_back (cursor); - } - } - if (!m_cursors.empty()) - { - lldb::addr_t first_frame_pc = m_cursors.front().pc; - if (first_frame_pc != LLDB_INVALID_ADDRESS) - { - const uint32_t resolve_scope = eSymbolContextModule | - eSymbolContextCompUnit | - eSymbolContextFunction | - eSymbolContextSymbol; - - SymbolContext first_frame_sc (first_frame->GetSymbolContext(resolve_scope)); - const AddressRange *addr_range_ptr = NULL; - AddressRange range; - if (first_frame_sc.function) - addr_range_ptr = &first_frame_sc.function->GetAddressRange(); - else if (first_frame_sc.symbol) - { - range.GetBaseAddress() = first_frame_sc.symbol->GetAddress(); - range.SetByteSize (first_frame_sc.symbol->GetByteSize()); - addr_range_ptr = ⦥ - } - - if (addr_range_ptr) - { - if (first_frame->GetFrameCodeAddress() == addr_range_ptr->GetBaseAddress()) - { - // We are at the first instruction, so we can recover the - // previous PC by dereferencing the SP - lldb::addr_t first_frame_sp = reg_ctx->GetSP (0); - // Read the real second frame return address into frame.pc - if (first_frame_sp && process->ReadMemory (first_frame_sp, &frame.pc, sizeof(frame.pc), error) == sizeof(frame.pc)) - { - cursor.fp = m_cursors.front().fp; - cursor.pc = frame.pc; // Set the new second frame PC - - // Insert the second frame - m_cursors.insert(m_cursors.begin()+1, cursor); - - m_cursors.front().fp = first_frame_sp; - } - } - } - } - } -// uint32_t i=0; -// printf(" PC FP\n"); -// printf(" ------------------ ------------------ \n"); -// for (i=0; i<m_cursors.size(); ++i) -// { -// printf("[%3u] 0x%16.16llx 0x%16.16llx\n", i, m_cursors[i].pc, m_cursors[i].fp); -// } - return m_cursors.size(); -} - - -size_t -UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64 (const ExecutionContext &exe_ctx) -{ - m_cursors.clear(); - - Process *process = exe_ctx.GetProcessPtr(); - if (process == NULL) - return 0; - - StackFrame *first_frame = exe_ctx.GetFramePtr(); - - std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair; - - struct Frame_x86_64 - { - uint64_t fp; - uint64_t pc; - }; - - RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); - assert (reg_ctx); - - Cursor cursor; - cursor.pc = reg_ctx->GetPC (LLDB_INVALID_ADDRESS); - cursor.fp = reg_ctx->GetFP (0); - - Frame_x86_64 frame = { cursor.fp, cursor.pc }; - - m_cursors.push_back(cursor); - Error error; - const size_t k_frame_size = sizeof(frame); - while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0)) - { - // Read both the FP and PC (16 bytes) - if (process->ReadMemory (frame.fp, &frame.fp, k_frame_size, error) != k_frame_size) - break; - - if (frame.pc >= 0x1000) - { - cursor.pc = frame.pc; - cursor.fp = frame.fp; - m_cursors.push_back (cursor); - } - } - if (!m_cursors.empty()) - { - lldb::addr_t first_frame_pc = m_cursors.front().pc; - if (first_frame_pc != LLDB_INVALID_ADDRESS) - { - const uint32_t resolve_scope = eSymbolContextModule | - eSymbolContextCompUnit | - eSymbolContextFunction | - eSymbolContextSymbol; - - SymbolContext first_frame_sc(first_frame->GetSymbolContext(resolve_scope)); - const AddressRange *addr_range_ptr = NULL; - AddressRange range; - if (first_frame_sc.function) - addr_range_ptr = &first_frame_sc.function->GetAddressRange(); - else if (first_frame_sc.symbol) - { - range.GetBaseAddress() = first_frame_sc.symbol->GetAddress(); - range.SetByteSize (first_frame_sc.symbol->GetByteSize()); - addr_range_ptr = ⦥ - } - - if (addr_range_ptr) - { - if (first_frame->GetFrameCodeAddress() == addr_range_ptr->GetBaseAddress()) - { - // We are at the first instruction, so we can recover the - // previous PC by dereferencing the SP - lldb::addr_t first_frame_sp = reg_ctx->GetSP (0); - // Read the real second frame return address into frame.pc - if (process->ReadMemory (first_frame_sp, &frame.pc, sizeof(frame.pc), error) == sizeof(frame.pc)) - { - cursor.fp = m_cursors.front().fp; - cursor.pc = frame.pc; // Set the new second frame PC - - // Insert the second frame - m_cursors.insert(m_cursors.begin()+1, cursor); - - m_cursors.front().fp = first_frame_sp; - } - } - } - } - } - return m_cursors.size(); -} - diff --git a/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h b/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h deleted file mode 100644 index 2695376fd6e0..000000000000 --- a/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h +++ /dev/null @@ -1,74 +0,0 @@ -//===-- UnwindMacOSXFrameBackchain.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_UnwindMacOSXFrameBackchain_h_ -#define lldb_UnwindMacOSXFrameBackchain_h_ - -// C Includes -// C++ Includes -#include <vector> - -// Other libraries and framework includes - -// Project includes -#include "lldb/lldb-private.h" -#include "lldb/Target/Unwind.h" - -class UnwindMacOSXFrameBackchain : public lldb_private::Unwind -{ -public: - UnwindMacOSXFrameBackchain (lldb_private::Thread &thread); - - virtual - ~UnwindMacOSXFrameBackchain() - { - } - -protected: - virtual void - DoClear() - { - m_cursors.clear(); - } - - virtual uint32_t - DoGetFrameCount(); - - bool - DoGetFrameInfoAtIndex (uint32_t frame_idx, - lldb::addr_t& cfa, - lldb::addr_t& pc); - - lldb::RegisterContextSP - DoCreateRegisterContextForFrame (lldb_private::StackFrame *frame); - - friend class RegisterContextMacOSXFrameBackchain; - - struct Cursor - { - lldb::addr_t pc; // Program counter - lldb::addr_t fp; // Frame pointer for us with backchain - }; - -private: - std::vector<Cursor> m_cursors; - - size_t - GetStackFrameData_i386 (const lldb_private::ExecutionContext &exe_ctx); - - size_t - GetStackFrameData_x86_64 (const lldb_private::ExecutionContext &exe_ctx); - - //------------------------------------------------------------------ - // For UnwindMacOSXFrameBackchain only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (UnwindMacOSXFrameBackchain); -}; - -#endif // lldb_UnwindMacOSXFrameBackchain_h_ diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp deleted file mode 100644 index a6d2d114da94..000000000000 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ /dev/null @@ -1,641 +0,0 @@ -//===-- GDBRemoteCommunication.cpp ------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - - -#include "GDBRemoteCommunication.h" - -// C Includes -#include <limits.h> -#include <string.h> - -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/Log.h" -#include "lldb/Core/StreamFile.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Host/FileSpec.h" -#include "lldb/Host/Host.h" -#include "lldb/Host/TimeValue.h" -#include "lldb/Target/Process.h" - -// Project includes -#include "ProcessGDBRemoteLog.h" - -#define DEBUGSERVER_BASENAME "debugserver" - -using namespace lldb; -using namespace lldb_private; - -GDBRemoteCommunication::History::History (uint32_t size) : - m_packets(), - m_curr_idx (0), - m_total_packet_count (0), - m_dumped_to_log (false) -{ - m_packets.resize(size); -} - -GDBRemoteCommunication::History::~History () -{ -} - -void -GDBRemoteCommunication::History::AddPacket (char packet_char, - PacketType type, - uint32_t bytes_transmitted) -{ - const size_t size = m_packets.size(); - if (size > 0) - { - const uint32_t idx = GetNextIndex(); - m_packets[idx].packet.assign (1, packet_char); - m_packets[idx].type = type; - m_packets[idx].bytes_transmitted = bytes_transmitted; - m_packets[idx].packet_idx = m_total_packet_count; - m_packets[idx].tid = Host::GetCurrentThreadID(); - } -} - -void -GDBRemoteCommunication::History::AddPacket (const std::string &src, - uint32_t src_len, - PacketType type, - uint32_t bytes_transmitted) -{ - const size_t size = m_packets.size(); - if (size > 0) - { - const uint32_t idx = GetNextIndex(); - m_packets[idx].packet.assign (src, 0, src_len); - m_packets[idx].type = type; - m_packets[idx].bytes_transmitted = bytes_transmitted; - m_packets[idx].packet_idx = m_total_packet_count; - m_packets[idx].tid = Host::GetCurrentThreadID(); - } -} - -void -GDBRemoteCommunication::History::Dump (lldb_private::Stream &strm) const -{ - const uint32_t size = GetNumPacketsInHistory (); - const uint32_t first_idx = GetFirstSavedPacketIndex (); - const uint32_t stop_idx = m_curr_idx + size; - for (uint32_t i = first_idx; i < stop_idx; ++i) - { - const uint32_t idx = NormalizeIndex (i); - const Entry &entry = m_packets[idx]; - if (entry.type == ePacketTypeInvalid || entry.packet.empty()) - break; - strm.Printf ("history[%u] tid=0x%4.4llx <%4u> %s packet: %s\n", - entry.packet_idx, - entry.tid, - entry.bytes_transmitted, - (entry.type == ePacketTypeSend) ? "send" : "read", - entry.packet.c_str()); - } -} - -void -GDBRemoteCommunication::History::Dump (lldb_private::Log *log) const -{ - if (log && !m_dumped_to_log) - { - m_dumped_to_log = true; - const uint32_t size = GetNumPacketsInHistory (); - const uint32_t first_idx = GetFirstSavedPacketIndex (); - const uint32_t stop_idx = m_curr_idx + size; - for (uint32_t i = first_idx; i < stop_idx; ++i) - { - const uint32_t idx = NormalizeIndex (i); - const Entry &entry = m_packets[idx]; - if (entry.type == ePacketTypeInvalid || entry.packet.empty()) - break; - log->Printf ("history[%u] tid=0x%4.4llx <%4u> %s packet: %s", - entry.packet_idx, - entry.tid, - entry.bytes_transmitted, - (entry.type == ePacketTypeSend) ? "send" : "read", - entry.packet.c_str()); - } - } -} - -//---------------------------------------------------------------------- -// GDBRemoteCommunication constructor -//---------------------------------------------------------------------- -GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, - const char *listener_name, - bool is_platform) : - Communication(comm_name), - m_packet_timeout (1), - m_sequence_mutex (Mutex::eMutexTypeRecursive), - m_public_is_running (false), - m_private_is_running (false), - m_history (512), - m_send_acks (true), - m_is_platform (is_platform) -{ -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -GDBRemoteCommunication::~GDBRemoteCommunication() -{ - if (IsConnected()) - { - Disconnect(); - } -} - -char -GDBRemoteCommunication::CalculcateChecksum (const char *payload, size_t payload_length) -{ - int checksum = 0; - - // We only need to compute the checksum if we are sending acks - if (GetSendAcks ()) - { - for (size_t i = 0; i < payload_length; ++i) - checksum += payload[i]; - } - return checksum & 255; -} - -size_t -GDBRemoteCommunication::SendAck () -{ - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); - ConnectionStatus status = eConnectionStatusSuccess; - char ch = '+'; - const size_t bytes_written = Write (&ch, 1, status, NULL); - if (log) - log->Printf ("<%4zu> send packet: %c", bytes_written, ch); - m_history.AddPacket (ch, History::ePacketTypeSend, bytes_written); - return bytes_written; -} - -size_t -GDBRemoteCommunication::SendNack () -{ - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); - ConnectionStatus status = eConnectionStatusSuccess; - char ch = '-'; - const size_t bytes_written = Write (&ch, 1, status, NULL); - if (log) - log->Printf ("<%4zu> send packet: %c", bytes_written, ch); - m_history.AddPacket (ch, History::ePacketTypeSend, bytes_written); - return bytes_written; -} - -size_t -GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length) -{ - Mutex::Locker locker(m_sequence_mutex); - return SendPacketNoLock (payload, payload_length); -} - -size_t -GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length) -{ - if (IsConnected()) - { - StreamString packet(0, 4, eByteOrderBig); - - packet.PutChar('$'); - packet.Write (payload, payload_length); - packet.PutChar('#'); - packet.PutHex8(CalculcateChecksum (payload, payload_length)); - - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); - ConnectionStatus status = eConnectionStatusSuccess; - size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL); - if (log) - { - // If logging was just enabled and we have history, then dump out what - // we have to the log so we get the historical context. The Dump() call that - // logs all of the packet will set a boolean so that we don't dump this more - // than once - if (!m_history.DidDumpToLog ()) - m_history.Dump (log.get()); - - log->Printf ("<%4zu> send packet: %.*s", bytes_written, (int)packet.GetSize(), packet.GetData()); - } - - m_history.AddPacket (packet.GetString(), packet.GetSize(), History::ePacketTypeSend, bytes_written); - - - if (bytes_written == packet.GetSize()) - { - if (GetSendAcks ()) - { - if (GetAck () != '+') - { - printf("get ack failed..."); - return 0; - } - } - } - else - { - if (log) - log->Printf ("error: failed to send packet: %.*s", (int)packet.GetSize(), packet.GetData()); - } - return bytes_written; - } - return 0; -} - -char -GDBRemoteCommunication::GetAck () -{ - StringExtractorGDBRemote packet; - if (WaitForPacketWithTimeoutMicroSecondsNoLock (packet, GetPacketTimeoutInMicroSeconds ()) == 1) - return packet.GetChar(); - return 0; -} - -bool -GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker) -{ - return locker.TryLock (m_sequence_mutex.GetMutex()); -} - - -bool -GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr) -{ - return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL); -} - -size_t -GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &packet, uint32_t timeout_usec) -{ - uint8_t buffer[8192]; - Error error; - - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE)); - - // Check for a packet from our cache first without trying any reading... - if (CheckForPacket (NULL, 0, packet)) - return packet.GetStringRef().size(); - - bool timed_out = false; - while (IsConnected() && !timed_out) - { - lldb::ConnectionStatus status = eConnectionStatusNoConnection; - size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error); - - if (log) - log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %zu", - __PRETTY_FUNCTION__, - timeout_usec, - Communication::ConnectionStatusAsCString (status), - error.AsCString(), - bytes_read); - - if (bytes_read > 0) - { - if (CheckForPacket (buffer, bytes_read, packet)) - return packet.GetStringRef().size(); - } - else - { - switch (status) - { - 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 -GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, StringExtractorGDBRemote &packet) -{ - // Put the packet data into the buffer in a thread safe fashion - Mutex::Locker locker(m_bytes_mutex); - - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); - - if (src && src_len > 0) - { - if (log && log->GetVerbose()) - { - StreamString s; - log->Printf ("GDBRemoteCommunication::%s adding %u bytes: %.*s", - __FUNCTION__, - (uint32_t)src_len, - (uint32_t)src_len, - src); - } - m_bytes.append ((const char *)src, src_len); - } - - // Parse up the packets into gdb remote packets - if (!m_bytes.empty()) - { - // end_idx must be one past the last valid packet byte. Start - // it off with an invalid value that is the same as the current - // index. - size_t content_start = 0; - size_t content_length = 0; - size_t total_length = 0; - size_t checksum_idx = std::string::npos; - - switch (m_bytes[0]) - { - case '+': // Look for ack - case '-': // Look for cancel - case '\x03': // ^C to halt target - content_length = total_length = 1; // The command is one byte long... - break; - - case '$': - // Look for a standard gdb packet? - { - size_t hash_pos = m_bytes.find('#'); - if (hash_pos != std::string::npos) - { - if (hash_pos + 2 < m_bytes.size()) - { - checksum_idx = hash_pos + 1; - // Skip the dollar sign - content_start = 1; - // Don't include the # in the content or the $ in the content length - content_length = hash_pos - 1; - - total_length = hash_pos + 3; // Skip the # and the two hex checksum bytes - } - else - { - // Checksum bytes aren't all here yet - content_length = std::string::npos; - } - } - } - break; - - default: - { - // We have an unexpected byte and we need to flush all bad - // data that is in m_bytes, so we need to find the first - // byte that is a '+' (ACK), '-' (NACK), \x03 (CTRL+C interrupt), - // or '$' character (start of packet header) or of course, - // the end of the data in m_bytes... - const size_t bytes_len = m_bytes.size(); - bool done = false; - uint32_t idx; - for (idx = 1; !done && idx < bytes_len; ++idx) - { - switch (m_bytes[idx]) - { - case '+': - case '-': - case '\x03': - case '$': - done = true; - break; - - default: - break; - } - } - if (log) - log->Printf ("GDBRemoteCommunication::%s tossing %u junk bytes: '%.*s'", - __FUNCTION__, idx, idx, m_bytes.c_str()); - m_bytes.erase(0, idx); - } - break; - } - - if (content_length == std::string::npos) - { - packet.Clear(); - return false; - } - else if (total_length > 0) - { - - // We have a valid packet... - assert (content_length <= m_bytes.size()); - assert (total_length <= m_bytes.size()); - assert (content_length <= total_length); - - bool success = true; - std::string &packet_str = packet.GetStringRef(); - - - if (log) - { - // If logging was just enabled and we have history, then dump out what - // we have to the log so we get the historical context. The Dump() call that - // logs all of the packet will set a boolean so that we don't dump this more - // than once - if (!m_history.DidDumpToLog ()) - m_history.Dump (log.get()); - - log->Printf ("<%4zu> read packet: %.*s", total_length, (int)(total_length), m_bytes.c_str()); - } - - m_history.AddPacket (m_bytes.c_str(), total_length, History::ePacketTypeRecv, total_length); - - packet_str.assign (m_bytes, content_start, content_length); - - if (m_bytes[0] == '$') - { - assert (checksum_idx < m_bytes.size()); - if (::isxdigit (m_bytes[checksum_idx+0]) || - ::isxdigit (m_bytes[checksum_idx+1])) - { - if (GetSendAcks ()) - { - const char *packet_checksum_cstr = &m_bytes[checksum_idx]; - char packet_checksum = strtol (packet_checksum_cstr, NULL, 16); - char actual_checksum = CalculcateChecksum (packet_str.c_str(), packet_str.size()); - success = packet_checksum == actual_checksum; - if (!success) - { - if (log) - log->Printf ("error: checksum mismatch: %.*s expected 0x%2.2x, got 0x%2.2x", - (int)(total_length), - m_bytes.c_str(), - (uint8_t)packet_checksum, - (uint8_t)actual_checksum); - } - // Send the ack or nack if needed - if (!success) - SendNack(); - else - SendAck(); - } - } - else - { - success = false; - if (log) - log->Printf ("error: invalid checksum in packet: '%s'\n", m_bytes.c_str()); - } - } - - m_bytes.erase(0, total_length); - packet.SetFilePos(0); - return success; - } - } - packet.Clear(); - return false; -} - -Error -GDBRemoteCommunication::StartDebugserverProcess (const char *debugserver_url, - const char *unix_socket_name, // For handshaking - lldb_private::ProcessLaunchInfo &launch_info) -{ - Error error; - // If we locate debugserver, keep that located version around - static FileSpec g_debugserver_file_spec; - - // This function will fill in the launch information for the debugserver - // instance that gets launched. - launch_info.Clear(); - - char debugserver_path[PATH_MAX]; - FileSpec &debugserver_file_spec = launch_info.GetExecutableFile(); - - // Always check to see if we have an environment override for the path - // to the debugserver to use and use it if we do. - const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH"); - if (env_debugserver_path) - debugserver_file_spec.SetFile (env_debugserver_path, false); - else - debugserver_file_spec = g_debugserver_file_spec; - bool debugserver_exists = debugserver_file_spec.Exists(); - if (!debugserver_exists) - { - // The debugserver binary is in the LLDB.framework/Resources - // directory. - if (Host::GetLLDBPath (ePathTypeSupportExecutableDir, debugserver_file_spec)) - { - debugserver_file_spec.GetFilename().SetCString(DEBUGSERVER_BASENAME); - debugserver_exists = debugserver_file_spec.Exists(); - if (debugserver_exists) - { - g_debugserver_file_spec = debugserver_file_spec; - } - else - { - g_debugserver_file_spec.Clear(); - debugserver_file_spec.Clear(); - } - } - } - - if (debugserver_exists) - { - debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path)); - - Args &debugserver_args = launch_info.GetArguments(); - debugserver_args.Clear(); - char arg_cstr[PATH_MAX]; - - // Start args with "debugserver /file/path -r --" - debugserver_args.AppendArgument(debugserver_path); - debugserver_args.AppendArgument(debugserver_url); - // use native registers, not the GDB registers - debugserver_args.AppendArgument("--native-regs"); - // make debugserver run in its own session so signals generated by - // special terminal key sequences (^C) don't affect debugserver - debugserver_args.AppendArgument("--setsid"); - - if (unix_socket_name && unix_socket_name[0]) - { - debugserver_args.AppendArgument("--unix-socket"); - debugserver_args.AppendArgument(unix_socket_name); - } - - const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE"); - if (env_debugserver_log_file) - { - ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-file=%s", env_debugserver_log_file); - debugserver_args.AppendArgument(arg_cstr); - } - - const char *env_debugserver_log_flags = getenv("LLDB_DEBUGSERVER_LOG_FLAGS"); - if (env_debugserver_log_flags) - { - ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags); - debugserver_args.AppendArgument(arg_cstr); - } - // debugserver_args.AppendArgument("--log-file=/tmp/debugserver.txt"); - // debugserver_args.AppendArgument("--log-flags=0x802e0e"); - - // We currently send down all arguments, attach pids, or attach - // process names in dedicated GDB server packets, so we don't need - // to pass them as arguments. This is currently because of all the - // things we need to setup prior to launching: the environment, - // current working dir, file actions, etc. -#if 0 - // Now append the program arguments - if (inferior_argv) - { - // Terminate the debugserver args so we can now append the inferior args - debugserver_args.AppendArgument("--"); - - for (int i = 0; inferior_argv[i] != NULL; ++i) - debugserver_args.AppendArgument (inferior_argv[i]); - } - else if (attach_pid != LLDB_INVALID_PROCESS_ID) - { - ::snprintf (arg_cstr, sizeof(arg_cstr), "--attach=%u", attach_pid); - debugserver_args.AppendArgument (arg_cstr); - } - else if (attach_name && attach_name[0]) - { - if (wait_for_launch) - debugserver_args.AppendArgument ("--waitfor"); - else - debugserver_args.AppendArgument ("--attach"); - debugserver_args.AppendArgument (attach_name); - } -#endif - - // Close STDIN, STDOUT and STDERR. We might need to redirect them - // to "/dev/null" if we run into any problems. -// launch_info.AppendCloseFileAction (STDIN_FILENO); -// launch_info.AppendCloseFileAction (STDOUT_FILENO); -// launch_info.AppendCloseFileAction (STDERR_FILENO); - - error = Host::LaunchProcess(launch_info); - } - else - { - error.SetErrorStringWithFormat ("unable to locate " DEBUGSERVER_BASENAME ); - } - return error; -} - -void -GDBRemoteCommunication::DumpHistory(Stream &strm) -{ - m_history.Dump (strm); -} diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h deleted file mode 100644 index b3bad7ede5c4..000000000000 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h +++ /dev/null @@ -1,264 +0,0 @@ -//===-- GDBRemoteCommunication.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_GDBRemoteCommunication_h_ -#define liblldb_GDBRemoteCommunication_h_ - -// C Includes -// C++ Includes -#include <list> -#include <string> - -// Other libraries and framework includes -// Project includes -#include "lldb/lldb-public.h" -#include "lldb/Core/Communication.h" -#include "lldb/Core/Listener.h" -#include "lldb/Host/Mutex.h" -#include "lldb/Host/Predicate.h" -#include "lldb/Host/TimeValue.h" - -#include "Utility/StringExtractorGDBRemote.h" - -class ProcessGDBRemote; - -class GDBRemoteCommunication : public lldb_private::Communication -{ -public: - enum - { - eBroadcastBitRunPacketSent = kLoUserBroadcastBit - }; - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - GDBRemoteCommunication(const char *comm_name, - const char *listener_name, - bool is_platform); - - virtual - ~GDBRemoteCommunication(); - - char - GetAck (); - - size_t - SendAck (); - - size_t - SendNack (); - - char - CalculcateChecksum (const char *payload, - size_t payload_length); - - bool - GetSequenceMutex (lldb_private::Mutex::Locker& locker); - - bool - CheckForPacket (const uint8_t *src, - size_t src_len, - StringExtractorGDBRemote &packet); - bool - IsRunning() const - { - return m_public_is_running.GetValue(); - } - - bool - GetSendAcks () - { - return m_send_acks; - } - - //------------------------------------------------------------------ - // Client and server must implement these pure virtual functions - //------------------------------------------------------------------ - virtual bool - GetThreadSuffixSupported () = 0; - - //------------------------------------------------------------------ - // 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 - // GDBRemoteCommunicationClient. - //------------------------------------------------------------------ - uint32_t - SetPacketTimeout (uint32_t packet_timeout) - { - const uint32_t old_packet_timeout = m_packet_timeout; - m_packet_timeout = packet_timeout; - return old_packet_timeout; - } - - uint32_t - GetPacketTimeoutInMicroSeconds () const - { - return m_packet_timeout * lldb_private::TimeValue::MicroSecPerSec; - } - //------------------------------------------------------------------ - // Start a debugserver instance on the current host using the - // supplied connection URL. - //------------------------------------------------------------------ - lldb_private::Error - StartDebugserverProcess (const char *connect_url, - const char *unix_socket_name, - lldb_private::ProcessLaunchInfo &launch_info); - - void - DumpHistory(lldb_private::Stream &strm); - -protected: - - class History - { - public: - enum PacketType - { - ePacketTypeInvalid = 0, - ePacketTypeSend, - ePacketTypeRecv - }; - - struct Entry - { - Entry() : - packet(), - type (ePacketTypeInvalid), - bytes_transmitted (0), - packet_idx (0), - tid (LLDB_INVALID_THREAD_ID) - { - } - - void - Clear () - { - packet.clear(); - type = ePacketTypeInvalid; - bytes_transmitted = 0; - packet_idx = 0; - tid = LLDB_INVALID_THREAD_ID; - } - std::string packet; - PacketType type; - uint32_t bytes_transmitted; - uint32_t packet_idx; - lldb::tid_t tid; - }; - - History (uint32_t size); - - ~History (); - - // For single char packets for ack, nack and /x03 - void - AddPacket (char packet_char, - PacketType type, - uint32_t bytes_transmitted); - void - AddPacket (const std::string &src, - uint32_t src_len, - PacketType type, - uint32_t bytes_transmitted); - - void - Dump (lldb_private::Stream &strm) const; - - void - Dump (lldb_private::Log *log) const; - - bool - DidDumpToLog () const - { - return m_dumped_to_log; - } - -protected: - uint32_t - GetFirstSavedPacketIndex () const - { - if (m_total_packet_count < m_packets.size()) - return 0; - else - return m_curr_idx + 1; - } - - uint32_t - GetNumPacketsInHistory () const - { - if (m_total_packet_count < m_packets.size()) - return m_total_packet_count; - else - return (uint32_t)m_packets.size(); - } - - uint32_t - GetNextIndex() - { - ++m_total_packet_count; - const uint32_t idx = m_curr_idx; - m_curr_idx = NormalizeIndex(idx + 1); - return idx; - } - - uint32_t - NormalizeIndex (uint32_t i) const - { - return i % m_packets.size(); - } - - - std::vector<Entry> m_packets; - uint32_t m_curr_idx; - uint32_t m_total_packet_count; - mutable bool m_dumped_to_log; - }; - - size_t - SendPacket (const char *payload, - size_t payload_length); - - size_t - SendPacketNoLock (const char *payload, - size_t payload_length); - - size_t - WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &response, - uint32_t timeout_usec); - - bool - WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr); - - //------------------------------------------------------------------ - // Classes that inherit from GDBRemoteCommunication can see and modify these - //------------------------------------------------------------------ - uint32_t m_packet_timeout; - lldb_private::Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time - lldb_private::Predicate<bool> m_public_is_running; - lldb_private::Predicate<bool> m_private_is_running; - History m_history; - bool m_send_acks; - bool m_is_platform; // Set to true if this class represents a platform, - // false if this class represents a debug session for - // a single process - - - - -private: - //------------------------------------------------------------------ - // For GDBRemoteCommunication only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunication); -}; - -#endif // liblldb_GDBRemoteCommunication_h_ diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp deleted file mode 100644 index a31f48af1f73..000000000000 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ /dev/null @@ -1,1897 +0,0 @@ -//===-- GDBRemoteCommunicationClient.cpp ------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - - -#include "GDBRemoteCommunicationClient.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "llvm/ADT/Triple.h" -#include "lldb/Interpreter/Args.h" -#include "lldb/Core/ConnectionFileDescriptor.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/State.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Host/Endian.h" -#include "lldb/Host/Host.h" -#include "lldb/Host/TimeValue.h" - -// Project includes -#include "Utility/StringExtractorGDBRemote.h" -#include "ProcessGDBRemote.h" -#include "ProcessGDBRemoteLog.h" - -using namespace lldb; -using namespace lldb_private; - -//---------------------------------------------------------------------- -// GDBRemoteCommunicationClient constructor -//---------------------------------------------------------------------- -GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) : - GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet", is_platform), - m_supports_not_sending_acks (eLazyBoolCalculate), - m_supports_thread_suffix (eLazyBoolCalculate), - m_supports_threads_in_stop_reply (eLazyBoolCalculate), - m_supports_vCont_all (eLazyBoolCalculate), - m_supports_vCont_any (eLazyBoolCalculate), - m_supports_vCont_c (eLazyBoolCalculate), - m_supports_vCont_C (eLazyBoolCalculate), - m_supports_vCont_s (eLazyBoolCalculate), - m_supports_vCont_S (eLazyBoolCalculate), - m_qHostInfo_is_valid (eLazyBoolCalculate), - m_supports_alloc_dealloc_memory (eLazyBoolCalculate), - m_supports_memory_region_info (eLazyBoolCalculate), - m_supports_qProcessInfoPID (true), - m_supports_qfProcessInfo (true), - m_supports_qUserName (true), - m_supports_qGroupName (true), - m_supports_qThreadStopInfo (true), - m_supports_z0 (true), - m_supports_z1 (true), - m_supports_z2 (true), - m_supports_z3 (true), - m_supports_z4 (true), - m_curr_tid (LLDB_INVALID_THREAD_ID), - m_curr_tid_run (LLDB_INVALID_THREAD_ID), - m_async_mutex (Mutex::eMutexTypeRecursive), - m_async_packet_predicate (false), - m_async_packet (), - m_async_response (), - m_async_signal (-1), - m_host_arch(), - m_os_version_major (UINT32_MAX), - m_os_version_minor (UINT32_MAX), - m_os_version_update (UINT32_MAX) -{ -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() -{ - if (IsConnected()) - Disconnect(); -} - -bool -GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr) -{ - // Start the read thread after we send the handshake ack since if we - // fail to send the handshake ack, there is no reason to continue... - if (SendAck()) - return true; - - if (error_ptr) - error_ptr->SetErrorString("failed to send the handshake ack"); - return false; -} - -void -GDBRemoteCommunicationClient::QueryNoAckModeSupported () -{ - if (m_supports_not_sending_acks == eLazyBoolCalculate) - { - m_send_acks = true; - m_supports_not_sending_acks = eLazyBoolNo; - - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false)) - { - if (response.IsOKResponse()) - { - m_send_acks = false; - m_supports_not_sending_acks = eLazyBoolYes; - } - } - } -} - -void -GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported () -{ - if (m_supports_threads_in_stop_reply == eLazyBoolCalculate) - { - m_supports_threads_in_stop_reply = eLazyBoolNo; - - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response, false)) - { - if (response.IsOKResponse()) - m_supports_threads_in_stop_reply = eLazyBoolYes; - } - } -} - - -void -GDBRemoteCommunicationClient::ResetDiscoverableSettings() -{ - m_supports_not_sending_acks = eLazyBoolCalculate; - m_supports_thread_suffix = eLazyBoolCalculate; - m_supports_threads_in_stop_reply = eLazyBoolCalculate; - m_supports_vCont_c = eLazyBoolCalculate; - m_supports_vCont_C = eLazyBoolCalculate; - m_supports_vCont_s = eLazyBoolCalculate; - m_supports_vCont_S = eLazyBoolCalculate; - m_qHostInfo_is_valid = eLazyBoolCalculate; - m_supports_alloc_dealloc_memory = eLazyBoolCalculate; - m_supports_memory_region_info = eLazyBoolCalculate; - - m_supports_qProcessInfoPID = true; - m_supports_qfProcessInfo = true; - m_supports_qUserName = true; - m_supports_qGroupName = true; - m_supports_qThreadStopInfo = true; - m_supports_z0 = true; - m_supports_z1 = true; - m_supports_z2 = true; - m_supports_z3 = true; - m_supports_z4 = true; - m_host_arch.Clear(); -} - - -bool -GDBRemoteCommunicationClient::GetThreadSuffixSupported () -{ - if (m_supports_thread_suffix == eLazyBoolCalculate) - { - StringExtractorGDBRemote response; - m_supports_thread_suffix = eLazyBoolNo; - if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false)) - { - if (response.IsOKResponse()) - m_supports_thread_suffix = eLazyBoolYes; - } - } - return m_supports_thread_suffix; -} -bool -GDBRemoteCommunicationClient::GetVContSupported (char flavor) -{ - if (m_supports_vCont_c == eLazyBoolCalculate) - { - StringExtractorGDBRemote response; - m_supports_vCont_any = eLazyBoolNo; - m_supports_vCont_all = eLazyBoolNo; - m_supports_vCont_c = eLazyBoolNo; - m_supports_vCont_C = eLazyBoolNo; - m_supports_vCont_s = eLazyBoolNo; - m_supports_vCont_S = eLazyBoolNo; - if (SendPacketAndWaitForResponse("vCont?", response, false)) - { - const char *response_cstr = response.GetStringRef().c_str(); - if (::strstr (response_cstr, ";c")) - m_supports_vCont_c = eLazyBoolYes; - - if (::strstr (response_cstr, ";C")) - m_supports_vCont_C = eLazyBoolYes; - - if (::strstr (response_cstr, ";s")) - m_supports_vCont_s = eLazyBoolYes; - - if (::strstr (response_cstr, ";S")) - m_supports_vCont_S = eLazyBoolYes; - - if (m_supports_vCont_c == eLazyBoolYes && - m_supports_vCont_C == eLazyBoolYes && - m_supports_vCont_s == eLazyBoolYes && - m_supports_vCont_S == eLazyBoolYes) - { - m_supports_vCont_all = eLazyBoolYes; - } - - if (m_supports_vCont_c == eLazyBoolYes || - m_supports_vCont_C == eLazyBoolYes || - m_supports_vCont_s == eLazyBoolYes || - m_supports_vCont_S == eLazyBoolYes) - { - m_supports_vCont_any = eLazyBoolYes; - } - } - } - - switch (flavor) - { - case 'a': return m_supports_vCont_any; - case 'A': return m_supports_vCont_all; - case 'c': return m_supports_vCont_c; - case 'C': return m_supports_vCont_C; - case 's': return m_supports_vCont_s; - case 'S': return m_supports_vCont_S; - default: break; - } - return false; -} - - -size_t -GDBRemoteCommunicationClient::SendPacketAndWaitForResponse -( - const char *payload, - StringExtractorGDBRemote &response, - bool send_async -) -{ - return SendPacketAndWaitForResponse (payload, - ::strlen (payload), - response, - send_async); -} - -size_t -GDBRemoteCommunicationClient::SendPacketAndWaitForResponse -( - const char *payload, - size_t payload_length, - StringExtractorGDBRemote &response, - bool send_async -) -{ - Mutex::Locker locker; - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); - size_t response_len = 0; - if (GetSequenceMutex (locker)) - { - if (SendPacketNoLock (payload, payload_length)) - response_len = WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ()); - else - { - if (log) - log->Printf("error: failed to send '%*s'", (int) payload_length, payload); - } - } - else - { - if (send_async) - { - Mutex::Locker async_locker (m_async_mutex); - m_async_packet.assign(payload, payload_length); - m_async_packet_predicate.SetValue (true, eBroadcastNever); - - if (log) - log->Printf ("async: async packet = %s", m_async_packet.c_str()); - - bool timed_out = false; - if (SendInterrupt(locker, 2, timed_out)) - { - if (m_interrupt_sent) - { - TimeValue timeout_time; - timeout_time = TimeValue::Now(); - timeout_time.OffsetWithSeconds (m_packet_timeout); - - if (log) - log->Printf ("async: sent interrupt"); - - if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out)) - { - if (log) - log->Printf ("async: got response"); - - // Swap the response buffer to avoid malloc and string copy - response.GetStringRef().swap (m_async_response.GetStringRef()); - response_len = response.GetStringRef().size(); - } - else - { - if (log) - log->Printf ("async: timed out waiting for response"); - } - - // Make sure we wait until the continue packet has been sent again... - if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out)) - { - if (log) - { - if (timed_out) - log->Printf ("async: timed out waiting for process to resume, but process was resumed"); - else - log->Printf ("async: async packet sent"); - } - } - else - { - if (log) - log->Printf ("async: timed out waiting for process to resume"); - } - } - else - { - // We had a racy condition where we went to send the interrupt - // yet we were able to get the lock, so the process must have - // just stopped? - if (log) - log->Printf ("async: got lock without sending interrupt"); - // Send the packet normally since we got the lock - if (SendPacketNoLock (payload, payload_length)) - response_len = WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ()); - else - { - if (log) - log->Printf("error: failed to send '%*s'", (int) payload_length, payload); - } - } - } - else - { - if (log) - log->Printf ("async: failed to interrupt"); - } - } - else - { - if (log) - log->Printf("error: failed to get packet sequence mutex, not sending packet '%*s'", (int) payload_length, payload); - } - } - if (response_len == 0) - { - if (log) - log->Printf("error: failed to get response for '%*s'", (int) payload_length, payload); - } - return response_len; -} - -StateType -GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse -( - ProcessGDBRemote *process, - const char *payload, - size_t packet_length, - StringExtractorGDBRemote &response -) -{ - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); - if (log) - log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__); - - Mutex::Locker locker(m_sequence_mutex); - StateType state = eStateRunning; - - BroadcastEvent(eBroadcastBitRunPacketSent, NULL); - m_public_is_running.SetValue (true, eBroadcastNever); - // Set the starting continue packet into "continue_packet". This packet - // make change if we are interrupted and we continue after an async packet... - std::string continue_packet(payload, packet_length); - - bool got_stdout = false; - - while (state == eStateRunning) - { - if (!got_stdout) - { - if (log) - log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str()); - if (SendPacketNoLock(continue_packet.c_str(), continue_packet.size()) == 0) - state = eStateInvalid; - - m_private_is_running.SetValue (true, eBroadcastAlways); - } - - got_stdout = false; - - if (log) - log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%s)", __FUNCTION__, continue_packet.c_str()); - - if (WaitForPacketWithTimeoutMicroSecondsNoLock(response, UINT32_MAX)) - { - if (response.Empty()) - state = eStateInvalid; - else - { - const char stop_type = response.GetChar(); - if (log) - log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str()); - switch (stop_type) - { - case 'T': - case 'S': - { - if (process->GetStopID() == 0) - { - if (process->GetID() == LLDB_INVALID_PROCESS_ID) - { - lldb::pid_t pid = GetCurrentProcessID (); - if (pid != LLDB_INVALID_PROCESS_ID) - process->SetID (pid); - } - process->BuildDynamicRegisterInfo (true); - } - - // Privately notify any internal threads that we have stopped - // in case we wanted to interrupt our process, yet we might - // send a packet and continue without returning control to the - // user. - m_private_is_running.SetValue (false, eBroadcastAlways); - - const uint8_t signo = response.GetHexU8 (UINT8_MAX); - - bool continue_after_aync = false; - if (m_async_signal != -1 || m_async_packet_predicate.GetValue()) - { - continue_after_aync = true; - // We sent an interrupt packet to stop the inferior process - // for an async signal or to send an async packet while running - // but we might have been single stepping and received the - // stop packet for the step instead of for the interrupt packet. - // Typically when an interrupt is sent a SIGINT or SIGSTOP - // is used, so if we get anything else, we need to try and - // get another stop reply packet that may have been sent - // due to sending the interrupt when the target is stopped - // which will just re-send a copy of the last stop reply - // packet. If we don't do this, then the reply for our - // async packet will be the repeat stop reply packet and cause - // a lot of trouble for us! - if (signo != SIGINT && signo != SIGSTOP) - { - continue_after_aync = false; - - // We didn't get a a SIGINT or SIGSTOP, so try for a - // very brief time (1 ms) to get another stop reply - // packet to make sure it doesn't get in the way - StringExtractorGDBRemote extra_stop_reply_packet; - uint32_t timeout_usec = 1000; - if (WaitForPacketWithTimeoutMicroSecondsNoLock (extra_stop_reply_packet, timeout_usec)) - { - switch (extra_stop_reply_packet.GetChar()) - { - case 'T': - case 'S': - // We did get an extra stop reply, which means - // our interrupt didn't stop the target so we - // shouldn't continue after the async signal - // or packet is sent... - continue_after_aync = false; - break; - } - } - } - } - - if (m_async_signal != -1) - { - if (log) - log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal)); - - // Save off the async signal we are supposed to send - const int async_signal = m_async_signal; - // Clear the async signal member so we don't end up - // sending the signal multiple times... - m_async_signal = -1; - // Check which signal we stopped with - if (signo == async_signal) - { - if (log) - log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo)); - - // We already stopped with a signal that we wanted - // to stop with, so we are done - } - else - { - // We stopped with a different signal that the one - // we wanted to stop with, so now we must resume - // with the signal we want - char signal_packet[32]; - int signal_packet_len = 0; - signal_packet_len = ::snprintf (signal_packet, - sizeof (signal_packet), - "C%2.2x", - async_signal); - - if (log) - log->Printf ("async: stopped with signal %s, resume with %s", - Host::GetSignalAsCString (signo), - Host::GetSignalAsCString (async_signal)); - - // Set the continue packet to resume even if the - // interrupt didn't cause our stop (ignore continue_after_aync) - continue_packet.assign(signal_packet, signal_packet_len); - continue; - } - } - else if (m_async_packet_predicate.GetValue()) - { - LogSP packet_log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS)); - - // We are supposed to send an asynchronous packet while - // we are running. - m_async_response.Clear(); - if (m_async_packet.empty()) - { - if (packet_log) - packet_log->Printf ("async: error: empty async packet"); - - } - else - { - if (packet_log) - packet_log->Printf ("async: sending packet"); - - SendPacketAndWaitForResponse (&m_async_packet[0], - m_async_packet.size(), - m_async_response, - false); - } - // Let the other thread that was trying to send the async - // packet know that the packet has been sent and response is - // ready... - m_async_packet_predicate.SetValue(false, eBroadcastAlways); - - if (packet_log) - packet_log->Printf ("async: sent packet, continue_after_aync = %i", continue_after_aync); - - // Set the continue packet to resume if our interrupt - // for the async packet did cause the stop - if (continue_after_aync) - { - continue_packet.assign (1, 'c'); - continue; - } - } - // Stop with signal and thread info - state = eStateStopped; - } - break; - - case 'W': - case 'X': - // process exited - state = eStateExited; - break; - - case 'O': - // STDOUT - { - got_stdout = true; - std::string inferior_stdout; - inferior_stdout.reserve(response.GetBytesLeft () / 2); - char ch; - while ((ch = response.GetHexU8()) != '\0') - inferior_stdout.append(1, ch); - process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size()); - } - break; - - case 'E': - // ERROR - state = eStateInvalid; - break; - - default: - if (log) - log->Printf ("GDBRemoteCommunicationClient::%s () unrecognized async packet", __FUNCTION__); - state = eStateInvalid; - break; - } - } - } - else - { - if (log) - log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(...) => false", __FUNCTION__); - state = eStateInvalid; - } - } - if (log) - log->Printf ("GDBRemoteCommunicationClient::%s () => %s", __FUNCTION__, StateAsCString(state)); - response.SetFilePos(0); - m_private_is_running.SetValue (false, eBroadcastAlways); - m_public_is_running.SetValue (false, eBroadcastAlways); - return state; -} - -bool -GDBRemoteCommunicationClient::SendAsyncSignal (int signo) -{ - Mutex::Locker async_locker (m_async_mutex); - m_async_signal = signo; - bool timed_out = false; - Mutex::Locker locker; - if (SendInterrupt (locker, 1, timed_out)) - return true; - m_async_signal = -1; - return false; -} - -// This function takes a mutex locker as a parameter in case the GetSequenceMutex -// actually succeeds. If it doesn't succeed in acquiring the sequence mutex -// (the expected result), then it will send the halt packet. If it does succeed -// then the caller that requested the interrupt will want to keep the sequence -// locked down so that no one else can send packets while the caller has control. -// This function usually gets called when we are running and need to stop the -// target. It can also be used when we are running and and we need to do something -// else (like read/write memory), so we need to interrupt the running process -// (gdb remote protocol requires this), and do what we need to do, then resume. - -bool -GDBRemoteCommunicationClient::SendInterrupt -( - Mutex::Locker& locker, - uint32_t seconds_to_wait_for_stop, - bool &timed_out -) -{ - m_interrupt_sent = false; - timed_out = false; - LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)); - - if (IsRunning()) - { - // Only send an interrupt if our debugserver is running... - if (GetSequenceMutex (locker)) - { - if (log) - log->Printf ("SendInterrupt () - got sequence mutex without having to interrupt"); - } - else - { - // Someone has the mutex locked waiting for a response or for the - // inferior to stop, so send the interrupt on the down low... - char ctrl_c = '\x03'; - ConnectionStatus status = eConnectionStatusSuccess; - size_t bytes_written = Write (&ctrl_c, 1, status, NULL); - if (log) - log->PutCString("send packet: \\x03"); - if (bytes_written > 0) - { - m_interrupt_sent = true; - if (seconds_to_wait_for_stop) - { - TimeValue timeout; - if (seconds_to_wait_for_stop) - { - timeout = TimeValue::Now(); - timeout.OffsetWithSeconds (seconds_to_wait_for_stop); - } - if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out)) - { - if (log) - log->PutCString ("SendInterrupt () - sent interrupt, private state stopped"); - return true; - } - else - { - if (log) - log->Printf ("SendInterrupt () - sent interrupt, timed out wating for async thread resume"); - } - } - else - { - if (log) - log->Printf ("SendInterrupt () - sent interrupt, not waiting for stop..."); - return true; - } - } - else - { - if (log) - log->Printf ("SendInterrupt () - failed to write interrupt"); - } - return false; - } - } - else - { - if (log) - log->Printf ("SendInterrupt () - not running"); - } - return true; -} - -lldb::pid_t -GDBRemoteCommunicationClient::GetCurrentProcessID () -{ - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false)) - { - if (response.GetChar() == 'Q') - if (response.GetChar() == 'C') - return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID); - } - return LLDB_INVALID_PROCESS_ID; -} - -bool -GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str) -{ - error_str.clear(); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false)) - { - if (response.IsOKResponse()) - return true; - if (response.GetChar() == 'E') - { - // A string the describes what failed when launching... - error_str = response.GetStringRef().substr(1); - } - else - { - error_str.assign ("unknown error occurred launching process"); - } - } - else - { - error_str.assign ("failed to send the qLaunchSuccess packet"); - } - return false; -} - -int -GDBRemoteCommunicationClient::SendArgumentsPacket (char const *argv[]) -{ - if (argv && argv[0]) - { - StreamString packet; - packet.PutChar('A'); - const char *arg; - for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i) - { - const int arg_len = strlen(arg); - if (i > 0) - packet.PutChar(','); - packet.Printf("%i,%i,", arg_len * 2, i); - packet.PutBytesAsRawHex8 (arg, arg_len); - } - - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) - { - if (response.IsOKResponse()) - return 0; - uint8_t error = response.GetError(); - if (error) - return error; - } - } - return -1; -} - -int -GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_value) -{ - if (name_equal_value && name_equal_value[0]) - { - StreamString packet; - packet.Printf("QEnvironment:%s", name_equal_value); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) - { - if (response.IsOKResponse()) - return 0; - uint8_t error = response.GetError(); - if (error) - return error; - } - } - return -1; -} - -int -GDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch) -{ - if (arch && arch[0]) - { - StreamString packet; - packet.Printf("QLaunchArch:%s", arch); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) - { - if (response.IsOKResponse()) - return 0; - uint8_t error = response.GetError(); - if (error) - return error; - } - } - return -1; -} - -bool -GDBRemoteCommunicationClient::GetOSVersion (uint32_t &major, - uint32_t &minor, - uint32_t &update) -{ - if (GetHostInfo ()) - { - if (m_os_version_major != UINT32_MAX) - { - major = m_os_version_major; - minor = m_os_version_minor; - update = m_os_version_update; - return true; - } - } - return false; -} - -bool -GDBRemoteCommunicationClient::GetOSBuildString (std::string &s) -{ - if (GetHostInfo ()) - { - if (!m_os_build.empty()) - { - s = m_os_build; - return true; - } - } - s.clear(); - return false; -} - - -bool -GDBRemoteCommunicationClient::GetOSKernelDescription (std::string &s) -{ - if (GetHostInfo ()) - { - if (!m_os_kernel.empty()) - { - s = m_os_kernel; - return true; - } - } - s.clear(); - return false; -} - -bool -GDBRemoteCommunicationClient::GetHostname (std::string &s) -{ - if (GetHostInfo ()) - { - if (!m_hostname.empty()) - { - s = m_hostname; - return true; - } - } - s.clear(); - return false; -} - -ArchSpec -GDBRemoteCommunicationClient::GetSystemArchitecture () -{ - if (GetHostInfo ()) - return m_host_arch; - return ArchSpec(); -} - - -bool -GDBRemoteCommunicationClient::GetHostInfo (bool force) -{ - if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) - { - m_qHostInfo_is_valid = eLazyBoolNo; - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse ("qHostInfo", response, false)) - { - if (response.IsNormalResponse()) - { - std::string name; - std::string value; - uint32_t cpu = LLDB_INVALID_CPUTYPE; - uint32_t sub = 0; - std::string arch_name; - std::string os_name; - std::string vendor_name; - std::string triple; - uint32_t pointer_byte_size = 0; - StringExtractor extractor; - ByteOrder byte_order = eByteOrderInvalid; - uint32_t num_keys_decoded = 0; - while (response.GetNameColonValue(name, value)) - { - if (name.compare("cputype") == 0) - { - // exception type in big endian hex - cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0); - if (cpu != LLDB_INVALID_CPUTYPE) - ++num_keys_decoded; - } - else if (name.compare("cpusubtype") == 0) - { - // exception count in big endian hex - sub = Args::StringToUInt32 (value.c_str(), 0, 0); - if (sub != 0) - ++num_keys_decoded; - } - else if (name.compare("arch") == 0) - { - arch_name.swap (value); - ++num_keys_decoded; - } - else if (name.compare("triple") == 0) - { - // The triple comes as ASCII hex bytes since it contains '-' chars - extractor.GetStringRef().swap(value); - extractor.SetFilePos(0); - extractor.GetHexByteString (triple); - ++num_keys_decoded; - } - else if (name.compare("os_build") == 0) - { - extractor.GetStringRef().swap(value); - extractor.SetFilePos(0); - extractor.GetHexByteString (m_os_build); - ++num_keys_decoded; - } - else if (name.compare("hostname") == 0) - { - extractor.GetStringRef().swap(value); - extractor.SetFilePos(0); - extractor.GetHexByteString (m_hostname); - ++num_keys_decoded; - } - else if (name.compare("os_kernel") == 0) - { - extractor.GetStringRef().swap(value); - extractor.SetFilePos(0); - extractor.GetHexByteString (m_os_kernel); - ++num_keys_decoded; - } - else if (name.compare("ostype") == 0) - { - os_name.swap (value); - ++num_keys_decoded; - } - else if (name.compare("vendor") == 0) - { - vendor_name.swap(value); - ++num_keys_decoded; - } - else if (name.compare("endian") == 0) - { - ++num_keys_decoded; - if (value.compare("little") == 0) - byte_order = eByteOrderLittle; - else if (value.compare("big") == 0) - byte_order = eByteOrderBig; - else if (value.compare("pdp") == 0) - byte_order = eByteOrderPDP; - else - --num_keys_decoded; - } - else if (name.compare("ptrsize") == 0) - { - pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0); - if (pointer_byte_size != 0) - ++num_keys_decoded; - } - else if (name.compare("os_version") == 0) - { - Args::StringToVersion (value.c_str(), - m_os_version_major, - m_os_version_minor, - m_os_version_update); - if (m_os_version_major != UINT32_MAX) - ++num_keys_decoded; - } - } - - if (num_keys_decoded > 0) - m_qHostInfo_is_valid = eLazyBoolYes; - - if (triple.empty()) - { - if (arch_name.empty()) - { - if (cpu != LLDB_INVALID_CPUTYPE) - { - m_host_arch.SetArchitecture (eArchTypeMachO, cpu, sub); - if (pointer_byte_size) - { - assert (pointer_byte_size == m_host_arch.GetAddressByteSize()); - } - if (byte_order != eByteOrderInvalid) - { - assert (byte_order == m_host_arch.GetByteOrder()); - } - if (!vendor_name.empty()) - m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name)); - if (!os_name.empty()) - m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name)); - - } - } - else - { - std::string triple; - triple += arch_name; - triple += '-'; - if (vendor_name.empty()) - triple += "unknown"; - else - triple += vendor_name; - triple += '-'; - if (os_name.empty()) - triple += "unknown"; - else - triple += os_name; - m_host_arch.SetTriple (triple.c_str(), NULL); - if (pointer_byte_size) - { - assert (pointer_byte_size == m_host_arch.GetAddressByteSize()); - } - if (byte_order != eByteOrderInvalid) - { - assert (byte_order == m_host_arch.GetByteOrder()); - } - - } - } - else - { - m_host_arch.SetTriple (triple.c_str(), NULL); - if (pointer_byte_size) - { - assert (pointer_byte_size == m_host_arch.GetAddressByteSize()); - } - if (byte_order != eByteOrderInvalid) - { - assert (byte_order == m_host_arch.GetByteOrder()); - } - } - } - } - } - return m_qHostInfo_is_valid == eLazyBoolYes; -} - -int -GDBRemoteCommunicationClient::SendAttach -( - lldb::pid_t pid, - StringExtractorGDBRemote& response -) -{ - if (pid != LLDB_INVALID_PROCESS_ID) - { - char packet[64]; - const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%llx", pid); - assert (packet_len < sizeof(packet)); - if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) - { - if (response.IsErrorResponse()) - return response.GetError(); - return 0; - } - } - return -1; -} - -const lldb_private::ArchSpec & -GDBRemoteCommunicationClient::GetHostArchitecture () -{ - if (m_qHostInfo_is_valid == eLazyBoolCalculate) - GetHostInfo (); - return m_host_arch; -} - -addr_t -GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions) -{ - if (m_supports_alloc_dealloc_memory != eLazyBoolNo) - { - m_supports_alloc_dealloc_memory = eLazyBoolYes; - char packet[64]; - const int packet_len = ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size, - permissions & lldb::ePermissionsReadable ? "r" : "", - permissions & lldb::ePermissionsWritable ? "w" : "", - permissions & lldb::ePermissionsExecutable ? "x" : ""); - assert (packet_len < sizeof(packet)); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) - { - if (!response.IsErrorResponse()) - return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS); - } - else - { - m_supports_alloc_dealloc_memory = eLazyBoolNo; - } - } - return LLDB_INVALID_ADDRESS; -} - -bool -GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr) -{ - if (m_supports_alloc_dealloc_memory != eLazyBoolNo) - { - m_supports_alloc_dealloc_memory = eLazyBoolYes; - char packet[64]; - const int packet_len = ::snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr); - assert (packet_len < sizeof(packet)); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) - { - if (response.IsOKResponse()) - return true; - } - else - { - m_supports_alloc_dealloc_memory = eLazyBoolNo; - } - } - return false; -} - -bool -GDBRemoteCommunicationClient::Detach () -{ - return SendPacket ("D", 1) > 0; -} - -Error -GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr, - lldb_private::MemoryRegionInfo ®ion_info) -{ - Error error; - region_info.Clear(); - - if (m_supports_memory_region_info != eLazyBoolNo) - { - m_supports_memory_region_info = eLazyBoolYes; - char packet[64]; - const int packet_len = ::snprintf(packet, sizeof(packet), "qMemoryRegionInfo:%llx", (uint64_t)addr); - assert (packet_len < sizeof(packet)); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) - { - std::string name; - std::string value; - addr_t addr_value; - bool success = true; - bool saw_permissions = false; - while (success && response.GetNameColonValue(name, value)) - { - if (name.compare ("start") == 0) - { - addr_value = Args::StringToUInt64(value.c_str(), LLDB_INVALID_ADDRESS, 16, &success); - if (success) - region_info.GetRange().SetRangeBase(addr_value); - } - else if (name.compare ("size") == 0) - { - addr_value = Args::StringToUInt64(value.c_str(), 0, 16, &success); - if (success) - region_info.GetRange().SetByteSize (addr_value); - } - else if (name.compare ("permissions") == 0 && region_info.GetRange().IsValid()) - { - saw_permissions = true; - if (region_info.GetRange().Contains (addr)) - { - if (value.find('r') != std::string::npos) - region_info.SetReadable (MemoryRegionInfo::eYes); - else - region_info.SetReadable (MemoryRegionInfo::eNo); - - if (value.find('w') != std::string::npos) - region_info.SetWritable (MemoryRegionInfo::eYes); - else - region_info.SetWritable (MemoryRegionInfo::eNo); - - if (value.find('x') != std::string::npos) - region_info.SetExecutable (MemoryRegionInfo::eYes); - else - region_info.SetExecutable (MemoryRegionInfo::eNo); - } - else - { - // The reported region does not contain this address -- we're looking at an unmapped page - region_info.SetReadable (MemoryRegionInfo::eNo); - region_info.SetWritable (MemoryRegionInfo::eNo); - region_info.SetExecutable (MemoryRegionInfo::eNo); - } - } - else if (name.compare ("error") == 0) - { - StringExtractorGDBRemote name_extractor; - // Swap "value" over into "name_extractor" - name_extractor.GetStringRef().swap(value); - // Now convert the HEX bytes into a string value - name_extractor.GetHexByteString (value); - error.SetErrorString(value.c_str()); - } - } - - // We got a valid address range back but no permissions -- which means this is an unmapped page - if (region_info.GetRange().IsValid() && saw_permissions == false) - { - region_info.SetReadable (MemoryRegionInfo::eNo); - region_info.SetWritable (MemoryRegionInfo::eNo); - region_info.SetExecutable (MemoryRegionInfo::eNo); - } - } - else - { - m_supports_memory_region_info = eLazyBoolNo; - } - } - - if (m_supports_memory_region_info == eLazyBoolNo) - { - error.SetErrorString("qMemoryRegionInfo is not supported"); - } - if (error.Fail()) - region_info.Clear(); - return error; - -} - - -int -GDBRemoteCommunicationClient::SetSTDIN (char const *path) -{ - if (path && path[0]) - { - StreamString packet; - packet.PutCString("QSetSTDIN:"); - packet.PutBytesAsRawHex8(path, strlen(path)); - - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) - { - if (response.IsOKResponse()) - return 0; - uint8_t error = response.GetError(); - if (error) - return error; - } - } - return -1; -} - -int -GDBRemoteCommunicationClient::SetSTDOUT (char const *path) -{ - if (path && path[0]) - { - StreamString packet; - packet.PutCString("QSetSTDOUT:"); - packet.PutBytesAsRawHex8(path, strlen(path)); - - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) - { - if (response.IsOKResponse()) - return 0; - uint8_t error = response.GetError(); - if (error) - return error; - } - } - return -1; -} - -int -GDBRemoteCommunicationClient::SetSTDERR (char const *path) -{ - if (path && path[0]) - { - StreamString packet; - packet.PutCString("QSetSTDERR:"); - packet.PutBytesAsRawHex8(path, strlen(path)); - - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) - { - if (response.IsOKResponse()) - return 0; - uint8_t error = response.GetError(); - if (error) - return error; - } - } - return -1; -} - -int -GDBRemoteCommunicationClient::SetWorkingDir (char const *path) -{ - if (path && path[0]) - { - StreamString packet; - packet.PutCString("QSetWorkingDir:"); - packet.PutBytesAsRawHex8(path, strlen(path)); - - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) - { - if (response.IsOKResponse()) - return 0; - uint8_t error = response.GetError(); - if (error) - return error; - } - } - return -1; -} - -int -GDBRemoteCommunicationClient::SetDisableASLR (bool enable) -{ - char packet[32]; - const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0); - assert (packet_len < sizeof(packet)); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) - { - if (response.IsOKResponse()) - return 0; - uint8_t error = response.GetError(); - if (error) - return error; - } - return -1; -} - -bool -GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemote &response, ProcessInstanceInfo &process_info) -{ - if (response.IsNormalResponse()) - { - std::string name; - std::string value; - StringExtractor extractor; - - while (response.GetNameColonValue(name, value)) - { - if (name.compare("pid") == 0) - { - process_info.SetProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0)); - } - else if (name.compare("ppid") == 0) - { - process_info.SetParentProcessID (Args::StringToUInt32 (value.c_str(), LLDB_INVALID_PROCESS_ID, 0)); - } - else if (name.compare("uid") == 0) - { - process_info.SetUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0)); - } - else if (name.compare("euid") == 0) - { - process_info.SetEffectiveUserID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0)); - } - else if (name.compare("gid") == 0) - { - process_info.SetGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0)); - } - else if (name.compare("egid") == 0) - { - process_info.SetEffectiveGroupID (Args::StringToUInt32 (value.c_str(), UINT32_MAX, 0)); - } - else if (name.compare("triple") == 0) - { - // The triple comes as ASCII hex bytes since it contains '-' chars - extractor.GetStringRef().swap(value); - extractor.SetFilePos(0); - extractor.GetHexByteString (value); - process_info.GetArchitecture ().SetTriple (value.c_str(), NULL); - } - else if (name.compare("name") == 0) - { - StringExtractor extractor; - // The the process name from ASCII hex bytes since we can't - // control the characters in a process name - extractor.GetStringRef().swap(value); - extractor.SetFilePos(0); - extractor.GetHexByteString (value); - process_info.GetExecutableFile().SetFile (value.c_str(), false); - } - } - - if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) - return true; - } - return false; -} - -bool -GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) -{ - process_info.Clear(); - - if (m_supports_qProcessInfoPID) - { - char packet[32]; - const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%llu", pid); - assert (packet_len < sizeof(packet)); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) - { - return DecodeProcessInfoResponse (response, process_info); - } - else - { - m_supports_qProcessInfoPID = false; - return false; - } - } - return false; -} - -uint32_t -GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info, - ProcessInstanceInfoList &process_infos) -{ - process_infos.Clear(); - - if (m_supports_qfProcessInfo) - { - StreamString packet; - packet.PutCString ("qfProcessInfo"); - if (!match_info.MatchAllProcesses()) - { - packet.PutChar (':'); - const char *name = match_info.GetProcessInfo().GetName(); - bool has_name_match = false; - if (name && name[0]) - { - has_name_match = true; - NameMatchType name_match_type = match_info.GetNameMatchType(); - switch (name_match_type) - { - case eNameMatchIgnore: - has_name_match = false; - break; - - case eNameMatchEquals: - packet.PutCString ("name_match:equals;"); - break; - - case eNameMatchContains: - packet.PutCString ("name_match:contains;"); - break; - - case eNameMatchStartsWith: - packet.PutCString ("name_match:starts_with;"); - break; - - case eNameMatchEndsWith: - packet.PutCString ("name_match:ends_with;"); - break; - - case eNameMatchRegularExpression: - packet.PutCString ("name_match:regex;"); - break; - } - if (has_name_match) - { - packet.PutCString ("name:"); - packet.PutBytesAsRawHex8(name, ::strlen(name)); - packet.PutChar (';'); - } - } - - if (match_info.GetProcessInfo().ProcessIDIsValid()) - packet.Printf("pid:%llu;",match_info.GetProcessInfo().GetProcessID()); - if (match_info.GetProcessInfo().ParentProcessIDIsValid()) - packet.Printf("parent_pid:%llu;",match_info.GetProcessInfo().GetParentProcessID()); - if (match_info.GetProcessInfo().UserIDIsValid()) - packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID()); - if (match_info.GetProcessInfo().GroupIDIsValid()) - packet.Printf("gid:%u;",match_info.GetProcessInfo().GetGroupID()); - if (match_info.GetProcessInfo().EffectiveUserIDIsValid()) - packet.Printf("euid:%u;",match_info.GetProcessInfo().GetEffectiveUserID()); - if (match_info.GetProcessInfo().EffectiveGroupIDIsValid()) - packet.Printf("egid:%u;",match_info.GetProcessInfo().GetEffectiveGroupID()); - if (match_info.GetProcessInfo().EffectiveGroupIDIsValid()) - packet.Printf("all_users:%u;",match_info.GetMatchAllUsers() ? 1 : 0); - if (match_info.GetProcessInfo().GetArchitecture().IsValid()) - { - const ArchSpec &match_arch = match_info.GetProcessInfo().GetArchitecture(); - const llvm::Triple &triple = match_arch.GetTriple(); - packet.PutCString("triple:"); - packet.PutCStringAsRawHex8(triple.getTriple().c_str()); - packet.PutChar (';'); - } - } - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false)) - { - do - { - ProcessInstanceInfo process_info; - if (!DecodeProcessInfoResponse (response, process_info)) - break; - process_infos.Append(process_info); - response.GetStringRef().clear(); - response.SetFilePos(0); - } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false)); - } - else - { - m_supports_qfProcessInfo = false; - return 0; - } - } - return process_infos.GetSize(); - -} - -bool -GDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name) -{ - if (m_supports_qUserName) - { - char packet[32]; - const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid); - assert (packet_len < sizeof(packet)); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) - { - if (response.IsNormalResponse()) - { - // Make sure we parsed the right number of characters. The response is - // the hex encoded user name and should make up the entire packet. - // If there are any non-hex ASCII bytes, the length won't match below.. - if (response.GetHexByteString (name) * 2 == response.GetStringRef().size()) - return true; - } - } - else - { - m_supports_qUserName = false; - return false; - } - } - return false; - -} - -bool -GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name) -{ - if (m_supports_qGroupName) - { - char packet[32]; - const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid); - assert (packet_len < sizeof(packet)); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse (packet, packet_len, response, false)) - { - if (response.IsNormalResponse()) - { - // Make sure we parsed the right number of characters. The response is - // the hex encoded group name and should make up the entire packet. - // If there are any non-hex ASCII bytes, the length won't match below.. - if (response.GetHexByteString (name) * 2 == response.GetStringRef().size()) - return true; - } - } - else - { - m_supports_qGroupName = false; - return false; - } - } - return false; -} - -void -GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets) -{ - uint32_t i; - TimeValue start_time, end_time; - uint64_t total_time_nsec; - float packets_per_second; - if (SendSpeedTestPacket (0, 0)) - { - for (uint32_t send_size = 0; send_size <= 1024; send_size *= 2) - { - for (uint32_t recv_size = 0; recv_size <= 1024; recv_size *= 2) - { - start_time = TimeValue::Now(); - for (i=0; i<num_packets; ++i) - { - SendSpeedTestPacket (send_size, recv_size); - } - end_time = TimeValue::Now(); - total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970(); - packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec; - printf ("%u qSpeedTest(send=%-5u, recv=%-5u) in %llu.%9.9llu sec for %f packets/sec.\n", - num_packets, - send_size, - recv_size, - total_time_nsec / TimeValue::NanoSecPerSec, - total_time_nsec % TimeValue::NanoSecPerSec, - packets_per_second); - if (recv_size == 0) - recv_size = 32; - } - if (send_size == 0) - send_size = 32; - } - } - else - { - start_time = TimeValue::Now(); - for (i=0; i<num_packets; ++i) - { - GetCurrentProcessID (); - } - end_time = TimeValue::Now(); - total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970(); - packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec; - printf ("%u 'qC' packets packets in 0x%llu%9.9llu sec for %f packets/sec.\n", - num_packets, - total_time_nsec / TimeValue::NanoSecPerSec, - total_time_nsec % TimeValue::NanoSecPerSec, - packets_per_second); - } -} - -bool -GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t recv_size) -{ - StreamString packet; - packet.Printf ("qSpeedTest:response_size:%i;data:", recv_size); - uint32_t bytes_left = send_size; - while (bytes_left > 0) - { - if (bytes_left >= 26) - { - packet.PutCString("abcdefghijklmnopqrstuvwxyz"); - bytes_left -= 26; - } - else - { - packet.Printf ("%*.*s;", bytes_left, bytes_left, "abcdefghijklmnopqrstuvwxyz"); - bytes_left = 0; - } - } - - StringExtractorGDBRemote response; - return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) > 0; - return false; -} - -uint16_t -GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort () -{ - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("qLaunchGDBServer", strlen("qLaunchGDBServer"), response, false)) - { - std::string name; - std::string value; - uint16_t port = 0; - lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; - while (response.GetNameColonValue(name, value)) - { - if (name.size() == 4 && name.compare("port") == 0) - port = Args::StringToUInt32(value.c_str(), 0, 0); - if (name.size() == 3 && name.compare("pid") == 0) - pid = Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0); - } - return port; - } - return 0; -} - -bool -GDBRemoteCommunicationClient::SetCurrentThread (int tid) -{ - if (m_curr_tid == tid) - return true; - - char packet[32]; - int packet_len; - if (tid <= 0) - packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid); - else - packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid); - assert (packet_len + 1 < sizeof(packet)); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet, packet_len, response, false)) - { - if (response.IsOKResponse()) - { - m_curr_tid = tid; - return true; - } - } - return false; -} - -bool -GDBRemoteCommunicationClient::SetCurrentThreadForRun (int tid) -{ - if (m_curr_tid_run == tid) - return true; - - char packet[32]; - int packet_len; - if (tid <= 0) - packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid); - else - packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid); - - assert (packet_len + 1 < sizeof(packet)); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet, packet_len, response, false)) - { - if (response.IsOKResponse()) - { - m_curr_tid_run = tid; - return true; - } - } - return false; -} - -bool -GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response) -{ - if (SendPacketAndWaitForResponse("?", 1, response, false)) - return response.IsNormalResponse(); - return false; -} - -bool -GDBRemoteCommunicationClient::GetThreadStopInfo (uint32_t tid, StringExtractorGDBRemote &response) -{ - if (m_supports_qThreadStopInfo) - { - char packet[256]; - int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%x", tid); - assert (packet_len < sizeof(packet)); - if (SendPacketAndWaitForResponse(packet, packet_len, response, false)) - { - if (response.IsNormalResponse()) - return true; - else - return false; - } - else - { - m_supports_qThreadStopInfo = false; - } - } -// if (SetCurrentThread (tid)) -// return GetStopReply (response); - return false; -} - - -uint8_t -GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type, bool insert, addr_t addr, uint32_t length) -{ - switch (type) - { - case eBreakpointSoftware: if (!m_supports_z0) return UINT8_MAX; break; - case eBreakpointHardware: if (!m_supports_z1) return UINT8_MAX; break; - case eWatchpointWrite: if (!m_supports_z2) return UINT8_MAX; break; - case eWatchpointRead: if (!m_supports_z3) return UINT8_MAX; break; - case eWatchpointReadWrite: if (!m_supports_z4) return UINT8_MAX; break; - default: return UINT8_MAX; - } - - char packet[64]; - const int packet_len = ::snprintf (packet, - sizeof(packet), - "%c%i,%llx,%x", - insert ? 'Z' : 'z', - type, - addr, - length); - - assert (packet_len + 1 < sizeof(packet)); - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse(packet, packet_len, response, true)) - { - if (response.IsOKResponse()) - return 0; - else if (response.IsErrorResponse()) - return response.GetError(); - } - else - { - switch (type) - { - case eBreakpointSoftware: m_supports_z0 = false; break; - case eBreakpointHardware: m_supports_z1 = false; break; - case eWatchpointWrite: m_supports_z2 = false; break; - case eWatchpointRead: m_supports_z3 = false; break; - case eWatchpointReadWrite: m_supports_z4 = false; break; - default: break; - } - } - - return UINT8_MAX; -} - -size_t -GDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids, - bool &sequence_mutex_unavailable) -{ - Mutex::Locker locker; - thread_ids.clear(); - - if (GetSequenceMutex (locker)) - { - sequence_mutex_unavailable = false; - StringExtractorGDBRemote response; - - for (SendPacketNoLock ("qfThreadInfo", strlen("qfThreadInfo")) && WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ()); - response.IsNormalResponse(); - SendPacketNoLock ("qsThreadInfo", strlen("qsThreadInfo")) && WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ())) - { - char ch = response.GetChar(); - if (ch == 'l') - break; - if (ch == 'm') - { - do - { - tid_t tid = response.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID); - - if (tid != LLDB_INVALID_THREAD_ID) - { - thread_ids.push_back (tid); - } - ch = response.GetChar(); // Skip the command separator - } while (ch == ','); // Make sure we got a comma separator - } - } - } - else - { - LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS)); - if (log) - log->Printf("error: failed to get packet sequence mutex, not sending packet 'qfThreadInfo'"); - sequence_mutex_unavailable = true; - } - return thread_ids.size(); -} - -lldb::addr_t -GDBRemoteCommunicationClient::GetShlibInfoAddr() -{ - if (!IsRunning()) - { - StringExtractorGDBRemote response; - if (SendPacketAndWaitForResponse("qShlibInfoAddr", ::strlen ("qShlibInfoAddr"), response, false)) - { - if (response.IsNormalResponse()) - return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS); - } - } - return LLDB_INVALID_ADDRESS; -} - diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h deleted file mode 100644 index 4794021908c8..000000000000 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ /dev/null @@ -1,402 +0,0 @@ -//===-- GDBRemoteCommunicationClient.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_GDBRemoteCommunicationClient_h_ -#define liblldb_GDBRemoteCommunicationClient_h_ - -// C Includes -// C++ Includes -#include <vector> - -// Other libraries and framework includes -// Project includes -#include "lldb/Core/ArchSpec.h" -#include "lldb/Target/Process.h" - -#include "GDBRemoteCommunication.h" - -typedef enum -{ - eBreakpointSoftware = 0, - eBreakpointHardware, - eWatchpointWrite, - eWatchpointRead, - eWatchpointReadWrite -} GDBStoppointType; - -class GDBRemoteCommunicationClient : public GDBRemoteCommunication -{ -public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - GDBRemoteCommunicationClient(bool is_platform); - - virtual - ~GDBRemoteCommunicationClient(); - - //------------------------------------------------------------------ - // After connecting, send the handshake to the server to make sure - // we are communicating with it. - //------------------------------------------------------------------ - bool - HandshakeWithServer (lldb_private::Error *error_ptr); - - size_t - SendPacketAndWaitForResponse (const char *send_payload, - StringExtractorGDBRemote &response, - bool send_async); - - size_t - SendPacketAndWaitForResponse (const char *send_payload, - size_t send_length, - StringExtractorGDBRemote &response, - bool send_async); - - lldb::StateType - SendContinuePacketAndWaitForResponse (ProcessGDBRemote *process, - const char *packet_payload, - size_t packet_length, - StringExtractorGDBRemote &response); - - virtual bool - GetThreadSuffixSupported (); - - void - QueryNoAckModeSupported (); - - void - GetListThreadsInStopReplySupported (); - - bool - SendAsyncSignal (int signo); - - bool - SendInterrupt (lldb_private::Mutex::Locker &locker, - uint32_t seconds_to_wait_for_stop, - bool &timed_out); - - lldb::pid_t - GetCurrentProcessID (); - - bool - GetLaunchSuccess (std::string &error_str); - - uint16_t - LaunchGDBserverAndGetPort (); - - //------------------------------------------------------------------ - /// Sends a GDB remote protocol 'A' packet that delivers program - /// arguments to the remote server. - /// - /// @param[in] argv - /// A NULL terminated array of const C strings to use as the - /// arguments. - /// - /// @return - /// Zero if the response was "OK", a positive value if the - /// the response was "Exx" where xx are two hex digits, or - /// -1 if the call is unsupported or any other unexpected - /// response was received. - //------------------------------------------------------------------ - int - SendArgumentsPacket (char const *argv[]); - - //------------------------------------------------------------------ - /// Sends a "QEnvironment:NAME=VALUE" packet that will build up the - /// environment that will get used when launching an application - /// in conjunction with the 'A' packet. This function can be called - /// multiple times in a row in order to pass on the desired - /// environment that the inferior should be launched with. - /// - /// @param[in] name_equal_value - /// A NULL terminated C string that contains a single environment - /// in the format "NAME=VALUE". - /// - /// @return - /// Zero if the response was "OK", a positive value if the - /// the response was "Exx" where xx are two hex digits, or - /// -1 if the call is unsupported or any other unexpected - /// response was received. - //------------------------------------------------------------------ - int - SendEnvironmentPacket (char const *name_equal_value); - - int - SendLaunchArchPacket (const char *arch); - //------------------------------------------------------------------ - /// Sends a "vAttach:PID" where PID is in hex. - /// - /// @param[in] pid - /// A process ID for the remote gdb server to attach to. - /// - /// @param[out] response - /// The response received from the gdb server. If the return - /// value is zero, \a response will contain a stop reply - /// packet. - /// - /// @return - /// Zero if the attach was successful, or an error indicating - /// an error code. - //------------------------------------------------------------------ - int - SendAttach (lldb::pid_t pid, - StringExtractorGDBRemote& response); - - - //------------------------------------------------------------------ - /// Sets the path to use for stdin/out/err for a process - /// that will be launched with the 'A' packet. - /// - /// @param[in] path - /// The path to use for stdin/out/err - /// - /// @return - /// Zero if the for success, or an error code for failure. - //------------------------------------------------------------------ - int - SetSTDIN (char const *path); - int - SetSTDOUT (char const *path); - int - SetSTDERR (char const *path); - - //------------------------------------------------------------------ - /// Sets the disable ASLR flag to \a enable for a process that will - /// be launched with the 'A' packet. - /// - /// @param[in] enable - /// A boolean value indicating wether to disable ASLR or not. - /// - /// @return - /// Zero if the for success, or an error code for failure. - //------------------------------------------------------------------ - int - SetDisableASLR (bool enable); - - //------------------------------------------------------------------ - /// Sets the working directory to \a path for a process that will - /// be launched with the 'A' packet. - /// - /// @param[in] path - /// The path to a directory to use when launching our processs - /// - /// @return - /// Zero if the for success, or an error code for failure. - //------------------------------------------------------------------ - int - SetWorkingDir (char const *path); - - lldb::addr_t - AllocateMemory (size_t size, uint32_t permissions); - - bool - DeallocateMemory (lldb::addr_t addr); - - bool - Detach (); - - lldb_private::Error - GetMemoryRegionInfo (lldb::addr_t addr, - lldb_private::MemoryRegionInfo &range_info); - - const lldb_private::ArchSpec & - GetHostArchitecture (); - - bool - GetVContSupported (char flavor); - - void - ResetDiscoverableSettings(); - - bool - GetHostInfo (bool force = false); - - bool - GetOSVersion (uint32_t &major, - uint32_t &minor, - uint32_t &update); - - bool - GetOSBuildString (std::string &s); - - bool - GetOSKernelDescription (std::string &s); - - lldb_private::ArchSpec - GetSystemArchitecture (); - - bool - GetHostname (std::string &s); - - lldb::addr_t - GetShlibInfoAddr(); - - bool - GetSupportsThreadSuffix (); - - bool - GetProcessInfo (lldb::pid_t pid, - lldb_private::ProcessInstanceInfo &process_info); - - uint32_t - FindProcesses (const lldb_private::ProcessInstanceInfoMatch &process_match_info, - lldb_private::ProcessInstanceInfoList &process_infos); - - bool - GetUserName (uint32_t uid, std::string &name); - - bool - GetGroupName (uint32_t gid, std::string &name); - - bool - HasFullVContSupport () - { - return GetVContSupported ('A'); - } - - bool - HasAnyVContSupport () - { - return GetVContSupported ('a'); - } - - uint32_t - SetPacketTimeout (uint32_t packet_timeout) - { - const uint32_t old_packet_timeout = m_packet_timeout; - m_packet_timeout = packet_timeout; - return old_packet_timeout; - } - - bool - GetStopReply (StringExtractorGDBRemote &response); - - bool - GetThreadStopInfo (uint32_t tid, - StringExtractorGDBRemote &response); - - bool - SupportsGDBStoppointPacket (GDBStoppointType type) - { - switch (type) - { - case eBreakpointSoftware: return m_supports_z0; - case eBreakpointHardware: return m_supports_z1; - case eWatchpointWrite: return m_supports_z2; - case eWatchpointRead: return m_supports_z3; - case eWatchpointReadWrite: return m_supports_z4; - default: break; - } - return false; - } - uint8_t - SendGDBStoppointTypePacket (GDBStoppointType type, // Type of breakpoint or watchpoint - bool insert, // Insert or remove? - lldb::addr_t addr, // Address of breakpoint or watchpoint - uint32_t length); // Byte Size of breakpoint or watchpoint - - void - TestPacketSpeed (const uint32_t num_packets); - - // This packet is for testing the speed of the interface only. Both - // the client and server need to support it, but this allows us to - // measure the packet speed without any other work being done on the - // other end and avoids any of that work affecting the packet send - // and response times. - bool - SendSpeedTestPacket (uint32_t send_size, - uint32_t recv_size); - - bool - SetCurrentThread (int tid); - - bool - SetCurrentThreadForRun (int tid); - - lldb_private::LazyBool - SupportsAllocDeallocMemory () // const - { - // Uncomment this to have lldb pretend the debug server doesn't respond to alloc/dealloc memory packets. - // m_supports_alloc_dealloc_memory = lldb_private::eLazyBoolNo; - return m_supports_alloc_dealloc_memory; - } - - size_t - GetCurrentThreadIDs (std::vector<lldb::tid_t> &thread_ids, - bool &sequence_mutex_unavailable); - - bool - GetInterruptWasSent () const - { - return m_interrupt_sent; - } -protected: - - //------------------------------------------------------------------ - // Classes that inherit from GDBRemoteCommunicationClient can see and modify these - //------------------------------------------------------------------ - lldb_private::LazyBool m_supports_not_sending_acks; - lldb_private::LazyBool m_supports_thread_suffix; - lldb_private::LazyBool m_supports_threads_in_stop_reply; - lldb_private::LazyBool m_supports_vCont_all; - lldb_private::LazyBool m_supports_vCont_any; - lldb_private::LazyBool m_supports_vCont_c; - lldb_private::LazyBool m_supports_vCont_C; - lldb_private::LazyBool m_supports_vCont_s; - lldb_private::LazyBool m_supports_vCont_S; - lldb_private::LazyBool m_qHostInfo_is_valid; - lldb_private::LazyBool m_supports_alloc_dealloc_memory; - lldb_private::LazyBool m_supports_memory_region_info; - - bool - m_supports_qProcessInfoPID:1, - m_supports_qfProcessInfo:1, - m_supports_qUserName:1, - m_supports_qGroupName:1, - m_supports_qThreadStopInfo:1, - m_supports_z0:1, - m_supports_z1:1, - m_supports_z2:1, - m_supports_z3:1, - m_supports_z4:1; - - - lldb::tid_t m_curr_tid; // Current gdb remote protocol thread index for all other operations - lldb::tid_t m_curr_tid_run; // Current gdb remote protocol thread index for continue, step, etc - - - // If we need to send a packet while the target is running, the m_async_XXX - // member variables take care of making this happen. - lldb_private::Mutex m_async_mutex; - lldb_private::Predicate<bool> m_async_packet_predicate; - std::string m_async_packet; - StringExtractorGDBRemote m_async_response; - int m_async_signal; // We were asked to deliver a signal to the inferior process. - bool m_interrupt_sent; - - lldb_private::ArchSpec m_host_arch; - uint32_t m_os_version_major; - uint32_t m_os_version_minor; - uint32_t m_os_version_update; - std::string m_os_build; - std::string m_os_kernel; - std::string m_hostname; - - bool - DecodeProcessInfoResponse (StringExtractorGDBRemote &response, - lldb_private::ProcessInstanceInfo &process_info); -private: - //------------------------------------------------------------------ - // For GDBRemoteCommunicationClient only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationClient); -}; - -#endif // liblldb_GDBRemoteCommunicationClient_h_ diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp deleted file mode 100644 index 3f8677d1c7e4..000000000000 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ /dev/null @@ -1,834 +0,0 @@ -//===-- GDBRemoteCommunicationServer.cpp ------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - - -#include "GDBRemoteCommunicationServer.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "llvm/ADT/Triple.h" -#include "lldb/Interpreter/Args.h" -#include "lldb/Core/ConnectionFileDescriptor.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/State.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Host/Endian.h" -#include "lldb/Host/Host.h" -#include "lldb/Host/TimeValue.h" -#include "lldb/Target/Process.h" - -// Project includes -#include "Utility/StringExtractorGDBRemote.h" -#include "ProcessGDBRemote.h" -#include "ProcessGDBRemoteLog.h" - -using namespace lldb; -using namespace lldb_private; - -//---------------------------------------------------------------------- -// GDBRemoteCommunicationServer constructor -//---------------------------------------------------------------------- -GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(bool is_platform) : - GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet", is_platform), - m_async_thread (LLDB_INVALID_HOST_THREAD), - m_process_launch_info (), - m_process_launch_error (), - m_proc_infos (), - m_proc_infos_index (0), - m_lo_port_num (0), - m_hi_port_num (0) -{ -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() -{ -} - - -//void * -//GDBRemoteCommunicationServer::AsyncThread (void *arg) -//{ -// GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer*) arg; -// -// LogSP log;// (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); -// if (log) -// log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID()); -// -// StringExtractorGDBRemote packet; -// -// while () -// { -// if (packet. -// } -// -// if (log) -// log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID()); -// -// process->m_async_thread = LLDB_INVALID_HOST_THREAD; -// return NULL; -//} -// -bool -GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec, - Error &error, - bool &interrupt, - bool &quit) -{ - StringExtractorGDBRemote packet; - if (WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec)) - { - const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType (); - switch (packet_type) - { - case StringExtractorGDBRemote::eServerPacketType_nack: - case StringExtractorGDBRemote::eServerPacketType_ack: - break; - - case StringExtractorGDBRemote::eServerPacketType_invalid: - error.SetErrorString("invalid packet"); - quit = true; - break; - - case StringExtractorGDBRemote::eServerPacketType_interrupt: - error.SetErrorString("interrupt received"); - interrupt = true; - break; - - case StringExtractorGDBRemote::eServerPacketType_unimplemented: - return SendUnimplementedResponse (packet.GetStringRef().c_str()) > 0; - - case StringExtractorGDBRemote::eServerPacketType_A: - return Handle_A (packet); - - case StringExtractorGDBRemote::eServerPacketType_qfProcessInfo: - return Handle_qfProcessInfo (packet); - - case StringExtractorGDBRemote::eServerPacketType_qsProcessInfo: - return Handle_qsProcessInfo (packet); - - case StringExtractorGDBRemote::eServerPacketType_qC: - return Handle_qC (packet); - - case StringExtractorGDBRemote::eServerPacketType_qHostInfo: - return Handle_qHostInfo (packet); - - case StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer: - return Handle_qLaunchGDBServer (packet); - - case StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess: - return Handle_qLaunchSuccess (packet); - - case StringExtractorGDBRemote::eServerPacketType_qGroupName: - return Handle_qGroupName (packet); - - case StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID: - return Handle_qProcessInfoPID (packet); - - case StringExtractorGDBRemote::eServerPacketType_qSpeedTest: - return Handle_qSpeedTest (packet); - - case StringExtractorGDBRemote::eServerPacketType_qUserName: - return Handle_qUserName (packet); - - case StringExtractorGDBRemote::eServerPacketType_QEnvironment: - return Handle_QEnvironment (packet); - - case StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR: - return Handle_QSetDisableASLR (packet); - - case StringExtractorGDBRemote::eServerPacketType_QSetSTDIN: - return Handle_QSetSTDIN (packet); - - case StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT: - return Handle_QSetSTDOUT (packet); - - case StringExtractorGDBRemote::eServerPacketType_QSetSTDERR: - return Handle_QSetSTDERR (packet); - - case StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir: - return Handle_QSetWorkingDir (packet); - - case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode: - return Handle_QStartNoAckMode (packet); - } - return true; - } - else - { - if (!IsConnected()) - error.SetErrorString("lost connection"); - else - error.SetErrorString("timeout"); - } - - return false; -} - -size_t -GDBRemoteCommunicationServer::SendUnimplementedResponse (const char *) -{ - // TODO: Log the packet we aren't handling... - return SendPacketNoLock ("", 0); -} - -size_t -GDBRemoteCommunicationServer::SendErrorResponse (uint8_t err) -{ - char packet[16]; - int packet_len = ::snprintf (packet, sizeof(packet), "E%2.2x", err); - assert (packet_len < sizeof(packet)); - return SendPacketNoLock (packet, packet_len); -} - - -size_t -GDBRemoteCommunicationServer::SendOKResponse () -{ - return SendPacketNoLock ("OK", 2); -} - -bool -GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr) -{ - return GetAck(); -} - -bool -GDBRemoteCommunicationServer::Handle_qHostInfo (StringExtractorGDBRemote &packet) -{ - StreamString response; - - // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00 - - ArchSpec host_arch (Host::GetArchitecture ()); - const llvm::Triple &host_triple = host_arch.GetTriple(); - response.PutCString("triple:"); - response.PutCStringAsRawHex8(host_triple.getTriple().c_str()); - response.Printf (";ptrsize:%u;",host_arch.GetAddressByteSize()); - - uint32_t cpu = host_arch.GetMachOCPUType(); - uint32_t sub = host_arch.GetMachOCPUSubType(); - if (cpu != LLDB_INVALID_CPUTYPE) - response.Printf ("cputype:%u;", cpu); - if (sub != LLDB_INVALID_CPUTYPE) - response.Printf ("cpusubtype:%u;", sub); - - switch (lldb::endian::InlHostByteOrder()) - { - case eByteOrderBig: response.PutCString ("endian:big;"); break; - case eByteOrderLittle: response.PutCString ("endian:little;"); break; - case eByteOrderPDP: response.PutCString ("endian:pdp;"); break; - default: response.PutCString ("endian:unknown;"); break; - } - - uint32_t major = UINT32_MAX; - uint32_t minor = UINT32_MAX; - uint32_t update = UINT32_MAX; - if (Host::GetOSVersion (major, minor, update)) - { - if (major != UINT32_MAX) - { - response.Printf("os_version:%u", major); - if (minor != UINT32_MAX) - { - response.Printf(".%u", minor); - if (update != UINT32_MAX) - response.Printf(".%u", update); - } - response.PutChar(';'); - } - } - - std::string s; - if (Host::GetOSBuildString (s)) - { - response.PutCString ("os_build:"); - response.PutCStringAsRawHex8(s.c_str()); - response.PutChar(';'); - } - if (Host::GetOSKernelDescription (s)) - { - response.PutCString ("os_kernel:"); - response.PutCStringAsRawHex8(s.c_str()); - response.PutChar(';'); - } - if (Host::GetHostname (s)) - { - response.PutCString ("hostname:"); - response.PutCStringAsRawHex8(s.c_str()); - response.PutChar(';'); - } - - return SendPacketNoLock (response.GetData(), response.GetSize()) > 0; -} - -static void -CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info, StreamString &response) -{ - response.Printf ("pid:%llu;ppid:%llu;uid:%i;gid:%i;euid:%i;egid:%i;", - proc_info.GetProcessID(), - proc_info.GetParentProcessID(), - proc_info.GetUserID(), - proc_info.GetGroupID(), - proc_info.GetEffectiveUserID(), - proc_info.GetEffectiveGroupID()); - response.PutCString ("name:"); - response.PutCStringAsRawHex8(proc_info.GetName()); - response.PutChar(';'); - const ArchSpec &proc_arch = proc_info.GetArchitecture(); - if (proc_arch.IsValid()) - { - const llvm::Triple &proc_triple = proc_arch.GetTriple(); - response.PutCString("triple:"); - response.PutCStringAsRawHex8(proc_triple.getTriple().c_str()); - response.PutChar(';'); - } -} - -bool -GDBRemoteCommunicationServer::Handle_qProcessInfoPID (StringExtractorGDBRemote &packet) -{ - // Packet format: "qProcessInfoPID:%i" where %i is the pid - packet.SetFilePos(::strlen ("qProcessInfoPID:")); - lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID); - if (pid != LLDB_INVALID_PROCESS_ID) - { - ProcessInstanceInfo proc_info; - if (Host::GetProcessInfo(pid, proc_info)) - { - StreamString response; - CreateProcessInfoResponse (proc_info, response); - return SendPacketNoLock (response.GetData(), response.GetSize()); - } - } - return SendErrorResponse (1); -} - -bool -GDBRemoteCommunicationServer::Handle_qfProcessInfo (StringExtractorGDBRemote &packet) -{ - m_proc_infos_index = 0; - m_proc_infos.Clear(); - - ProcessInstanceInfoMatch match_info; - packet.SetFilePos(::strlen ("qfProcessInfo")); - if (packet.GetChar() == ':') - { - - std::string key; - std::string value; - while (packet.GetNameColonValue(key, value)) - { - bool success = true; - if (key.compare("name") == 0) - { - StringExtractor extractor; - extractor.GetStringRef().swap(value); - extractor.GetHexByteString (value); - match_info.GetProcessInfo().GetExecutableFile().SetFile(value.c_str(), false); - } - else if (key.compare("name_match") == 0) - { - if (value.compare("equals") == 0) - { - match_info.SetNameMatchType (eNameMatchEquals); - } - else if (value.compare("starts_with") == 0) - { - match_info.SetNameMatchType (eNameMatchStartsWith); - } - else if (value.compare("ends_with") == 0) - { - match_info.SetNameMatchType (eNameMatchEndsWith); - } - else if (value.compare("contains") == 0) - { - match_info.SetNameMatchType (eNameMatchContains); - } - else if (value.compare("regex") == 0) - { - match_info.SetNameMatchType (eNameMatchRegularExpression); - } - else - { - success = false; - } - } - else if (key.compare("pid") == 0) - { - match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success)); - } - else if (key.compare("parent_pid") == 0) - { - match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success)); - } - else if (key.compare("uid") == 0) - { - match_info.GetProcessInfo().SetUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); - } - else if (key.compare("gid") == 0) - { - match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); - } - else if (key.compare("euid") == 0) - { - match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); - } - else if (key.compare("egid") == 0) - { - match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32(value.c_str(), UINT32_MAX, 0, &success)); - } - else if (key.compare("all_users") == 0) - { - match_info.SetMatchAllUsers(Args::StringToBoolean(value.c_str(), false, &success)); - } - else if (key.compare("triple") == 0) - { - match_info.GetProcessInfo().GetArchitecture().SetTriple (value.c_str(), NULL); - } - else - { - success = false; - } - - if (!success) - return SendErrorResponse (2); - } - } - - if (Host::FindProcesses (match_info, m_proc_infos)) - { - // We found something, return the first item by calling the get - // subsequent process info packet handler... - return Handle_qsProcessInfo (packet); - } - return SendErrorResponse (3); -} - -bool -GDBRemoteCommunicationServer::Handle_qsProcessInfo (StringExtractorGDBRemote &packet) -{ - if (m_proc_infos_index < m_proc_infos.GetSize()) - { - StreamString response; - CreateProcessInfoResponse (m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response); - ++m_proc_infos_index; - return SendPacketNoLock (response.GetData(), response.GetSize()); - } - return SendErrorResponse (4); -} - -bool -GDBRemoteCommunicationServer::Handle_qUserName (StringExtractorGDBRemote &packet) -{ - // Packet format: "qUserName:%i" where %i is the uid - packet.SetFilePos(::strlen ("qUserName:")); - uint32_t uid = packet.GetU32 (UINT32_MAX); - if (uid != UINT32_MAX) - { - std::string name; - if (Host::GetUserName (uid, name)) - { - StreamString response; - response.PutCStringAsRawHex8 (name.c_str()); - return SendPacketNoLock (response.GetData(), response.GetSize()); - } - } - return SendErrorResponse (5); - -} - -bool -GDBRemoteCommunicationServer::Handle_qGroupName (StringExtractorGDBRemote &packet) -{ - // Packet format: "qGroupName:%i" where %i is the gid - packet.SetFilePos(::strlen ("qGroupName:")); - uint32_t gid = packet.GetU32 (UINT32_MAX); - if (gid != UINT32_MAX) - { - std::string name; - if (Host::GetGroupName (gid, name)) - { - StreamString response; - response.PutCStringAsRawHex8 (name.c_str()); - return SendPacketNoLock (response.GetData(), response.GetSize()); - } - } - return SendErrorResponse (6); -} - -bool -GDBRemoteCommunicationServer::Handle_qSpeedTest (StringExtractorGDBRemote &packet) -{ - packet.SetFilePos(::strlen ("qSpeedTest:")); - - std::string key; - std::string value; - bool success = packet.GetNameColonValue(key, value); - if (success && key.compare("response_size") == 0) - { - uint32_t response_size = Args::StringToUInt32(value.c_str(), 0, 0, &success); - if (success) - { - if (response_size == 0) - return SendOKResponse(); - StreamString response; - uint32_t bytes_left = response_size; - response.PutCString("data:"); - while (bytes_left > 0) - { - if (bytes_left >= 26) - { - response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - bytes_left -= 26; - } - else - { - response.Printf ("%*.*s;", bytes_left, bytes_left, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - bytes_left = 0; - } - } - return SendPacketNoLock (response.GetData(), response.GetSize()); - } - } - return SendErrorResponse (7); -} - - -static void * -AcceptPortFromInferior (void *arg) -{ - const char *connect_url = (const char *)arg; - ConnectionFileDescriptor file_conn; - Error error; - if (file_conn.Connect (connect_url, &error) == eConnectionStatusSuccess) - { - char pid_str[256]; - ::memset (pid_str, 0, sizeof(pid_str)); - ConnectionStatus status; - const size_t pid_str_len = file_conn.Read (pid_str, sizeof(pid_str), 0, status, NULL); - if (pid_str_len > 0) - { - int pid = atoi (pid_str); - return (void *)(intptr_t)pid; - } - } - return NULL; -} -// -//static bool -//WaitForProcessToSIGSTOP (const lldb::pid_t pid, const int timeout_in_seconds) -//{ -// const int time_delta_usecs = 100000; -// const int num_retries = timeout_in_seconds/time_delta_usecs; -// for (int i=0; i<num_retries; i++) -// { -// struct proc_bsdinfo bsd_info; -// int error = ::proc_pidinfo (pid, PROC_PIDTBSDINFO, -// (uint64_t) 0, -// &bsd_info, -// PROC_PIDTBSDINFO_SIZE); -// -// switch (error) -// { -// case EINVAL: -// case ENOTSUP: -// case ESRCH: -// case EPERM: -// return false; -// -// default: -// break; -// -// case 0: -// if (bsd_info.pbi_status == SSTOP) -// return true; -// } -// ::usleep (time_delta_usecs); -// } -// return false; -//} - -bool -GDBRemoteCommunicationServer::Handle_A (StringExtractorGDBRemote &packet) -{ - // The 'A' packet is the most over designed packet ever here with - // redundant argument indexes, redundant argument lengths and needed hex - // encoded argument string values. Really all that is needed is a comma - // separated hex encoded argument value list, but we will stay true to the - // documented version of the 'A' packet here... - - packet.SetFilePos(1); // Skip the 'A' - bool success = true; - while (success && packet.GetBytesLeft() > 0) - { - // Decode the decimal argument string length. This length is the - // number of hex nibbles in the argument string value. - const uint32_t arg_len = packet.GetU32(UINT32_MAX); - if (arg_len == UINT32_MAX) - success = false; - else - { - // Make sure the argument hex string length is followed by a comma - if (packet.GetChar() != ',') - success = false; - else - { - // Decode the argument index. We ignore this really becuase - // who would really send down the arguments in a random order??? - const uint32_t arg_idx = packet.GetU32(UINT32_MAX); - if (arg_idx == UINT32_MAX) - success = false; - else - { - // Make sure the argument index is followed by a comma - if (packet.GetChar() != ',') - success = false; - else - { - // Decode the argument string value from hex bytes - // back into a UTF8 string and make sure the length - // matches the one supplied in the packet - std::string arg; - if (packet.GetHexByteString(arg) != (arg_len / 2)) - success = false; - else - { - // If there are any bytes lft - if (packet.GetBytesLeft()) - { - if (packet.GetChar() != ',') - success = false; - } - - if (success) - { - if (arg_idx == 0) - m_process_launch_info.GetExecutableFile().SetFile(arg.c_str(), false); - m_process_launch_info.GetArguments().AppendArgument(arg.c_str()); - } - } - } - } - } - } - } - - if (success) - { - m_process_launch_info.GetFlags().Set (eLaunchFlagDebug); - m_process_launch_error = Host::LaunchProcess (m_process_launch_info); - if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) - { - return SendOKResponse (); - } - } - return SendErrorResponse (8); -} - -bool -GDBRemoteCommunicationServer::Handle_qC (StringExtractorGDBRemote &packet) -{ - lldb::pid_t pid = m_process_launch_info.GetProcessID(); - StreamString response; - response.Printf("QC%llx", pid); - if (m_is_platform) - { - // If we launch a process and this GDB server is acting as a platform, - // then we need to clear the process launch state so we can start - // launching another process. In order to launch a process a bunch or - // packets need to be sent: environment packets, working directory, - // disable ASLR, and many more settings. When we launch a process we - // then need to know when to clear this information. Currently we are - // selecting the 'qC' packet as that packet which seems to make the most - // sense. - if (pid != LLDB_INVALID_PROCESS_ID) - { - m_process_launch_info.Clear(); - } - } - return SendPacketNoLock (response.GetData(), response.GetSize()); -} - -bool -GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet) -{ - // Spawn a local debugserver as a platform so we can then attach or launch - // a process... - - if (m_is_platform) - { - // Sleep and wait a bit for debugserver to start to listen... - ConnectionFileDescriptor file_conn; - char connect_url[PATH_MAX]; - Error error; - char unix_socket_name[PATH_MAX] = "/tmp/XXXXXX"; - if (::mktemp (unix_socket_name) == NULL) - { - error.SetErrorString ("failed to make temporary path for a unix socket"); - } - else - { - ::snprintf (connect_url, sizeof(connect_url), "unix-accept://%s", unix_socket_name); - // Spawn a new thread to accept the port that gets bound after - // binding to port 0 (zero). - lldb::thread_t accept_thread = Host::ThreadCreate (unix_socket_name, - AcceptPortFromInferior, - connect_url, - &error); - - if (IS_VALID_LLDB_HOST_THREAD(accept_thread)) - { - // Spawn a debugserver and try to get - ProcessLaunchInfo debugserver_launch_info; - error = StartDebugserverProcess ("localhost:0", - unix_socket_name, - debugserver_launch_info); - - lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID(); - if (error.Success()) - { - bool success = false; - - thread_result_t accept_thread_result = NULL; - if (Host::ThreadJoin (accept_thread, &accept_thread_result, &error)) - { - if (accept_thread_result) - { - uint16_t port = (intptr_t)accept_thread_result; - char response[256]; - const int response_len = ::snprintf (response, sizeof(response), "pid:%llu;port:%u;", debugserver_pid, port); - assert (response_len < sizeof(response)); - //m_port_to_pid_map[port] = debugserver_launch_info.GetProcessID(); - success = SendPacketNoLock (response, response_len) > 0; - } - } - ::unlink (unix_socket_name); - - if (!success) - { - if (debugserver_pid != LLDB_INVALID_PROCESS_ID) - ::kill (debugserver_pid, SIGINT); - } - return success; - } - } - } - } - return SendErrorResponse (13); -} - -bool -GDBRemoteCommunicationServer::Handle_qLaunchSuccess (StringExtractorGDBRemote &packet) -{ - if (m_process_launch_error.Success()) - return SendOKResponse(); - StreamString response; - response.PutChar('E'); - response.PutCString(m_process_launch_error.AsCString("<unknown error>")); - return SendPacketNoLock (response.GetData(), response.GetSize()); -} - -bool -GDBRemoteCommunicationServer::Handle_QEnvironment (StringExtractorGDBRemote &packet) -{ - packet.SetFilePos(::strlen ("QEnvironment:")); - const uint32_t bytes_left = packet.GetBytesLeft(); - if (bytes_left > 0) - { - m_process_launch_info.GetEnvironmentEntries ().AppendArgument (packet.Peek()); - return SendOKResponse (); - } - return SendErrorResponse (9); -} - -bool -GDBRemoteCommunicationServer::Handle_QSetDisableASLR (StringExtractorGDBRemote &packet) -{ - packet.SetFilePos(::strlen ("QSetDisableASLR:")); - if (packet.GetU32(0)) - m_process_launch_info.GetFlags().Set (eLaunchFlagDisableASLR); - else - m_process_launch_info.GetFlags().Clear (eLaunchFlagDisableASLR); - return SendOKResponse (); -} - -bool -GDBRemoteCommunicationServer::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet) -{ - packet.SetFilePos(::strlen ("QSetWorkingDir:")); - std::string path; - packet.GetHexByteString(path); - m_process_launch_info.SwapWorkingDirectory (path); - return SendOKResponse (); -} - -bool -GDBRemoteCommunicationServer::Handle_QSetSTDIN (StringExtractorGDBRemote &packet) -{ - packet.SetFilePos(::strlen ("QSetSTDIN:")); - ProcessLaunchInfo::FileAction file_action; - std::string path; - packet.GetHexByteString(path); - const bool read = false; - const bool write = true; - if (file_action.Open(STDIN_FILENO, path.c_str(), read, write)) - { - m_process_launch_info.AppendFileAction(file_action); - return SendOKResponse (); - } - return SendErrorResponse (10); -} - -bool -GDBRemoteCommunicationServer::Handle_QSetSTDOUT (StringExtractorGDBRemote &packet) -{ - packet.SetFilePos(::strlen ("QSetSTDOUT:")); - ProcessLaunchInfo::FileAction file_action; - std::string path; - packet.GetHexByteString(path); - const bool read = true; - const bool write = false; - if (file_action.Open(STDOUT_FILENO, path.c_str(), read, write)) - { - m_process_launch_info.AppendFileAction(file_action); - return SendOKResponse (); - } - return SendErrorResponse (11); -} - -bool -GDBRemoteCommunicationServer::Handle_QSetSTDERR (StringExtractorGDBRemote &packet) -{ - packet.SetFilePos(::strlen ("QSetSTDERR:")); - ProcessLaunchInfo::FileAction file_action; - std::string path; - packet.GetHexByteString(path); - const bool read = true; - const bool write = false; - if (file_action.Open(STDERR_FILENO, path.c_str(), read, write)) - { - m_process_launch_info.AppendFileAction(file_action); - return SendOKResponse (); - } - return SendErrorResponse (12); -} - -bool -GDBRemoteCommunicationServer::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet) -{ - // Send response first before changing m_send_acks to we ack this packet - SendOKResponse (); - m_send_acks = false; - return true; -} diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h deleted file mode 100644 index cce0e4e64c1e..000000000000 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h +++ /dev/null @@ -1,147 +0,0 @@ -//===-- GDBRemoteCommunicationServer.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_GDBRemoteCommunicationServer_h_ -#define liblldb_GDBRemoteCommunicationServer_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Target/Process.h" - -#include "GDBRemoteCommunication.h" - -class ProcessGDBRemote; -class StringExtractorGDBRemote; - -class GDBRemoteCommunicationServer : public GDBRemoteCommunication -{ -public: - enum - { - eBroadcastBitRunPacketSent = kLoUserBroadcastBit - }; - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - GDBRemoteCommunicationServer(bool is_platform); - - virtual - ~GDBRemoteCommunicationServer(); - - bool - GetPacketAndSendResponse (uint32_t timeout_usec, - lldb_private::Error &error, - bool &interrupt, - bool &quit); - - virtual bool - GetThreadSuffixSupported () - { - return true; - } - - // After connecting, do a little handshake with the client to make sure - // we are at least communicating - bool - HandshakeWithClient (lldb_private::Error *error_ptr); - - // Set both ports to zero to let the platform automatically bind to - // a port chosen by the OS. - void - SetPortRange (uint16_t lo_port_num, uint16_t hi_port_num) - { - m_lo_port_num = lo_port_num; - m_hi_port_num = hi_port_num; - } - -protected: - //typedef std::map<uint16_t, lldb::pid_t> PortToPIDMap; - - lldb::thread_t m_async_thread; - lldb_private::ProcessLaunchInfo m_process_launch_info; - lldb_private::Error m_process_launch_error; - lldb_private::ProcessInstanceInfoList m_proc_infos; - uint32_t m_proc_infos_index; - uint16_t m_lo_port_num; - uint16_t m_hi_port_num; - //PortToPIDMap m_port_to_pid_map; - - size_t - SendUnimplementedResponse (const char *packet); - - size_t - SendErrorResponse (uint8_t error); - - size_t - SendOKResponse (); - - bool - Handle_A (StringExtractorGDBRemote &packet); - - bool - Handle_qLaunchSuccess (StringExtractorGDBRemote &packet); - - bool - Handle_qHostInfo (StringExtractorGDBRemote &packet); - - bool - Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet); - - bool - Handle_qProcessInfoPID (StringExtractorGDBRemote &packet); - - bool - Handle_qfProcessInfo (StringExtractorGDBRemote &packet); - - bool - Handle_qsProcessInfo (StringExtractorGDBRemote &packet); - - bool - Handle_qC (StringExtractorGDBRemote &packet); - - bool - Handle_qUserName (StringExtractorGDBRemote &packet); - - bool - Handle_qGroupName (StringExtractorGDBRemote &packet); - - bool - Handle_qSpeedTest (StringExtractorGDBRemote &packet); - - bool - Handle_QEnvironment (StringExtractorGDBRemote &packet); - - bool - Handle_QSetDisableASLR (StringExtractorGDBRemote &packet); - - bool - Handle_QSetWorkingDir (StringExtractorGDBRemote &packet); - - bool - Handle_QStartNoAckMode (StringExtractorGDBRemote &packet); - - bool - Handle_QSetSTDIN (StringExtractorGDBRemote &packet); - - bool - Handle_QSetSTDOUT (StringExtractorGDBRemote &packet); - - bool - Handle_QSetSTDERR (StringExtractorGDBRemote &packet); - -private: - //------------------------------------------------------------------ - // For GDBRemoteCommunicationServer only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationServer); -}; - -#endif // liblldb_GDBRemoteCommunicationServer_h_ diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp deleted file mode 100644 index 7ace1ebe4775..000000000000 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ /dev/null @@ -1,865 +0,0 @@ -//===-- GDBRemoteRegisterContext.cpp ----------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "GDBRemoteRegisterContext.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Target/ExecutionContext.h" -// Project includes -#include "Utility/StringExtractorGDBRemote.h" -#include "ProcessGDBRemote.h" -#include "ProcessGDBRemoteLog.h" -#include "ThreadGDBRemote.h" -#include "Utility/ARM_GCC_Registers.h" -#include "Utility/ARM_DWARF_Registers.h" - -using namespace lldb; -using namespace lldb_private; - -//---------------------------------------------------------------------- -// GDBRemoteRegisterContext constructor -//---------------------------------------------------------------------- -GDBRemoteRegisterContext::GDBRemoteRegisterContext -( - ThreadGDBRemote &thread, - uint32_t concrete_frame_idx, - GDBRemoteDynamicRegisterInfo ®_info, - bool read_all_at_once -) : - RegisterContext (thread, concrete_frame_idx), - m_reg_info (reg_info), - m_reg_valid (), - m_reg_data (), - m_read_all_at_once (read_all_at_once) -{ - // Resize our vector of bools to contain one bool for every register. - // We will use these boolean values to know when a register value - // is valid in m_reg_data. - m_reg_valid.resize (reg_info.GetNumRegisters()); - - // Make a heap based buffer that is big enough to store all registers - DataBufferSP reg_data_sp(new DataBufferHeap (reg_info.GetRegisterDataByteSize(), 0)); - m_reg_data.SetData (reg_data_sp); - -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -GDBRemoteRegisterContext::~GDBRemoteRegisterContext() -{ -} - -void -GDBRemoteRegisterContext::InvalidateAllRegisters () -{ - SetAllRegisterValid (false); -} - -void -GDBRemoteRegisterContext::SetAllRegisterValid (bool b) -{ - std::vector<bool>::iterator pos, end = m_reg_valid.end(); - for (pos = m_reg_valid.begin(); pos != end; ++pos) - *pos = b; -} - -size_t -GDBRemoteRegisterContext::GetRegisterCount () -{ - return m_reg_info.GetNumRegisters (); -} - -const RegisterInfo * -GDBRemoteRegisterContext::GetRegisterInfoAtIndex (uint32_t reg) -{ - return m_reg_info.GetRegisterInfoAtIndex (reg); -} - -size_t -GDBRemoteRegisterContext::GetRegisterSetCount () -{ - return m_reg_info.GetNumRegisterSets (); -} - - - -const RegisterSet * -GDBRemoteRegisterContext::GetRegisterSet (uint32_t reg_set) -{ - return m_reg_info.GetRegisterSet (reg_set); -} - - - -bool -GDBRemoteRegisterContext::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) -{ - // Read the register - if (ReadRegisterBytes (reg_info, m_reg_data)) - { - const bool partial_data_ok = false; - Error error (value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok)); - return error.Success(); - } - return false; -} - -bool -GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response) -{ - const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); - if (reg_info == NULL) - return false; - - // Invalidate if needed - InvalidateIfNeeded(false); - - const uint32_t reg_byte_size = reg_info->byte_size; - const size_t bytes_copied = response.GetHexBytes (const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)), reg_byte_size, '\xcc'); - bool success = bytes_copied == reg_byte_size; - if (success) - { - m_reg_valid[reg] = true; - } - else if (bytes_copied > 0) - { - // Only set register is valid to false if we copied some bytes, else - // leave it as it was. - m_reg_valid[reg] = false; - } - return success; -} - -// Helper function for GDBRemoteRegisterContext::ReadRegisterBytes(). -bool -GDBRemoteRegisterContext::GetPrimordialRegister(const lldb_private::RegisterInfo *reg_info, - GDBRemoteCommunicationClient &gdb_comm) -{ - char packet[64]; - StringExtractorGDBRemote response; - int packet_len = 0; - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - if (gdb_comm.GetThreadSuffixSupported()) - packet_len = ::snprintf (packet, sizeof(packet), "p%x;thread:%4.4llx;", reg, m_thread.GetID()); - else - packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg); - assert (packet_len < (sizeof(packet) - 1)); - if (gdb_comm.SendPacketAndWaitForResponse(packet, response, false)) - return PrivateSetRegisterValue (reg, response); - - return false; -} -bool -GDBRemoteRegisterContext::ReadRegisterBytes (const RegisterInfo *reg_info, DataExtractor &data) -{ - ExecutionContext exe_ctx (CalculateThread()); - - Process *process = exe_ctx.GetProcessPtr(); - Thread *thread = exe_ctx.GetThreadPtr(); - if (process == NULL || thread == NULL) - return false; - - GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); - - InvalidateIfNeeded(false); - - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - - if (!m_reg_valid[reg]) - { - Mutex::Locker locker; - if (gdb_comm.GetSequenceMutex (locker)) - { - const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); - ProcessSP process_sp (m_thread.GetProcess()); - if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID())) - { - char packet[64]; - StringExtractorGDBRemote response; - int packet_len = 0; - if (m_read_all_at_once) - { - // Get all registers in one packet - if (thread_suffix_supported) - packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4llx;", m_thread.GetID()); - else - packet_len = ::snprintf (packet, sizeof(packet), "g"); - assert (packet_len < (sizeof(packet) - 1)); - if (gdb_comm.SendPacketAndWaitForResponse(packet, response, false)) - { - if (response.IsNormalResponse()) - if (response.GetHexBytes ((void *)m_reg_data.GetDataStart(), m_reg_data.GetByteSize(), '\xcc') == m_reg_data.GetByteSize()) - SetAllRegisterValid (true); - } - } - else if (!reg_info->value_regs) - { - // Get each register individually - GetPrimordialRegister(reg_info, gdb_comm); - } - else - { - // Process this composite register request by delegating to the constituent - // primordial registers. - - // Index of the primordial register. - uint32_t prim_reg_idx; - bool success = true; - for (uint32_t idx = 0; - (prim_reg_idx = reg_info->value_regs[idx]) != LLDB_INVALID_REGNUM; - ++idx) - { - // We have a valid primordial regsiter as our constituent. - // Grab the corresponding register info. - const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg_idx); - if (!GetPrimordialRegister(prim_reg_info, gdb_comm)) - { - success = false; - // Some failure occurred. Let's break out of the for loop. - break; - } - } - if (success) - { - // If we reach this point, all primordial register requests have succeeded. - // Validate this composite register. - m_reg_valid[reg_info->kinds[eRegisterKindLLDB]] = true; - } - } - } - } - else - { - LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS)); - if (log) - { - if (log->GetVerbose()) - { - StreamString strm; - gdb_comm.DumpHistory(strm); - log->Printf("error: failed to get packet sequence mutex, not sending read register for \"%s\":\n%s", reg_info->name, strm.GetData()); - } - else - { - log->Printf("error: failed to get packet sequence mutex, not sending read register for \"%s\"", reg_info->name); - } - } - } - - // Make sure we got a valid register value after reading it - if (!m_reg_valid[reg]) - return false; - } - - if (&data != &m_reg_data) - { - // If we aren't extracting into our own buffer (which - // only happens when this function is called from - // ReadRegisterValue(uint32_t, Scalar&)) then - // we transfer bytes from our buffer into the data - // buffer that was passed in - data.SetByteOrder (m_reg_data.GetByteOrder()); - data.SetData (m_reg_data, reg_info->byte_offset, reg_info->byte_size); - } - return true; -} - - -bool -GDBRemoteRegisterContext::WriteRegister (const RegisterInfo *reg_info, - const RegisterValue &value) -{ - DataExtractor data; - if (value.GetData (data)) - return WriteRegisterBytes (reg_info, data, 0); - return false; -} - -// Helper function for GDBRemoteRegisterContext::WriteRegisterBytes(). -bool -GDBRemoteRegisterContext::SetPrimordialRegister(const lldb_private::RegisterInfo *reg_info, - GDBRemoteCommunicationClient &gdb_comm) -{ - StreamString packet; - StringExtractorGDBRemote response; - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - packet.Printf ("P%x=", reg); - packet.PutBytesAsRawHex8 (m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size), - reg_info->byte_size, - lldb::endian::InlHostByteOrder(), - lldb::endian::InlHostByteOrder()); - - if (gdb_comm.GetThreadSuffixSupported()) - packet.Printf (";thread:%4.4llx;", m_thread.GetID()); - - // Invalidate just this register - m_reg_valid[reg] = false; - if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), - packet.GetString().size(), - response, - false)) - { - if (response.IsOKResponse()) - return true; - } - return false; -} -bool -GDBRemoteRegisterContext::WriteRegisterBytes (const lldb_private::RegisterInfo *reg_info, DataExtractor &data, uint32_t data_offset) -{ - ExecutionContext exe_ctx (CalculateThread()); - - Process *process = exe_ctx.GetProcessPtr(); - Thread *thread = exe_ctx.GetThreadPtr(); - if (process == NULL || thread == NULL) - return false; - - GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); -// FIXME: This check isn't right because IsRunning checks the Public state, but this -// is work you need to do - for instance in ShouldStop & friends - before the public -// state has been changed. -// if (gdb_comm.IsRunning()) -// return false; - - // Grab a pointer to where we are going to put this register - uint8_t *dst = const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size)); - - if (dst == NULL) - return false; - - - if (data.CopyByteOrderedData (data_offset, // src offset - reg_info->byte_size, // src length - dst, // dst - reg_info->byte_size, // dst length - m_reg_data.GetByteOrder())) // dst byte order - { - Mutex::Locker locker; - if (gdb_comm.GetSequenceMutex (locker)) - { - const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); - ProcessSP process_sp (m_thread.GetProcess()); - if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID())) - { - uint32_t offset, end_offset; - StreamString packet; - StringExtractorGDBRemote response; - if (m_read_all_at_once) - { - // Set all registers in one packet - packet.PutChar ('G'); - offset = 0; - end_offset = m_reg_data.GetByteSize(); - - packet.PutBytesAsRawHex8 (m_reg_data.GetDataStart(), - m_reg_data.GetByteSize(), - lldb::endian::InlHostByteOrder(), - lldb::endian::InlHostByteOrder()); - - if (thread_suffix_supported) - packet.Printf (";thread:%4.4llx;", m_thread.GetID()); - - // Invalidate all register values - InvalidateIfNeeded (true); - - if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), - packet.GetString().size(), - response, - false)) - { - SetAllRegisterValid (false); - if (response.IsOKResponse()) - { - return true; - } - } - } - else if (!reg_info->value_regs) - { - // Set each register individually - return SetPrimordialRegister(reg_info, gdb_comm); - } - else - { - // Process this composite register request by delegating to the constituent - // primordial registers. - - // Invalidate this composite register first. - m_reg_valid[reg_info->kinds[eRegisterKindLLDB]] = false; - - // Index of the primordial register. - uint32_t prim_reg_idx; - // For loop index. - uint32_t idx; - - // Invalidate the invalidate_regs, if present. - if (reg_info->invalidate_regs) - { - for (idx = 0; - (prim_reg_idx = reg_info->invalidate_regs[idx]) != LLDB_INVALID_REGNUM; - ++idx) - { - // Grab the invalidate register info. - const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg_idx); - m_reg_valid[prim_reg_info->kinds[eRegisterKindLLDB]] = false; - } - } - - bool success = true; - for (idx = 0; - (prim_reg_idx = reg_info->value_regs[idx]) != LLDB_INVALID_REGNUM; - ++idx) - { - // We have a valid primordial regsiter as our constituent. - // Grab the corresponding register info. - const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg_idx); - if (!SetPrimordialRegister(prim_reg_info, gdb_comm)) - { - success = false; - // Some failure occurred. Let's break out of the for loop. - break; - } - } - return success; - } - } - } - else - { - LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS)); - if (log) - { - if (log->GetVerbose()) - { - StreamString strm; - gdb_comm.DumpHistory(strm); - log->Printf("error: failed to get packet sequence mutex, not sending write register for \"%s\":\n%s", reg_info->name, strm.GetData()); - } - else - log->Printf("error: failed to get packet sequence mutex, not sending write register for \"%s\"", reg_info->name); - } - } - } - return false; -} - - -bool -GDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) -{ - ExecutionContext exe_ctx (CalculateThread()); - - Process *process = exe_ctx.GetProcessPtr(); - Thread *thread = exe_ctx.GetThreadPtr(); - if (process == NULL || thread == NULL) - return false; - - GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); - - StringExtractorGDBRemote response; - - Mutex::Locker locker; - if (gdb_comm.GetSequenceMutex (locker)) - { - char packet[32]; - const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); - ProcessSP process_sp (m_thread.GetProcess()); - if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID())) - { - int packet_len = 0; - if (thread_suffix_supported) - packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4llx", m_thread.GetID()); - else - packet_len = ::snprintf (packet, sizeof(packet), "g"); - assert (packet_len < (sizeof(packet) - 1)); - - if (gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false)) - { - if (response.IsErrorResponse()) - return false; - - std::string &response_str = response.GetStringRef(); - if (isxdigit(response_str[0])) - { - response_str.insert(0, 1, 'G'); - if (thread_suffix_supported) - { - char thread_id_cstr[64]; - ::snprintf (thread_id_cstr, sizeof(thread_id_cstr), ";thread:%4.4llx;", m_thread.GetID()); - response_str.append (thread_id_cstr); - } - data_sp.reset (new DataBufferHeap (response_str.c_str(), response_str.size())); - return true; - } - } - } - } - else - { - LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS)); - if (log) - { - if (log->GetVerbose()) - { - StreamString strm; - gdb_comm.DumpHistory(strm); - log->Printf("error: failed to get packet sequence mutex, not sending read all registers:\n%s", strm.GetData()); - } - else - log->Printf("error: failed to get packet sequence mutex, not sending read all registers"); - } - } - - data_sp.reset(); - return false; -} - -bool -GDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) -{ - if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0) - return false; - - ExecutionContext exe_ctx (CalculateThread()); - - Process *process = exe_ctx.GetProcessPtr(); - Thread *thread = exe_ctx.GetThreadPtr(); - if (process == NULL || thread == NULL) - return false; - - GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); - - StringExtractorGDBRemote response; - Mutex::Locker locker; - if (gdb_comm.GetSequenceMutex (locker)) - { - const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); - ProcessSP process_sp (m_thread.GetProcess()); - if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetID())) - { - // The data_sp contains the entire G response packet including the - // G, and if the thread suffix is supported, it has the thread suffix - // as well. - const char *G_packet = (const char *)data_sp->GetBytes(); - size_t G_packet_len = data_sp->GetByteSize(); - if (gdb_comm.SendPacketAndWaitForResponse (G_packet, - G_packet_len, - response, - false)) - { - if (response.IsOKResponse()) - return true; - else if (response.IsErrorResponse()) - { - uint32_t num_restored = 0; - // We need to manually go through all of the registers and - // restore them manually - - response.GetStringRef().assign (G_packet, G_packet_len); - response.SetFilePos(1); // Skip the leading 'G' - DataBufferHeap buffer (m_reg_data.GetByteSize(), 0); - DataExtractor restore_data (buffer.GetBytes(), - buffer.GetByteSize(), - m_reg_data.GetByteOrder(), - m_reg_data.GetAddressByteSize()); - - const uint32_t bytes_extracted = response.GetHexBytes ((void *)restore_data.GetDataStart(), - restore_data.GetByteSize(), - '\xcc'); - - if (bytes_extracted < restore_data.GetByteSize()) - restore_data.SetData(restore_data.GetDataStart(), bytes_extracted, m_reg_data.GetByteOrder()); - - //ReadRegisterBytes (const RegisterInfo *reg_info, RegisterValue &value, DataExtractor &data) - const RegisterInfo *reg_info; - // We have to march the offset of each register along in the - // buffer to make sure we get the right offset. - uint32_t reg_byte_offset = 0; - for (uint32_t reg_idx=0; (reg_info = GetRegisterInfoAtIndex (reg_idx)) != NULL; ++reg_idx, reg_byte_offset += reg_info->byte_size) - { - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - - // Skip composite registers. - if (reg_info->value_regs) - continue; - - // Only write down the registers that need to be written - // if we are going to be doing registers individually. - bool write_reg = true; - const uint32_t reg_byte_size = reg_info->byte_size; - - const char *restore_src = (const char *)restore_data.PeekData(reg_byte_offset, reg_byte_size); - if (restore_src) - { - if (m_reg_valid[reg]) - { - const char *current_src = (const char *)m_reg_data.PeekData(reg_byte_offset, reg_byte_size); - if (current_src) - write_reg = memcmp (current_src, restore_src, reg_byte_size) != 0; - } - - if (write_reg) - { - StreamString packet; - packet.Printf ("P%x=", reg); - packet.PutBytesAsRawHex8 (restore_src, - reg_byte_size, - lldb::endian::InlHostByteOrder(), - lldb::endian::InlHostByteOrder()); - - if (thread_suffix_supported) - packet.Printf (";thread:%4.4llx;", m_thread.GetID()); - - m_reg_valid[reg] = false; - if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), - packet.GetString().size(), - response, - false)) - { - if (response.IsOKResponse()) - ++num_restored; - } - } - } - } - return num_restored > 0; - } - } - } - } - else - { - LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS)); - if (log) - { - if (log->GetVerbose()) - { - StreamString strm; - gdb_comm.DumpHistory(strm); - log->Printf("error: failed to get packet sequence mutex, not sending write all registers:\n%s", strm.GetData()); - } - else - log->Printf("error: failed to get packet sequence mutex, not sending write all registers"); - } - } - return false; -} - - -uint32_t -GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) -{ - return m_reg_info.ConvertRegisterKindToRegisterNumber (kind, num); -} - -void -GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters() -{ - // For Advanced SIMD and VFP register mapping. - static uint32_t g_d0_regs[] = { 26, 27, LLDB_INVALID_REGNUM }; // (s0, s1) - static uint32_t g_d1_regs[] = { 28, 29, LLDB_INVALID_REGNUM }; // (s2, s3) - static uint32_t g_d2_regs[] = { 30, 31, LLDB_INVALID_REGNUM }; // (s4, s5) - static uint32_t g_d3_regs[] = { 32, 33, LLDB_INVALID_REGNUM }; // (s6, s7) - static uint32_t g_d4_regs[] = { 34, 35, LLDB_INVALID_REGNUM }; // (s8, s9) - static uint32_t g_d5_regs[] = { 36, 37, LLDB_INVALID_REGNUM }; // (s10, s11) - static uint32_t g_d6_regs[] = { 38, 39, LLDB_INVALID_REGNUM }; // (s12, s13) - static uint32_t g_d7_regs[] = { 40, 41, LLDB_INVALID_REGNUM }; // (s14, s15) - static uint32_t g_d8_regs[] = { 42, 43, LLDB_INVALID_REGNUM }; // (s16, s17) - static uint32_t g_d9_regs[] = { 44, 45, LLDB_INVALID_REGNUM }; // (s18, s19) - static uint32_t g_d10_regs[] = { 46, 47, LLDB_INVALID_REGNUM }; // (s20, s21) - static uint32_t g_d11_regs[] = { 48, 49, LLDB_INVALID_REGNUM }; // (s22, s23) - static uint32_t g_d12_regs[] = { 50, 51, LLDB_INVALID_REGNUM }; // (s24, s25) - static uint32_t g_d13_regs[] = { 52, 53, LLDB_INVALID_REGNUM }; // (s26, s27) - static uint32_t g_d14_regs[] = { 54, 55, LLDB_INVALID_REGNUM }; // (s28, s29) - static uint32_t g_d15_regs[] = { 56, 57, LLDB_INVALID_REGNUM }; // (s30, s31) - static uint32_t g_q0_regs[] = { 26, 27, 28, 29, LLDB_INVALID_REGNUM }; // (d0, d1) -> (s0, s1, s2, s3) - static uint32_t g_q1_regs[] = { 30, 31, 32, 33, LLDB_INVALID_REGNUM }; // (d2, d3) -> (s4, s5, s6, s7) - static uint32_t g_q2_regs[] = { 34, 35, 36, 37, LLDB_INVALID_REGNUM }; // (d4, d5) -> (s8, s9, s10, s11) - static uint32_t g_q3_regs[] = { 38, 39, 40, 41, LLDB_INVALID_REGNUM }; // (d6, d7) -> (s12, s13, s14, s15) - static uint32_t g_q4_regs[] = { 42, 43, 44, 45, LLDB_INVALID_REGNUM }; // (d8, d9) -> (s16, s17, s18, s19) - static uint32_t g_q5_regs[] = { 46, 47, 48, 49, LLDB_INVALID_REGNUM }; // (d10, d11) -> (s20, s21, s22, s23) - static uint32_t g_q6_regs[] = { 50, 51, 52, 53, LLDB_INVALID_REGNUM }; // (d12, d13) -> (s24, s25, s26, s27) - static uint32_t g_q7_regs[] = { 54, 55, 56, 57, LLDB_INVALID_REGNUM }; // (d14, d15) -> (s28, s29, s30, s31) - static uint32_t g_q8_regs[] = { 59, 60, LLDB_INVALID_REGNUM }; // (d16, d17) - static uint32_t g_q9_regs[] = { 61, 62, LLDB_INVALID_REGNUM }; // (d18, d19) - static uint32_t g_q10_regs[] = { 63, 64, LLDB_INVALID_REGNUM }; // (d20, d21) - static uint32_t g_q11_regs[] = { 65, 66, LLDB_INVALID_REGNUM }; // (d22, d23) - static uint32_t g_q12_regs[] = { 67, 68, LLDB_INVALID_REGNUM }; // (d24, d25) - static uint32_t g_q13_regs[] = { 69, 70, LLDB_INVALID_REGNUM }; // (d26, d27) - static uint32_t g_q14_regs[] = { 71, 72, LLDB_INVALID_REGNUM }; // (d28, d29) - static uint32_t g_q15_regs[] = { 73, 74, LLDB_INVALID_REGNUM }; // (d30, d31) - - static RegisterInfo g_register_infos[] = { -// NAME ALT SZ OFF ENCODING FORMAT COMPILER DWARF GENERIC GDB LLDB VALUE REGS INVALIDATE REGS -// ====== ====== === === ============= ============ =================== =================== ====================== === ==== ========== =============== - { "r0", "arg1", 4, 0, eEncodingUint, eFormatHex, { gcc_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1,0, 0 }, NULL, NULL}, - { "r1", "arg2", 4, 0, eEncodingUint, eFormatHex, { gcc_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2,1, 1 }, NULL, NULL}, - { "r2", "arg3", 4, 0, eEncodingUint, eFormatHex, { gcc_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3,2, 2 }, NULL, NULL}, - { "r3", "arg4", 4, 0, eEncodingUint, eFormatHex, { gcc_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4,3, 3 }, NULL, NULL}, - { "r4", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r4, dwarf_r4, LLDB_INVALID_REGNUM, 4, 4 }, NULL, NULL}, - { "r5", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r5, dwarf_r5, LLDB_INVALID_REGNUM, 5, 5 }, NULL, NULL}, - { "r6", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r6, dwarf_r6, LLDB_INVALID_REGNUM, 6, 6 }, NULL, NULL}, - { "r7", "fp", 4, 0, eEncodingUint, eFormatHex, { gcc_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, 7, 7 }, NULL, NULL}, - { "r8", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r8, dwarf_r8, LLDB_INVALID_REGNUM, 8, 8 }, NULL, NULL}, - { "r9", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r9, dwarf_r9, LLDB_INVALID_REGNUM, 9, 9 }, NULL, NULL}, - { "r10", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r10, dwarf_r10, LLDB_INVALID_REGNUM, 10, 10 }, NULL, NULL}, - { "r11", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r11, dwarf_r11, LLDB_INVALID_REGNUM, 11, 11 }, NULL, NULL}, - { "r12", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r12, dwarf_r12, LLDB_INVALID_REGNUM, 12, 12 }, NULL, NULL}, - { "sp", "r13", 4, 0, eEncodingUint, eFormatHex, { gcc_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, 13, 13 }, NULL, NULL}, - { "lr", "r14", 4, 0, eEncodingUint, eFormatHex, { gcc_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, 14, 14 }, NULL, NULL}, - { "pc", "r15", 4, 0, eEncodingUint, eFormatHex, { gcc_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, 15, 15 }, NULL, NULL}, - { "f0", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 16, 16 }, NULL, NULL}, - { "f1", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 17, 17 }, NULL, NULL}, - { "f2", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 18, 18 }, NULL, NULL}, - { "f3", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 19, 19 }, NULL, NULL}, - { "f4", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 20, 20 }, NULL, NULL}, - { "f5", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 21, 21 }, NULL, NULL}, - { "f6", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 22, 22 }, NULL, NULL}, - { "f7", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 23, 23 }, NULL, NULL}, - { "fps", NULL, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 24, 24 }, NULL, NULL}, - { "cpsr","flags", 4, 0, eEncodingUint, eFormatHex, { gcc_cpsr, dwarf_cpsr, LLDB_INVALID_REGNUM, 25, 25 }, NULL, NULL}, - { "s0", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, 26, 26 }, NULL, NULL}, - { "s1", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, 27, 27 }, NULL, NULL}, - { "s2", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, 28, 28 }, NULL, NULL}, - { "s3", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, 29, 29 }, NULL, NULL}, - { "s4", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, 30, 30 }, NULL, NULL}, - { "s5", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, 31, 31 }, NULL, NULL}, - { "s6", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, 32, 32 }, NULL, NULL}, - { "s7", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, 33, 33 }, NULL, NULL}, - { "s8", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, 34, 34 }, NULL, NULL}, - { "s9", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, 35, 35 }, NULL, NULL}, - { "s10", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, 36, 36 }, NULL, NULL}, - { "s11", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, 37, 37 }, NULL, NULL}, - { "s12", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, 38, 38 }, NULL, NULL}, - { "s13", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, 39, 39 }, NULL, NULL}, - { "s14", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, 40, 40 }, NULL, NULL}, - { "s15", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, 41, 41 }, NULL, NULL}, - { "s16", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, 42, 42 }, NULL, NULL}, - { "s17", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, 43, 43 }, NULL, NULL}, - { "s18", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, 44, 44 }, NULL, NULL}, - { "s19", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, 45, 45 }, NULL, NULL}, - { "s20", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, 46, 46 }, NULL, NULL}, - { "s21", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, 47, 47 }, NULL, NULL}, - { "s22", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, 48, 48 }, NULL, NULL}, - { "s23", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, 49, 49 }, NULL, NULL}, - { "s24", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, 50, 50 }, NULL, NULL}, - { "s25", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, 51, 51 }, NULL, NULL}, - { "s26", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, 52, 52 }, NULL, NULL}, - { "s27", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, 53, 53 }, NULL, NULL}, - { "s28", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, 54, 54 }, NULL, NULL}, - { "s29", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, 55, 55 }, NULL, NULL}, - { "s30", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, 56, 56 }, NULL, NULL}, - { "s31", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, 57, 57 }, NULL, NULL}, - { "fpscr",NULL, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 58, 58 }, NULL, NULL}, - { "d16", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, 59, 59 }, NULL, NULL}, - { "d17", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, 60, 60 }, NULL, NULL}, - { "d18", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, 61, 61 }, NULL, NULL}, - { "d19", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, 62, 62 }, NULL, NULL}, - { "d20", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, 63, 63 }, NULL, NULL}, - { "d21", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, 64, 64 }, NULL, NULL}, - { "d22", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, 65, 65 }, NULL, NULL}, - { "d23", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, 66, 66 }, NULL, NULL}, - { "d24", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, 67, 67 }, NULL, NULL}, - { "d25", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, 68, 68 }, NULL, NULL}, - { "d26", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, 69, 69 }, NULL, NULL}, - { "d27", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, 70, 70 }, NULL, NULL}, - { "d28", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, 71, 71 }, NULL, NULL}, - { "d29", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, 72, 72 }, NULL, NULL}, - { "d30", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, 73, 73 }, NULL, NULL}, - { "d31", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, 74, 74 }, NULL, NULL}, - { "d0", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, 75, 75 }, g_d0_regs, NULL}, - { "d1", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, 76, 76 }, g_d1_regs, NULL}, - { "d2", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, 77, 77 }, g_d2_regs, NULL}, - { "d3", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, 78, 78 }, g_d3_regs, NULL}, - { "d4", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, 79, 79 }, g_d4_regs, NULL}, - { "d5", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, 80, 80 }, g_d5_regs, NULL}, - { "d6", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, 81, 81 }, g_d6_regs, NULL}, - { "d7", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, 82, 82 }, g_d7_regs, NULL}, - { "d8", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, 83, 83 }, g_d8_regs, NULL}, - { "d9", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, 84, 84 }, g_d9_regs, NULL}, - { "d10", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, 85, 85 }, g_d10_regs, NULL}, - { "d11", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, 86, 86 }, g_d11_regs, NULL}, - { "d12", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, 87, 87 }, g_d12_regs, NULL}, - { "d13", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, 88, 88 }, g_d13_regs, NULL}, - { "d14", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, 89, 89 }, g_d14_regs, NULL}, - { "d15", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, 90, 90 }, g_d15_regs, NULL}, - { "q0", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q0, LLDB_INVALID_REGNUM, 91, 91 }, g_q0_regs, NULL}, - { "q1", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q1, LLDB_INVALID_REGNUM, 92, 92 }, g_q1_regs, NULL}, - { "q2", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q2, LLDB_INVALID_REGNUM, 93, 93 }, g_q2_regs, NULL}, - { "q3", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q3, LLDB_INVALID_REGNUM, 94, 94 }, g_q3_regs, NULL}, - { "q4", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q4, LLDB_INVALID_REGNUM, 95, 95 }, g_q4_regs, NULL}, - { "q5", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q5, LLDB_INVALID_REGNUM, 96, 96 }, g_q5_regs, NULL}, - { "q6", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q6, LLDB_INVALID_REGNUM, 97, 97 }, g_q6_regs, NULL}, - { "q7", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q7, LLDB_INVALID_REGNUM, 98, 98 }, g_q7_regs, NULL}, - { "q8", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q8, LLDB_INVALID_REGNUM, 99, 99 }, g_q8_regs, NULL}, - { "q9", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q9, LLDB_INVALID_REGNUM, 100, 100 }, g_q9_regs, NULL}, - { "q10", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q10, LLDB_INVALID_REGNUM, 101, 101 }, g_q10_regs, NULL}, - { "q11", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q11, LLDB_INVALID_REGNUM, 102, 102 }, g_q11_regs, NULL}, - { "q12", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q12, LLDB_INVALID_REGNUM, 103, 103 }, g_q12_regs, NULL}, - { "q13", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q13, LLDB_INVALID_REGNUM, 104, 104 }, g_q13_regs, NULL}, - { "q14", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q14, LLDB_INVALID_REGNUM, 105, 105 }, g_q14_regs, NULL}, - { "q15", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q15, LLDB_INVALID_REGNUM, 106, 106 }, g_q15_regs, NULL} - }; - - static const uint32_t num_registers = sizeof (g_register_infos)/sizeof (RegisterInfo); - static ConstString gpr_reg_set ("General Purpose Registers"); - static ConstString sfp_reg_set ("Software Floating Point Registers"); - static ConstString vfp_reg_set ("Floating Point Registers"); - uint32_t i; - // Calculate the offsets of the registers - // Note that the layout of the "composite" registers (d0-d15 and q0-q15) which comes after the - // "primordial" registers is important. This enables us to calculate the offset of the composite - // register by using the offset of its first primordial register. For example, to calculate the - // offset of q0, use s0's offset. - if (g_register_infos[2].byte_offset == 0) - { - uint32_t byte_offset = 0; - for (i=0; i<num_registers; ++i) - { - // For primordial registers, increment the byte_offset by the byte_size to arrive at the - // byte_offset for the next register. Otherwise, we have a composite register whose - // offset can be calculated by consulting the offset of its first primordial register. - if (!g_register_infos[i].value_regs) - { - g_register_infos[i].byte_offset = byte_offset; - byte_offset += g_register_infos[i].byte_size; - } - else - { - const uint32_t first_primordial_reg = g_register_infos[i].value_regs[0]; - g_register_infos[i].byte_offset = g_register_infos[first_primordial_reg].byte_offset; - } - } - } - for (i=0; i<num_registers; ++i) - { - ConstString name; - ConstString alt_name; - if (g_register_infos[i].name && g_register_infos[i].name[0]) - name.SetCString(g_register_infos[i].name); - if (g_register_infos[i].alt_name && g_register_infos[i].alt_name[0]) - alt_name.SetCString(g_register_infos[i].alt_name); - - if (i <= 15 || i == 25) - AddRegister (g_register_infos[i], name, alt_name, gpr_reg_set); - else if (i <= 24) - AddRegister (g_register_infos[i], name, alt_name, sfp_reg_set); - else - AddRegister (g_register_infos[i], name, alt_name, vfp_reg_set); - } -} - diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h deleted file mode 100644 index 257baf4df83c..000000000000 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h +++ /dev/null @@ -1,262 +0,0 @@ -//===-- GDBRemoteRegisterContext.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_GDBRemoteRegisterContext_h_ -#define lldb_GDBRemoteRegisterContext_h_ - -// C Includes -// C++ Includes -#include <vector> - -// Other libraries and framework includes -// Project includes -#include "lldb/lldb-private.h" -#include "lldb/lldb-enumerations.h" -#include "lldb/Core/ConstString.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Target/RegisterContext.h" -#include "GDBRemoteCommunicationClient.h" - -class ThreadGDBRemote; -class ProcessGDBRemote; -class StringExtractor; - -class GDBRemoteDynamicRegisterInfo -{ -public: - GDBRemoteDynamicRegisterInfo () : - m_regs (), - m_sets (), - m_set_reg_nums (), - m_reg_names (), - m_reg_alt_names (), - m_set_names (), - m_reg_data_byte_size (0) - { - } - - ~GDBRemoteDynamicRegisterInfo () - { - } - - void - AddRegister (lldb_private::RegisterInfo ®_info, - lldb_private::ConstString ®_name, - lldb_private::ConstString ®_alt_name, - lldb_private::ConstString &set_name) - { - const uint32_t reg_num = m_regs.size(); - m_reg_names.push_back (reg_name); - m_reg_alt_names.push_back (reg_alt_name); - reg_info.name = reg_name.AsCString(); - assert (reg_info.name); - reg_info.alt_name = reg_alt_name.AsCString(NULL); - m_regs.push_back (reg_info); - uint32_t set = GetRegisterSetIndexByName (set_name, true); - assert (set < m_sets.size()); - assert (set < m_set_reg_nums.size()); - assert (set < m_set_names.size()); - m_set_reg_nums[set].push_back(reg_num); - size_t end_reg_offset = reg_info.byte_offset + reg_info.byte_size; - if (m_reg_data_byte_size < end_reg_offset) - m_reg_data_byte_size = end_reg_offset; - } - - void - Finalize () - { - for (uint32_t set = 0; set < m_sets.size(); ++set) - { - assert (m_sets.size() == m_set_reg_nums.size()); - m_sets[set].num_registers = m_set_reg_nums[set].size(); - m_sets[set].registers = &m_set_reg_nums[set][0]; - } - } - - size_t - GetNumRegisters() const - { - return m_regs.size(); - } - - size_t - GetNumRegisterSets() const - { - return m_sets.size(); - } - - size_t - GetRegisterDataByteSize() const - { - return m_reg_data_byte_size; - } - - const lldb_private::RegisterInfo * - GetRegisterInfoAtIndex (uint32_t i) const - { - if (i < m_regs.size()) - return &m_regs[i]; - return NULL; - } - - const lldb_private::RegisterSet * - GetRegisterSet (uint32_t i) const - { - if (i < m_sets.size()) - return &m_sets[i]; - return NULL; - } - - uint32_t - GetRegisterSetIndexByName (lldb_private::ConstString &set_name, bool can_create) - { - name_collection::iterator pos, end = m_set_names.end(); - for (pos = m_set_names.begin(); pos != end; ++pos) - { - if (*pos == set_name) - return std::distance (m_set_names.begin(), pos); - } - - m_set_names.push_back(set_name); - m_set_reg_nums.resize(m_set_reg_nums.size()+1); - lldb_private::RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL }; - m_sets.push_back (new_set); - return m_sets.size() - 1; - } - - uint32_t - ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const - { - reg_collection::const_iterator pos, end = m_regs.end(); - for (pos = m_regs.begin(); pos != end; ++pos) - { - if (pos->kinds[kind] == num) - return std::distance (m_regs.begin(), pos); - } - - return LLDB_INVALID_REGNUM; - } - void - Clear() - { - m_regs.clear(); - m_sets.clear(); - m_set_reg_nums.clear(); - m_reg_names.clear(); - m_reg_alt_names.clear(); - m_set_names.clear(); - } - - void - HardcodeARMRegisters(); - -protected: - //------------------------------------------------------------------ - // Classes that inherit from GDBRemoteRegisterContext can see and modify these - //------------------------------------------------------------------ - typedef std::vector <lldb_private::RegisterInfo> reg_collection; - typedef std::vector <lldb_private::RegisterSet> set_collection; - typedef std::vector <uint32_t> reg_num_collection; - typedef std::vector <reg_num_collection> set_reg_num_collection; - typedef std::vector <lldb_private::ConstString> name_collection; - - reg_collection m_regs; - set_collection m_sets; - set_reg_num_collection m_set_reg_nums; - name_collection m_reg_names; - name_collection m_reg_alt_names; - name_collection m_set_names; - size_t m_reg_data_byte_size; // The number of bytes required to store all registers -}; - -class GDBRemoteRegisterContext : public lldb_private::RegisterContext -{ -public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - GDBRemoteRegisterContext (ThreadGDBRemote &thread, - uint32_t concrete_frame_idx, - GDBRemoteDynamicRegisterInfo ®_info, - bool read_all_at_once); - - virtual - ~GDBRemoteRegisterContext (); - - //------------------------------------------------------------------ - // Subclasses must override these functions - //------------------------------------------------------------------ - virtual void - InvalidateAllRegisters (); - - virtual size_t - GetRegisterCount (); - - virtual const lldb_private::RegisterInfo * - GetRegisterInfoAtIndex (uint32_t reg); - - virtual size_t - GetRegisterSetCount (); - - virtual const lldb_private::RegisterSet * - GetRegisterSet (uint32_t reg_set); - - virtual bool - ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value); - - virtual bool - WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value); - - virtual bool - ReadAllRegisterValues (lldb::DataBufferSP &data_sp); - - virtual bool - WriteAllRegisterValues (const lldb::DataBufferSP &data_sp); - - virtual uint32_t - ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num); - -protected: - friend class ThreadGDBRemote; - - bool - ReadRegisterBytes (const lldb_private::RegisterInfo *reg_info, - lldb_private::DataExtractor &data); - - bool - WriteRegisterBytes (const lldb_private::RegisterInfo *reg_info, - lldb_private::DataExtractor &data, - uint32_t data_offset); - - bool - PrivateSetRegisterValue (uint32_t reg, StringExtractor &response); - - void - SetAllRegisterValid (bool b); - - GDBRemoteDynamicRegisterInfo &m_reg_info; - std::vector<bool> m_reg_valid; - lldb_private::DataExtractor m_reg_data; - bool m_read_all_at_once; - -private: - // Helper function for ReadRegisterBytes(). - bool GetPrimordialRegister(const lldb_private::RegisterInfo *reg_info, - GDBRemoteCommunicationClient &gdb_comm); - // Helper function for WriteRegisterBytes(). - bool SetPrimordialRegister(const lldb_private::RegisterInfo *reg_info, - GDBRemoteCommunicationClient &gdb_comm); - - //------------------------------------------------------------------ - // For GDBRemoteRegisterContext only - //------------------------------------------------------------------ - DISALLOW_COPY_AND_ASSIGN (GDBRemoteRegisterContext); -}; - -#endif // lldb_GDBRemoteRegisterContext_h_ diff --git a/lldb/source/Plugins/Process/gdb-remote/Makefile b/lldb/source/Plugins/Process/gdb-remote/Makefile deleted file mode 100644 index 8a9b61077875..000000000000 --- a/lldb/source/Plugins/Process/gdb-remote/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -##===- source/Plugins/Process/gdb-remote/Makefile -------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLDB_LEVEL := ../../../.. -LIBRARYNAME := lldbPluginProcessGDBRemote -BUILD_ARCHIVE = 1 - -include $(LLDB_LEVEL)/Makefile diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp deleted file mode 100644 index ffb165d279cb..000000000000 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ /dev/null @@ -1,2732 +0,0 @@ -//===-- ProcessGDBRemote.cpp ------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -#include <errno.h> -#include <spawn.h> -#include <stdlib.h> -#include <sys/mman.h> // for mmap -#include <sys/stat.h> -#include <sys/types.h> -#include <time.h> - -// C++ Includes -#include <algorithm> -#include <map> - -// Other libraries and framework includes - -#include "lldb/Breakpoint/Watchpoint.h" -#include "lldb/Interpreter/Args.h" -#include "lldb/Core/ArchSpec.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Core/ConnectionFileDescriptor.h" -#include "lldb/Host/FileSpec.h" -#include "lldb/Core/InputReader.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" -#include "lldb/Core/StreamFile.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Core/Timer.h" -#include "lldb/Core/Value.h" -#include "lldb/Host/TimeValue.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Target/DynamicLoader.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/TargetList.h" -#include "lldb/Target/ThreadPlanCallFunction.h" -#include "lldb/Utility/PseudoTerminal.h" - -// Project includes -#include "lldb/Host/Host.h" -#include "Plugins/Process/Utility/InferiorCallPOSIX.h" -#include "Utility/StringExtractorGDBRemote.h" -#include "GDBRemoteRegisterContext.h" -#include "ProcessGDBRemote.h" -#include "ProcessGDBRemoteLog.h" -#include "ThreadGDBRemote.h" -#include "StopInfoMachException.h" - -namespace lldb -{ - // Provide a function that can easily dump the packet history if we know a - // ProcessGDBRemote * value (which we can get from logs or from debugging). - // We need the function in the lldb namespace so it makes it into the final - // executable since the LLDB shared library only exports stuff in the lldb - // namespace. This allows you to attach with a debugger and call this - // function and get the packet history dumped to a file. - void - DumpProcessGDBRemotePacketHistory (void *p, const char *path) - { - lldb_private::StreamFile strm; - lldb_private::Error error (strm.GetFile().Open(path, lldb_private::File::eOpenOptionWrite | lldb_private::File::eOpenOptionCanCreate)); - if (error.Success()) - ((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory (strm); - } -}; - - -#define DEBUGSERVER_BASENAME "debugserver" -using namespace lldb; -using namespace lldb_private; - -static bool rand_initialized = false; - -static inline uint16_t -get_random_port () -{ - if (!rand_initialized) - { - time_t seed = time(NULL); - - rand_initialized = true; - srand(seed); - } - return (rand() % (UINT16_MAX - 1000u)) + 1000u; -} - - -const char * -ProcessGDBRemote::GetPluginNameStatic() -{ - return "gdb-remote"; -} - -const char * -ProcessGDBRemote::GetPluginDescriptionStatic() -{ - return "GDB Remote protocol based debugging plug-in."; -} - -void -ProcessGDBRemote::Terminate() -{ - PluginManager::UnregisterPlugin (ProcessGDBRemote::CreateInstance); -} - - -lldb::ProcessSP -ProcessGDBRemote::CreateInstance (Target &target, Listener &listener, const FileSpec *crash_file_path) -{ - lldb::ProcessSP process_sp; - if (crash_file_path == NULL) - process_sp.reset (new ProcessGDBRemote (target, listener)); - return process_sp; -} - -bool -ProcessGDBRemote::CanDebug (Target &target, 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.GetExecutableModulePointer(); - if (exe_module) - { - ObjectFile *exe_objfile = exe_module->GetObjectFile(); - // We can't debug core files... - switch (exe_objfile->GetType()) - { - case ObjectFile::eTypeInvalid: - case ObjectFile::eTypeCoreFile: - case ObjectFile::eTypeDebugInfo: - case ObjectFile::eTypeObjectFile: - case ObjectFile::eTypeSharedLibrary: - case ObjectFile::eTypeStubLibrary: - return false; - case ObjectFile::eTypeExecutable: - case ObjectFile::eTypeDynamicLinker: - case ObjectFile::eTypeUnknown: - break; - } - return exe_module->GetFileSpec().Exists(); - } - // However, if there is no executable module, we return true since we might be preparing to attach. - return true; -} - -//---------------------------------------------------------------------- -// ProcessGDBRemote constructor -//---------------------------------------------------------------------- -ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) : - Process (target, listener), - m_flags (0), - m_gdb_comm(false), - m_debugserver_pid (LLDB_INVALID_PROCESS_ID), - m_last_stop_packet (), - m_last_stop_packet_mutex (Mutex::eMutexTypeNormal), - m_register_info (), - m_async_broadcaster (NULL, "lldb.process.gdb-remote.async-broadcaster"), - m_async_thread (LLDB_INVALID_HOST_THREAD), - m_thread_ids (), - m_continue_c_tids (), - m_continue_C_tids (), - m_continue_s_tids (), - m_continue_S_tids (), - m_dispatch_queue_offsets_addr (LLDB_INVALID_ADDRESS), - m_max_memory_size (512), - m_waiting_for_attach (false), - m_thread_observation_bps() -{ - m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit"); - m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue"); - m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadDidExit, "async thread did exit"); -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -ProcessGDBRemote::~ProcessGDBRemote() -{ - // m_mach_process.UnregisterNotificationCallbacks (this); - 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 -//---------------------------------------------------------------------- -const char * -ProcessGDBRemote::GetPluginName() -{ - return "Process debugging plug-in that uses the GDB remote protocol"; -} - -const char * -ProcessGDBRemote::GetShortPluginName() -{ - return GetPluginNameStatic(); -} - -uint32_t -ProcessGDBRemote::GetPluginVersion() -{ - return 1; -} - -void -ProcessGDBRemote::BuildDynamicRegisterInfo (bool force) -{ - if (!force && m_register_info.GetNumRegisters() > 0) - return; - - char packet[128]; - m_register_info.Clear(); - uint32_t reg_offset = 0; - uint32_t reg_num = 0; - StringExtractorGDBRemote::ResponseType response_type; - for (response_type = StringExtractorGDBRemote::eResponse; - response_type == StringExtractorGDBRemote::eResponse; - ++reg_num) - { - const int packet_len = ::snprintf (packet, sizeof(packet), "qRegisterInfo%x", reg_num); - assert (packet_len < sizeof(packet)); - StringExtractorGDBRemote response; - if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false)) - { - response_type = response.GetResponseType(); - if (response_type == StringExtractorGDBRemote::eResponse) - { - std::string name; - std::string value; - ConstString reg_name; - ConstString alt_name; - ConstString set_name; - RegisterInfo reg_info = { NULL, // Name - NULL, // Alt name - 0, // byte size - reg_offset, // offset - eEncodingUint, // encoding - eFormatHex, // formate - { - LLDB_INVALID_REGNUM, // GCC reg num - LLDB_INVALID_REGNUM, // DWARF reg num - LLDB_INVALID_REGNUM, // generic reg num - reg_num, // GDB reg num - reg_num // native register number - }, - NULL, - NULL - }; - - while (response.GetNameColonValue(name, value)) - { - if (name.compare("name") == 0) - { - reg_name.SetCString(value.c_str()); - } - else if (name.compare("alt-name") == 0) - { - alt_name.SetCString(value.c_str()); - } - else if (name.compare("bitsize") == 0) - { - reg_info.byte_size = Args::StringToUInt32(value.c_str(), 0, 0) / CHAR_BIT; - } - else if (name.compare("offset") == 0) - { - uint32_t offset = Args::StringToUInt32(value.c_str(), UINT32_MAX, 0); - if (reg_offset != offset) - { - reg_offset = offset; - } - } - else if (name.compare("encoding") == 0) - { - if (value.compare("uint") == 0) - reg_info.encoding = eEncodingUint; - else if (value.compare("sint") == 0) - reg_info.encoding = eEncodingSint; - else if (value.compare("ieee754") == 0) - reg_info.encoding = eEncodingIEEE754; - else if (value.compare("vector") == 0) - reg_info.encoding = eEncodingVector; - } - else if (name.compare("format") == 0) - { - if (value.compare("binary") == 0) - reg_info.format = eFormatBinary; - else if (value.compare("decimal") == 0) - reg_info.format = eFormatDecimal; - else if (value.compare("hex") == 0) - reg_info.format = eFormatHex; - else if (value.compare("float") == 0) - reg_info.format = eFormatFloat; - else if (value.compare("vector-sint8") == 0) - reg_info.format = eFormatVectorOfSInt8; - else if (value.compare("vector-uint8") == 0) - reg_info.format = eFormatVectorOfUInt8; - else if (value.compare("vector-sint16") == 0) - reg_info.format = eFormatVectorOfSInt16; - else if (value.compare("vector-uint16") == 0) - reg_info.format = eFormatVectorOfUInt16; - else if (value.compare("vector-sint32") == 0) - reg_info.format = eFormatVectorOfSInt32; - else if (value.compare("vector-uint32") == 0) - reg_info.format = eFormatVectorOfUInt32; - else if (value.compare("vector-float32") == 0) - reg_info.format = eFormatVectorOfFloat32; - else if (value.compare("vector-uint128") == 0) - reg_info.format = eFormatVectorOfUInt128; - } - else if (name.compare("set") == 0) - { - set_name.SetCString(value.c_str()); - } - else if (name.compare("gcc") == 0) - { - reg_info.kinds[eRegisterKindGCC] = Args::StringToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0); - } - else if (name.compare("dwarf") == 0) - { - reg_info.kinds[eRegisterKindDWARF] = Args::StringToUInt32(value.c_str(), LLDB_INVALID_REGNUM, 0); - } - else if (name.compare("generic") == 0) - { - if (value.compare("pc") == 0) - reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; - else if (value.compare("sp") == 0) - reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; - else if (value.compare("fp") == 0) - reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; - else if (value.compare("ra") == 0) - reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; - else if (value.compare("flags") == 0) - reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; - else if (value.find("arg") == 0) - { - if (value.size() == 4) - { - switch (value[3]) - { - case '1': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG1; break; - case '2': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG2; break; - case '3': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG3; break; - case '4': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG4; break; - case '5': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG5; break; - case '6': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG6; break; - case '7': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG7; break; - case '8': reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG8; break; - } - } - } - } - } - - reg_info.byte_offset = reg_offset; - assert (reg_info.byte_size != 0); - reg_offset += reg_info.byte_size; - m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name); - } - } - else - { - response_type = StringExtractorGDBRemote::eError; - break; - } - } - - if (reg_num == 0) - { - // We didn't get anything. See if we are debugging ARM and fill with - // a hard coded register set until we can get an updated debugserver - // down on the devices. - - if (!GetTarget().GetArchitecture().IsValid() - && m_gdb_comm.GetHostArchitecture().IsValid() - && m_gdb_comm.GetHostArchitecture().GetMachine() == llvm::Triple::arm - && m_gdb_comm.GetHostArchitecture().GetTriple().getVendor() == llvm::Triple::Apple) - { - m_register_info.HardcodeARMRegisters(); - } - else if (GetTarget().GetArchitecture().GetMachine() == llvm::Triple::arm) - { - m_register_info.HardcodeARMRegisters(); - } - } - m_register_info.Finalize (); -} - -Error -ProcessGDBRemote::WillLaunch (Module* module) -{ - return WillLaunchOrAttach (); -} - -Error -ProcessGDBRemote::WillAttachToProcessWithID (lldb::pid_t pid) -{ - return WillLaunchOrAttach (); -} - -Error -ProcessGDBRemote::WillAttachToProcessWithName (const char *process_name, bool wait_for_launch) -{ - return WillLaunchOrAttach (); -} - -Error -ProcessGDBRemote::DoConnectRemote (const char *remote_url) -{ - Error error (WillLaunchOrAttach ()); - - if (error.Fail()) - return error; - - error = ConnectToDebugserver (remote_url); - - if (error.Fail()) - return error; - StartAsyncThread (); - - lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID (); - if (pid == LLDB_INVALID_PROCESS_ID) - { - // We don't have a valid process ID, so note that we are connected - // and could now request to launch or attach, or get remote process - // listings... - SetPrivateState (eStateConnected); - } - else - { - // We have a valid process - SetID (pid); - GetThreadList(); - if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, m_last_stop_packet, false)) - { - const StateType state = SetThreadStopInfo (m_last_stop_packet); - if (state == eStateStopped) - { - SetPrivateState (state); - } - else - error.SetErrorStringWithFormat ("Process %llu was reported after connecting to '%s', but state was not stopped: %s", pid, remote_url, StateAsCString (state)); - } - else - error.SetErrorStringWithFormat ("Process %llu was reported after connecting to '%s', but no stop reply packet was received", pid, remote_url); - } - return error; -} - -Error -ProcessGDBRemote::WillLaunchOrAttach () -{ - Error error; - m_stdio_communication.Clear (); - return error; -} - -//---------------------------------------------------------------------- -// Process Control -//---------------------------------------------------------------------- -Error -ProcessGDBRemote::DoLaunch (Module *exe_module, const ProcessLaunchInfo &launch_info) -{ - Error error; - - uint32_t launch_flags = launch_info.GetFlags().Get(); - const char *stdin_path = NULL; - const char *stdout_path = NULL; - const char *stderr_path = NULL; - const char *working_dir = launch_info.GetWorkingDirectory(); - - const ProcessLaunchInfo::FileAction *file_action; - file_action = launch_info.GetFileActionForFD (STDIN_FILENO); - if (file_action) - { - if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen) - stdin_path = file_action->GetPath(); - } - file_action = launch_info.GetFileActionForFD (STDOUT_FILENO); - if (file_action) - { - if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen) - stdout_path = file_action->GetPath(); - } - file_action = launch_info.GetFileActionForFD (STDERR_FILENO); - if (file_action) - { - if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen) - stderr_path = file_action->GetPath(); - } - - // ::LogSetBitMask (GDBR_LOG_DEFAULT); - // ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE | LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD); - // ::LogSetLogFile ("/dev/stdout"); - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); - - ObjectFile * object_file = exe_module->GetObjectFile(); - if (object_file) - { - char host_port[128]; - snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ()); - char connect_url[128]; - snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port); - - // Make sure we aren't already connected? - if (!m_gdb_comm.IsConnected()) - { - error = StartDebugserverProcess (host_port, launch_info); - if (error.Fail()) - { - if (log) - log->Printf("failed to start debugserver process: %s", error.AsCString()); - return error; - } - - error = ConnectToDebugserver (connect_url); - } - - if (error.Success()) - { - lldb_utility::PseudoTerminal pty; - const bool disable_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0; - - // If the debugserver is local and we aren't disabling STDIO, lets use - // a pseudo terminal to instead of relying on the 'O' packets for stdio - // since 'O' packets can really slow down debugging if the inferior - // does a lot of output. - PlatformSP platform_sp (m_target.GetPlatform()); - if (platform_sp && platform_sp->IsHost() && !disable_stdio) - { - const char *slave_name = NULL; - if (stdin_path == NULL || stdout_path == NULL || stderr_path == NULL) - { - if (pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, NULL, 0)) - slave_name = pty.GetSlaveName (NULL, 0); - } - if (stdin_path == NULL) - stdin_path = slave_name; - - if (stdout_path == NULL) - stdout_path = slave_name; - - if (stderr_path == NULL) - stderr_path = slave_name; - } - - // Set STDIN to /dev/null if we want STDIO disabled or if either - // STDOUT or STDERR have been set to something and STDIN hasn't - if (disable_stdio || (stdin_path == NULL && (stdout_path || stderr_path))) - stdin_path = "/dev/null"; - - // Set STDOUT to /dev/null if we want STDIO disabled or if either - // STDIN or STDERR have been set to something and STDOUT hasn't - if (disable_stdio || (stdout_path == NULL && (stdin_path || stderr_path))) - stdout_path = "/dev/null"; - - // Set STDERR to /dev/null if we want STDIO disabled or if either - // STDIN or STDOUT have been set to something and STDERR hasn't - if (disable_stdio || (stderr_path == NULL && (stdin_path || stdout_path))) - stderr_path = "/dev/null"; - - if (stdin_path) - m_gdb_comm.SetSTDIN (stdin_path); - if (stdout_path) - m_gdb_comm.SetSTDOUT (stdout_path); - if (stderr_path) - m_gdb_comm.SetSTDERR (stderr_path); - - m_gdb_comm.SetDisableASLR (launch_flags & eLaunchFlagDisableASLR); - - m_gdb_comm.SendLaunchArchPacket (m_target.GetArchitecture().GetArchitectureName()); - - if (working_dir && working_dir[0]) - { - m_gdb_comm.SetWorkingDir (working_dir); - } - - // Send the environment and the program + arguments after we connect - const Args &environment = launch_info.GetEnvironmentEntries(); - if (environment.GetArgumentCount()) - { - size_t num_environment_entries = environment.GetArgumentCount(); - for (size_t i=0; i<num_environment_entries; ++i) - { - const char *env_entry = environment.GetArgumentAtIndex(i); - if (env_entry == NULL || m_gdb_comm.SendEnvironmentPacket(env_entry) != 0) - break; - } - } - - const uint32_t old_packet_timeout = m_gdb_comm.SetPacketTimeout (10); - int arg_packet_err = m_gdb_comm.SendArgumentsPacket (launch_info.GetArguments().GetConstArgumentVector()); - if (arg_packet_err == 0) - { - std::string error_str; - if (m_gdb_comm.GetLaunchSuccess (error_str)) - { - SetID (m_gdb_comm.GetCurrentProcessID ()); - } - else - { - error.SetErrorString (error_str.c_str()); - } - } - else - { - error.SetErrorStringWithFormat("'A' packet returned an error: %i", arg_packet_err); - } - - m_gdb_comm.SetPacketTimeout (old_packet_timeout); - - if (GetID() == LLDB_INVALID_PROCESS_ID) - { - if (log) - log->Printf("failed to connect to debugserver: %s", error.AsCString()); - KillDebugserverProcess (); - return error; - } - - if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, m_last_stop_packet, false)) - { - SetPrivateState (SetThreadStopInfo (m_last_stop_packet)); - - if (!disable_stdio) - { - if (pty.GetMasterFileDescriptor() != lldb_utility::PseudoTerminal::invalid_fd) - SetSTDIOFileDescriptor (pty.ReleaseMasterFileDescriptor()); - } - } - } - else - { - if (log) - log->Printf("failed to connect to debugserver: %s", error.AsCString()); - } - } - else - { - // Set our user ID to an invalid process ID. - SetID(LLDB_INVALID_PROCESS_ID); - error.SetErrorStringWithFormat ("failed to get object file from '%s' for arch %s", - exe_module->GetFileSpec().GetFilename().AsCString(), - exe_module->GetArchitecture().GetArchitectureName()); - } - return error; - -} - - -Error -ProcessGDBRemote::ConnectToDebugserver (const char *connect_url) -{ - Error error; - // Sleep and wait a bit for debugserver to start to listen... - std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor()); - if (conn_ap.get()) - { - const uint32_t max_retry_count = 50; - uint32_t retry_count = 0; - while (!m_gdb_comm.IsConnected()) - { - if (conn_ap->Connect(connect_url, &error) == eConnectionStatusSuccess) - { - m_gdb_comm.SetConnection (conn_ap.release()); - break; - } - retry_count++; - - if (retry_count >= max_retry_count) - break; - - usleep (100000); - } - } - - if (!m_gdb_comm.IsConnected()) - { - if (error.Success()) - error.SetErrorString("not connected to remote gdb server"); - return error; - } - - // We always seem to be able to open a connection to a local port - // so we need to make sure we can then send data to it. If we can't - // then we aren't actually connected to anything, so try and do the - // handshake with the remote GDB server and make sure that goes - // alright. - if (!m_gdb_comm.HandshakeWithServer (NULL)) - { - m_gdb_comm.Disconnect(); - if (error.Success()) - error.SetErrorString("not connected to remote gdb server"); - return error; - } - m_gdb_comm.ResetDiscoverableSettings(); - m_gdb_comm.QueryNoAckModeSupported (); - m_gdb_comm.GetThreadSuffixSupported (); - m_gdb_comm.GetListThreadsInStopReplySupported (); - m_gdb_comm.GetHostInfo (); - m_gdb_comm.GetVContSupported ('c'); - return error; -} - -void -ProcessGDBRemote::DidLaunchOrAttach () -{ - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); - if (log) - log->Printf ("ProcessGDBRemote::DidLaunch()"); - if (GetID() != LLDB_INVALID_PROCESS_ID) - { - m_dispatch_queue_offsets_addr = LLDB_INVALID_ADDRESS; - - BuildDynamicRegisterInfo (false); - - // See if the GDB server supports the qHostInfo information - - const ArchSpec &gdb_remote_arch = m_gdb_comm.GetHostArchitecture(); - if (gdb_remote_arch.IsValid()) - { - ArchSpec &target_arch = GetTarget().GetArchitecture(); - - if (target_arch.IsValid()) - { - // If the remote host is ARM and we have apple as the vendor, then - // ARM executables and shared libraries can have mixed ARM architectures. - // You can have an armv6 executable, and if the host is armv7, then the - // system will load the best possible architecture for all shared libraries - // it has, so we really need to take the remote host architecture as our - // defacto architecture in this case. - - if (gdb_remote_arch.GetMachine() == llvm::Triple::arm && - gdb_remote_arch.GetTriple().getVendor() == llvm::Triple::Apple) - { - target_arch = gdb_remote_arch; - } - else - { - // Fill in what is missing in the triple - const llvm::Triple &remote_triple = gdb_remote_arch.GetTriple(); - llvm::Triple &target_triple = target_arch.GetTriple(); - if (target_triple.getVendorName().size() == 0) - { - target_triple.setVendor (remote_triple.getVendor()); - - if (target_triple.getOSName().size() == 0) - { - target_triple.setOS (remote_triple.getOS()); - - if (target_triple.getEnvironmentName().size() == 0) - target_triple.setEnvironment (remote_triple.getEnvironment()); - } - } - } - } - else - { - // The target doesn't have a valid architecture yet, set it from - // the architecture we got from the remote GDB server - target_arch = gdb_remote_arch; - } - } - } -} - -void -ProcessGDBRemote::DidLaunch () -{ - DidLaunchOrAttach (); -} - -Error -ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid) -{ - ProcessAttachInfo attach_info; - return DoAttachToProcessWithID(attach_pid, attach_info); -} - -Error -ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid, const ProcessAttachInfo &attach_info) -{ - Error error; - // Clear out and clean up from any current state - Clear(); - if (attach_pid != LLDB_INVALID_PROCESS_ID) - { - // Make sure we aren't already connected? - if (!m_gdb_comm.IsConnected()) - { - char host_port[128]; - snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ()); - char connect_url[128]; - snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port); - - error = StartDebugserverProcess (host_port, attach_info); - - if (error.Fail()) - { - const char *error_string = error.AsCString(); - if (error_string == NULL) - error_string = "unable to launch " DEBUGSERVER_BASENAME; - - SetExitStatus (-1, error_string); - } - else - { - error = ConnectToDebugserver (connect_url); - } - } - - if (error.Success()) - { - char packet[64]; - const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%llx", attach_pid); - SetID (attach_pid); - m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (packet, packet_len)); - } - } - return error; -} - -size_t -ProcessGDBRemote::AttachInputReaderCallback -( - void *baton, - InputReader *reader, - lldb::InputReaderAction notification, - const char *bytes, - size_t bytes_len -) -{ - if (notification == eInputReaderGotToken) - { - ProcessGDBRemote *gdb_process = (ProcessGDBRemote *)baton; - if (gdb_process->m_waiting_for_attach) - gdb_process->m_waiting_for_attach = false; - reader->SetIsDone(true); - return 1; - } - return 0; -} - -Error -ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, bool wait_for_launch, const ProcessAttachInfo &attach_info) -{ - Error error; - // Clear out and clean up from any current state - Clear(); - - if (process_name && process_name[0]) - { - // Make sure we aren't already connected? - if (!m_gdb_comm.IsConnected()) - { - char host_port[128]; - snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ()); - char connect_url[128]; - snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port); - - error = StartDebugserverProcess (host_port, attach_info); - if (error.Fail()) - { - const char *error_string = error.AsCString(); - if (error_string == NULL) - error_string = "unable to launch " DEBUGSERVER_BASENAME; - - SetExitStatus (-1, error_string); - } - else - { - error = ConnectToDebugserver (connect_url); - } - } - - if (error.Success()) - { - StreamString packet; - - if (wait_for_launch) - packet.PutCString("vAttachWait"); - else - packet.PutCString("vAttachName"); - packet.PutChar(';'); - packet.PutBytesAsRawHex8(process_name, strlen(process_name), lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder()); - - m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (packet.GetData(), packet.GetSize())); - - } - } - return error; -} - - -void -ProcessGDBRemote::DidAttach () -{ - DidLaunchOrAttach (); -} - -Error -ProcessGDBRemote::WillResume () -{ - m_continue_c_tids.clear(); - m_continue_C_tids.clear(); - m_continue_s_tids.clear(); - m_continue_S_tids.clear(); - return Error(); -} - -Error -ProcessGDBRemote::DoResume () -{ - Error error; - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); - if (log) - log->Printf ("ProcessGDBRemote::Resume()"); - - Listener listener ("gdb-remote.resume-packet-sent"); - if (listener.StartListeningForEvents (&m_gdb_comm, GDBRemoteCommunication::eBroadcastBitRunPacketSent)) - { - listener.StartListeningForEvents (&m_async_broadcaster, ProcessGDBRemote::eBroadcastBitAsyncThreadDidExit); - - StreamString continue_packet; - bool continue_packet_error = false; - if (m_gdb_comm.HasAnyVContSupport ()) - { - continue_packet.PutCString ("vCont"); - - if (!m_continue_c_tids.empty()) - { - if (m_gdb_comm.GetVContSupported ('c')) - { - for (tid_collection::const_iterator t_pos = m_continue_c_tids.begin(), t_end = m_continue_c_tids.end(); t_pos != t_end; ++t_pos) - continue_packet.Printf(";c:%4.4llx", *t_pos); - } - else - continue_packet_error = true; - } - - if (!continue_packet_error && !m_continue_C_tids.empty()) - { - if (m_gdb_comm.GetVContSupported ('C')) - { - for (tid_sig_collection::const_iterator s_pos = m_continue_C_tids.begin(), s_end = m_continue_C_tids.end(); s_pos != s_end; ++s_pos) - continue_packet.Printf(";C%2.2x:%4.4llx", s_pos->second, s_pos->first); - } - else - continue_packet_error = true; - } - - if (!continue_packet_error && !m_continue_s_tids.empty()) - { - if (m_gdb_comm.GetVContSupported ('s')) - { - for (tid_collection::const_iterator t_pos = m_continue_s_tids.begin(), t_end = m_continue_s_tids.end(); t_pos != t_end; ++t_pos) - continue_packet.Printf(";s:%4.4llx", *t_pos); - } - else - continue_packet_error = true; - } - - if (!continue_packet_error && !m_continue_S_tids.empty()) - { - if (m_gdb_comm.GetVContSupported ('S')) - { - for (tid_sig_collection::const_iterator s_pos = m_continue_S_tids.begin(), s_end = m_continue_S_tids.end(); s_pos != s_end; ++s_pos) - continue_packet.Printf(";S%2.2x:%4.4llx", s_pos->second, s_pos->first); - } - else - continue_packet_error = true; - } - - if (continue_packet_error) - continue_packet.GetString().clear(); - } - else - continue_packet_error = true; - - if (continue_packet_error) - { - // Either no vCont support, or we tried to use part of the vCont - // packet that wasn't supported by the remote GDB server. - // We need to try and make a simple packet that can do our continue - const size_t num_threads = GetThreadList().GetSize(); - const size_t num_continue_c_tids = m_continue_c_tids.size(); - const size_t num_continue_C_tids = m_continue_C_tids.size(); - const size_t num_continue_s_tids = m_continue_s_tids.size(); - const size_t num_continue_S_tids = m_continue_S_tids.size(); - if (num_continue_c_tids > 0) - { - if (num_continue_c_tids == num_threads) - { - // All threads are resuming... - m_gdb_comm.SetCurrentThreadForRun (-1); - continue_packet.PutChar ('c'); - continue_packet_error = false; - } - else if (num_continue_c_tids == 1 && - num_continue_C_tids == 0 && - num_continue_s_tids == 0 && - num_continue_S_tids == 0 ) - { - // Only one thread is continuing - m_gdb_comm.SetCurrentThreadForRun (m_continue_c_tids.front()); - continue_packet.PutChar ('c'); - continue_packet_error = false; - } - } - - if (continue_packet_error && num_continue_C_tids > 0) - { - if ((num_continue_C_tids + num_continue_c_tids) == num_threads && - num_continue_C_tids > 0 && - num_continue_s_tids == 0 && - num_continue_S_tids == 0 ) - { - const int continue_signo = m_continue_C_tids.front().second; - // Only one thread is continuing - if (num_continue_C_tids > 1) - { - // More that one thread with a signal, yet we don't have - // vCont support and we are being asked to resume each - // thread with a signal, we need to make sure they are - // all the same signal, or we can't issue the continue - // accurately with the current support... - if (num_continue_C_tids > 1) - { - continue_packet_error = false; - for (size_t i=1; i<m_continue_C_tids.size(); ++i) - { - if (m_continue_C_tids[i].second != continue_signo) - continue_packet_error = true; - } - } - if (!continue_packet_error) - m_gdb_comm.SetCurrentThreadForRun (-1); - } - else - { - // Set the continue thread ID - continue_packet_error = false; - m_gdb_comm.SetCurrentThreadForRun (m_continue_C_tids.front().first); - } - if (!continue_packet_error) - { - // Add threads continuing with the same signo... - continue_packet.Printf("C%2.2x", continue_signo); - } - } - } - - if (continue_packet_error && num_continue_s_tids > 0) - { - if (num_continue_s_tids == num_threads) - { - // All threads are resuming... - m_gdb_comm.SetCurrentThreadForRun (-1); - continue_packet.PutChar ('s'); - continue_packet_error = false; - } - else if (num_continue_c_tids == 0 && - num_continue_C_tids == 0 && - num_continue_s_tids == 1 && - num_continue_S_tids == 0 ) - { - // Only one thread is stepping - m_gdb_comm.SetCurrentThreadForRun (m_continue_s_tids.front()); - continue_packet.PutChar ('s'); - continue_packet_error = false; - } - } - - if (!continue_packet_error && num_continue_S_tids > 0) - { - if (num_continue_S_tids == num_threads) - { - const int step_signo = m_continue_S_tids.front().second; - // Are all threads trying to step with the same signal? - continue_packet_error = false; - if (num_continue_S_tids > 1) - { - for (size_t i=1; i<num_threads; ++i) - { - if (m_continue_S_tids[i].second != step_signo) - continue_packet_error = true; - } - } - if (!continue_packet_error) - { - // Add threads stepping with the same signo... - m_gdb_comm.SetCurrentThreadForRun (-1); - continue_packet.Printf("S%2.2x", step_signo); - } - } - else if (num_continue_c_tids == 0 && - num_continue_C_tids == 0 && - num_continue_s_tids == 0 && - num_continue_S_tids == 1 ) - { - // Only one thread is stepping with signal - m_gdb_comm.SetCurrentThreadForRun (m_continue_S_tids.front().first); - continue_packet.Printf("S%2.2x", m_continue_S_tids.front().second); - continue_packet_error = false; - } - } - } - - if (continue_packet_error) - { - error.SetErrorString ("can't make continue packet for this resume"); - } - else - { - EventSP event_sp; - TimeValue timeout; - timeout = TimeValue::Now(); - timeout.OffsetWithSeconds (5); - if (!IS_VALID_LLDB_HOST_THREAD(m_async_thread)) - { - error.SetErrorString ("Trying to resume but the async thread is dead."); - if (log) - log->Printf ("ProcessGDBRemote::DoResume: Trying to resume but the async thread is dead."); - return error; - } - - m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (continue_packet.GetData(), continue_packet.GetSize())); - - if (listener.WaitForEvent (&timeout, event_sp) == false) - { - error.SetErrorString("Resume timed out."); - if (log) - log->Printf ("ProcessGDBRemote::DoResume: Resume timed out."); - } - else if (event_sp->BroadcasterIs (&m_async_broadcaster)) - { - error.SetErrorString ("Broadcast continue, but the async thread was killed before we got an ack back."); - if (log) - log->Printf ("ProcessGDBRemote::DoResume: Broadcast continue, but the async thread was killed before we got an ack back."); - return error; - } - } - } - - return error; -} - -void -ProcessGDBRemote::ClearThreadIDList () -{ - Mutex::Locker locker(m_thread_list.GetMutex()); - m_thread_ids.clear(); -} - -bool -ProcessGDBRemote::UpdateThreadIDList () -{ - Mutex::Locker locker(m_thread_list.GetMutex()); - bool sequence_mutex_unavailable = false; - m_gdb_comm.GetCurrentThreadIDs (m_thread_ids, sequence_mutex_unavailable); - if (sequence_mutex_unavailable) - { -#if defined (LLDB_CONFIGURATION_DEBUG) - assert(!"ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex"); -#endif - return false; // We just didn't get the list - } - return true; -} - -bool -ProcessGDBRemote::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list) -{ - // locker will keep a mutex locked until it goes out of scope - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_THREAD)); - if (log && log->GetMask().Test(GDBR_LOG_VERBOSE)) - log->Printf ("ProcessGDBRemote::%s (pid = %llu)", __FUNCTION__, GetID()); - - size_t num_thread_ids = m_thread_ids.size(); - // The "m_thread_ids" thread ID list should always be updated after each stop - // reply packet, but in case it isn't, update it here. - if (num_thread_ids == 0) - { - if (!UpdateThreadIDList ()) - return false; - num_thread_ids = m_thread_ids.size(); - } - - if (num_thread_ids > 0) - { - for (size_t i=0; i<num_thread_ids; ++i) - { - tid_t tid = m_thread_ids[i]; - ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false)); - if (!thread_sp) - thread_sp.reset (new ThreadGDBRemote (shared_from_this(), tid)); - new_thread_list.AddThread(thread_sp); - } - } - - return true; -} - - -StateType -ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet) -{ - stop_packet.SetFilePos (0); - const char stop_type = stop_packet.GetChar(); - switch (stop_type) - { - case 'T': - case 'S': - { - if (GetStopID() == 0) - { - // Our first stop, make sure we have a process ID, and also make - // sure we know about our registers - if (GetID() == LLDB_INVALID_PROCESS_ID) - { - lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID (); - if (pid != LLDB_INVALID_PROCESS_ID) - SetID (pid); - } - BuildDynamicRegisterInfo (true); - } - // Stop with signal and thread info - const uint8_t signo = stop_packet.GetHexU8(); - std::string name; - std::string value; - std::string thread_name; - std::string reason; - std::string description; - uint32_t exc_type = 0; - std::vector<addr_t> exc_data; - addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS; - uint32_t exc_data_count = 0; - ThreadSP thread_sp; - - while (stop_packet.GetNameColonValue(name, value)) - { - if (name.compare("metype") == 0) - { - // exception type in big endian hex - exc_type = Args::StringToUInt32 (value.c_str(), 0, 16); - } - else if (name.compare("mecount") == 0) - { - // exception count in big endian hex - exc_data_count = Args::StringToUInt32 (value.c_str(), 0, 16); - } - else if (name.compare("medata") == 0) - { - // exception data in big endian hex - exc_data.push_back(Args::StringToUInt64 (value.c_str(), 0, 16)); - } - else if (name.compare("thread") == 0) - { - // thread in big endian hex - lldb::tid_t tid = Args::StringToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16); - // m_thread_list does have its own mutex, but we need to - // hold onto the mutex between the call to m_thread_list.FindThreadByID(...) - // and the m_thread_list.AddThread(...) so it doesn't change on us - Mutex::Locker locker (m_thread_list.GetMutex ()); - thread_sp = m_thread_list.FindThreadByID(tid, false); - if (!thread_sp) - { - // Create the thread if we need to - thread_sp.reset (new ThreadGDBRemote (shared_from_this(), tid)); - m_thread_list.AddThread(thread_sp); - } - } - else if (name.compare("threads") == 0) - { - Mutex::Locker locker(m_thread_list.GetMutex()); - m_thread_ids.clear(); - // A comma separated list of all threads in the current - // process that includes the thread for this stop reply - // packet - size_t comma_pos; - lldb::tid_t tid; - while ((comma_pos = value.find(',')) != std::string::npos) - { - value[comma_pos] = '\0'; - // thread in big endian hex - tid = Args::StringToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16); - if (tid != LLDB_INVALID_THREAD_ID) - m_thread_ids.push_back (tid); - value.erase(0, comma_pos + 1); - - } - tid = Args::StringToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16); - if (tid != LLDB_INVALID_THREAD_ID) - m_thread_ids.push_back (tid); - } - else if (name.compare("hexname") == 0) - { - StringExtractor name_extractor; - // Swap "value" over into "name_extractor" - name_extractor.GetStringRef().swap(value); - // Now convert the HEX bytes into a string value - name_extractor.GetHexByteString (value); - thread_name.swap (value); - } - else if (name.compare("name") == 0) - { - thread_name.swap (value); - } - else if (name.compare("qaddr") == 0) - { - thread_dispatch_qaddr = Args::StringToUInt64 (value.c_str(), 0, 16); - } - else if (name.compare("reason") == 0) - { - reason.swap(value); - } - else if (name.compare("description") == 0) - { - StringExtractor desc_extractor; - // Swap "value" over into "name_extractor" - desc_extractor.GetStringRef().swap(value); - // Now convert the HEX bytes into a string value - desc_extractor.GetHexByteString (thread_name); - } - else if (name.size() == 2 && ::isxdigit(name[0]) && ::isxdigit(name[1])) - { - // We have a register number that contains an expedited - // register value. Lets supply this register to our thread - // so it won't have to go and read it. - if (thread_sp) - { - uint32_t reg = Args::StringToUInt32 (name.c_str(), UINT32_MAX, 16); - - if (reg != UINT32_MAX) - { - StringExtractor reg_value_extractor; - // Swap "value" over into "reg_value_extractor" - reg_value_extractor.GetStringRef().swap(value); - if (!static_cast<ThreadGDBRemote *> (thread_sp.get())->PrivateSetRegisterValue (reg, reg_value_extractor)) - { - Host::SetCrashDescriptionWithFormat("Setting thread register '%s' (decoded to %u (0x%x)) with value '%s' for stop packet: '%s'", - name.c_str(), - reg, - reg, - reg_value_extractor.GetStringRef().c_str(), - stop_packet.GetStringRef().c_str()); - } - } - } - } - } - - if (thread_sp) - { - ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get()); - - gdb_thread->SetThreadDispatchQAddr (thread_dispatch_qaddr); - gdb_thread->SetName (thread_name.empty() ? NULL : thread_name.c_str()); - if (exc_type != 0) - { - const size_t exc_data_size = exc_data.size(); - - gdb_thread->SetStopInfo (StopInfoMachException::CreateStopReasonWithMachException (*thread_sp, - exc_type, - exc_data_size, - exc_data_size >= 1 ? exc_data[0] : 0, - exc_data_size >= 2 ? exc_data[1] : 0, - exc_data_size >= 3 ? exc_data[2] : 0)); - } - else - { - bool handled = false; - if (!reason.empty()) - { - if (reason.compare("trace") == 0) - { - gdb_thread->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp)); - handled = true; - } - else if (reason.compare("breakpoint") == 0) - { - addr_t pc = gdb_thread->GetRegisterContext()->GetPC(); - lldb::BreakpointSiteSP bp_site_sp = gdb_thread->GetProcess()->GetBreakpointSiteList().FindByAddress(pc); - if (bp_site_sp) - { - // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread, - // we can just report no reason. We don't need to worry about stepping over the breakpoint here, that - // will be taken care of when the thread resumes and notices that there's a breakpoint under the pc. - if (bp_site_sp->ValidForThisThread (gdb_thread)) - { - gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID())); - handled = true; - } - } - - if (!handled) - { - gdb_thread->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp)); - } - } - else if (reason.compare("trap") == 0) - { - // Let the trap just use the standard signal stop reason below... - } - else if (reason.compare("watchpoint") == 0) - { - break_id_t watch_id = LLDB_INVALID_WATCH_ID; - // TODO: locate the watchpoint somehow... - gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID (*thread_sp, watch_id)); - handled = true; - } - else if (reason.compare("exception") == 0) - { - gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithException(*thread_sp, description.c_str())); - handled = true; - } - } - - if (signo) - { - if (signo == SIGTRAP) - { - // Currently we are going to assume SIGTRAP means we are either - // hitting a breakpoint or hardware single stepping. - addr_t pc = gdb_thread->GetRegisterContext()->GetPC(); - lldb::BreakpointSiteSP bp_site_sp = gdb_thread->GetProcess()->GetBreakpointSiteList().FindByAddress(pc); - if (bp_site_sp) - { - // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread, - // we can just report no reason. We don't need to worry about stepping over the breakpoint here, that - // will be taken care of when the thread resumes and notices that there's a breakpoint under the pc. - if (bp_site_sp->ValidForThisThread (gdb_thread)) - { - gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID())); - handled = true; - } - } - if (!handled) - { - // TODO: check for breakpoint or trap opcode in case there is a hard - // coded software trap - gdb_thread->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp)); - handled = true; - } - } - if (!handled) - gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithSignal (*thread_sp, signo)); - } - else - { - StopInfoSP invalid_stop_info_sp; - gdb_thread->SetStopInfo (invalid_stop_info_sp); - } - - if (!description.empty()) - { - lldb::StopInfoSP stop_info_sp (gdb_thread->GetStopInfo ()); - if (stop_info_sp) - { - stop_info_sp->SetDescription (description.c_str()); - } - else - { - gdb_thread->SetStopInfo (StopInfo::CreateStopReasonWithException (*thread_sp, description.c_str())); - } - } - } - } - return eStateStopped; - } - break; - - case 'W': - // process exited - return eStateExited; - - default: - break; - } - return eStateInvalid; -} - -void -ProcessGDBRemote::RefreshStateAfterStop () -{ - Mutex::Locker locker(m_thread_list.GetMutex()); - m_thread_ids.clear(); - // Set the thread stop info. It might have a "threads" key whose value is - // a list of all thread IDs in the current process, so m_thread_ids might - // get set. - SetThreadStopInfo (m_last_stop_packet); - // Check to see if SetThreadStopInfo() filled in m_thread_ids? - if (m_thread_ids.empty()) - { - // No, we need to fetch the thread list manually - UpdateThreadIDList(); - } - - // Let all threads recover from stopping and do any clean up based - // on the previous thread state (if any). - m_thread_list.RefreshStateAfterStop(); - -} - -Error -ProcessGDBRemote::DoHalt (bool &caused_stop) -{ - Error error; - - bool timed_out = false; - Mutex::Locker locker; - - if (m_public_state.GetValue() == eStateAttaching) - { - // We are being asked to halt during an attach. We need to just close - // our file handle and debugserver will go away, and we can be done... - m_gdb_comm.Disconnect(); - } - else - { - if (!m_gdb_comm.SendInterrupt (locker, 2, timed_out)) - { - if (timed_out) - error.SetErrorString("timed out sending interrupt packet"); - else - error.SetErrorString("unknown error sending interrupt packet"); - } - - caused_stop = m_gdb_comm.GetInterruptWasSent (); - } - return error; -} - -Error -ProcessGDBRemote::InterruptIfRunning -( - bool discard_thread_plans, - bool catch_stop_event, - EventSP &stop_event_sp -) -{ - Error error; - - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - - bool paused_private_state_thread = false; - const bool is_running = m_gdb_comm.IsRunning(); - if (log) - log->Printf ("ProcessGDBRemote::InterruptIfRunning(discard_thread_plans=%i, catch_stop_event=%i) is_running=%i", - discard_thread_plans, - catch_stop_event, - is_running); - - if (discard_thread_plans) - { - if (log) - log->Printf ("ProcessGDBRemote::InterruptIfRunning() discarding all thread plans"); - m_thread_list.DiscardThreadPlans(); - } - if (is_running) - { - if (catch_stop_event) - { - if (log) - log->Printf ("ProcessGDBRemote::InterruptIfRunning() pausing private state thread"); - PausePrivateStateThread(); - paused_private_state_thread = true; - } - - bool timed_out = false; - Mutex::Locker locker; - - if (!m_gdb_comm.SendInterrupt (locker, 1, timed_out)) - { - if (timed_out) - error.SetErrorString("timed out sending interrupt packet"); - else - error.SetErrorString("unknown error sending interrupt packet"); - if (paused_private_state_thread) - ResumePrivateStateThread(); - return error; - } - - if (catch_stop_event) - { - // LISTEN HERE - TimeValue timeout_time; - timeout_time = TimeValue::Now(); - timeout_time.OffsetWithSeconds(5); - StateType state = WaitForStateChangedEventsPrivate (&timeout_time, stop_event_sp); - - timed_out = state == eStateInvalid; - if (log) - log->Printf ("ProcessGDBRemote::InterruptIfRunning() catch stop event: state = %s, timed-out=%i", StateAsCString(state), timed_out); - - if (timed_out) - error.SetErrorString("unable to verify target stopped"); - } - - if (paused_private_state_thread) - { - if (log) - log->Printf ("ProcessGDBRemote::InterruptIfRunning() resuming private state thread"); - ResumePrivateStateThread(); - } - } - return error; -} - -Error -ProcessGDBRemote::WillDetach () -{ - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - if (log) - log->Printf ("ProcessGDBRemote::WillDetach()"); - - bool discard_thread_plans = true; - bool catch_stop_event = true; - EventSP event_sp; - return InterruptIfRunning (discard_thread_plans, catch_stop_event, event_sp); -} - -Error -ProcessGDBRemote::DoDetach() -{ - Error error; - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - if (log) - log->Printf ("ProcessGDBRemote::DoDetach()"); - - DisableAllBreakpointSites (); - - m_thread_list.DiscardThreadPlans(); - - bool success = m_gdb_comm.Detach (); - if (log) - { - if (success) - log->PutCString ("ProcessGDBRemote::DoDetach() detach packet sent successfully"); - else - log->PutCString ("ProcessGDBRemote::DoDetach() detach packet send failed"); - } - // Sleep for one second to let the process get all detached... - StopAsyncThread (); - - SetPrivateState (eStateDetached); - ResumePrivateStateThread(); - - //KillDebugserverProcess (); - return error; -} - -Error -ProcessGDBRemote::DoDestroy () -{ - Error error; - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - if (log) - log->Printf ("ProcessGDBRemote::DoDestroy()"); - - // Interrupt if our inferior is running... - if (m_gdb_comm.IsConnected()) - { - if (m_public_state.GetValue() != eStateAttaching) - { - - StringExtractorGDBRemote response; - bool send_async = true; - if (m_gdb_comm.SendPacketAndWaitForResponse("k", 1, response, send_async)) - { - char packet_cmd = response.GetChar(0); - - if (packet_cmd == 'W' || packet_cmd == 'X') - { - SetLastStopPacket (response); - ClearThreadIDList (); - SetExitStatus(response.GetHexU8(), NULL); - } - } - else - { - SetExitStatus(SIGABRT, NULL); - //error.SetErrorString("kill packet failed"); - } - } - } - StopAsyncThread (); - KillDebugserverProcess (); - return error; -} - -//------------------------------------------------------------------ -// Process Queries -//------------------------------------------------------------------ - -bool -ProcessGDBRemote::IsAlive () -{ - return m_gdb_comm.IsConnected() && m_private_state.GetValue() != eStateExited; -} - -addr_t -ProcessGDBRemote::GetImageInfoAddress() -{ - return m_gdb_comm.GetShlibInfoAddr(); -} - -//------------------------------------------------------------------ -// Process Memory -//------------------------------------------------------------------ -size_t -ProcessGDBRemote::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error) -{ - if (size > m_max_memory_size) - { - // Keep memory read sizes down to a sane limit. This function will be - // called multiple times in order to complete the task by - // lldb_private::Process so it is ok to do this. - size = m_max_memory_size; - } - - char packet[64]; - const int packet_len = ::snprintf (packet, sizeof(packet), "m%llx,%zx", (uint64_t)addr, size); - assert (packet_len + 1 < sizeof(packet)); - StringExtractorGDBRemote response; - if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true)) - { - if (response.IsNormalResponse()) - { - error.Clear(); - return response.GetHexBytes(buf, size, '\xdd'); - } - else if (response.IsErrorResponse()) - error.SetErrorStringWithFormat("gdb remote returned an error: %s", response.GetStringRef().c_str()); - else if (response.IsUnsupportedResponse()) - error.SetErrorStringWithFormat("'%s' packet unsupported", packet); - else - error.SetErrorStringWithFormat("unexpected response to '%s': '%s'", packet, response.GetStringRef().c_str()); - } - else - { - error.SetErrorStringWithFormat("failed to sent packet: '%s'", packet); - } - return 0; -} - -size_t -ProcessGDBRemote::DoWriteMemory (addr_t addr, const void *buf, size_t size, Error &error) -{ - if (size > m_max_memory_size) - { - // Keep memory read sizes down to a sane limit. This function will be - // called multiple times in order to complete the task by - // lldb_private::Process so it is ok to do this. - size = m_max_memory_size; - } - - StreamString packet; - packet.Printf("M%llx,%zx:", addr, size); - packet.PutBytesAsRawHex8(buf, size, lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder()); - StringExtractorGDBRemote response; - if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, true)) - { - if (response.IsOKResponse()) - { - error.Clear(); - return size; - } - else if (response.IsErrorResponse()) - error.SetErrorStringWithFormat("gdb remote returned an error: %s", response.GetStringRef().c_str()); - else if (response.IsUnsupportedResponse()) - error.SetErrorStringWithFormat("'%s' packet unsupported", packet.GetString().c_str()); - else - error.SetErrorStringWithFormat("unexpected response to '%s': '%s'", packet.GetString().c_str(), response.GetStringRef().c_str()); - } - else - { - error.SetErrorStringWithFormat("failed to sent packet: '%s'", packet.GetString().c_str()); - } - return 0; -} - -lldb::addr_t -ProcessGDBRemote::DoAllocateMemory (size_t size, uint32_t permissions, Error &error) -{ - addr_t allocated_addr = LLDB_INVALID_ADDRESS; - - LazyBool supported = m_gdb_comm.SupportsAllocDeallocMemory(); - switch (supported) - { - case eLazyBoolCalculate: - case eLazyBoolYes: - allocated_addr = m_gdb_comm.AllocateMemory (size, permissions); - if (allocated_addr != LLDB_INVALID_ADDRESS || supported == eLazyBoolYes) - return allocated_addr; - - case eLazyBoolNo: - // Call mmap() to create memory in the inferior.. - unsigned prot = 0; - if (permissions & lldb::ePermissionsReadable) - prot |= eMmapProtRead; - if (permissions & lldb::ePermissionsWritable) - prot |= eMmapProtWrite; - if (permissions & lldb::ePermissionsExecutable) - prot |= eMmapProtExec; - - if (InferiorCallMmap(this, allocated_addr, 0, size, prot, - eMmapFlagsAnon | eMmapFlagsPrivate, -1, 0)) - m_addr_to_mmap_size[allocated_addr] = size; - else - allocated_addr = LLDB_INVALID_ADDRESS; - break; - } - - if (allocated_addr == LLDB_INVALID_ADDRESS) - error.SetErrorStringWithFormat("unable to allocate %zu bytes of memory with permissions %s", size, GetPermissionsAsCString (permissions)); - else - error.Clear(); - return allocated_addr; -} - -Error -ProcessGDBRemote::GetMemoryRegionInfo (addr_t load_addr, - MemoryRegionInfo ®ion_info) -{ - - Error error (m_gdb_comm.GetMemoryRegionInfo (load_addr, region_info)); - return error; -} - -Error -ProcessGDBRemote::DoDeallocateMemory (lldb::addr_t addr) -{ - Error error; - LazyBool supported = m_gdb_comm.SupportsAllocDeallocMemory(); - - switch (supported) - { - case eLazyBoolCalculate: - // We should never be deallocating memory without allocating memory - // first so we should never get eLazyBoolCalculate - error.SetErrorString ("tried to deallocate memory without ever allocating memory"); - break; - - case eLazyBoolYes: - if (!m_gdb_comm.DeallocateMemory (addr)) - error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr); - break; - - case eLazyBoolNo: - // Call munmap() to deallocate memory in the inferior.. - { - MMapMap::iterator pos = m_addr_to_mmap_size.find(addr); - if (pos != m_addr_to_mmap_size.end() && - InferiorCallMunmap(this, addr, pos->second)) - m_addr_to_mmap_size.erase (pos); - else - error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr); - } - break; - } - - return error; -} - - -//------------------------------------------------------------------ -// Process STDIO -//------------------------------------------------------------------ -size_t -ProcessGDBRemote::PutSTDIN (const char *src, size_t src_len, Error &error) -{ - if (m_stdio_communication.IsConnected()) - { - ConnectionStatus status; - m_stdio_communication.Write(src, src_len, status, NULL); - } - return 0; -} - -Error -ProcessGDBRemote::EnableBreakpoint (BreakpointSite *bp_site) -{ - Error error; - assert (bp_site != NULL); - - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS)); - user_id_t site_id = bp_site->GetID(); - const addr_t addr = bp_site->GetLoadAddress(); - if (log) - log->Printf ("ProcessGDBRemote::EnableBreakpoint (size_id = %llu) address = 0x%llx", site_id, (uint64_t)addr); - - if (bp_site->IsEnabled()) - { - if (log) - log->Printf ("ProcessGDBRemote::EnableBreakpoint (size_id = %llu) address = 0x%llx -- SUCCESS (already enabled)", site_id, (uint64_t)addr); - return error; - } - else - { - const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode (bp_site); - - if (bp_site->HardwarePreferred()) - { - // Try and set hardware breakpoint, and if that fails, fall through - // and set a software breakpoint? - if (m_gdb_comm.SupportsGDBStoppointPacket (eBreakpointHardware)) - { - if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointHardware, true, addr, bp_op_size) == 0) - { - bp_site->SetEnabled(true); - bp_site->SetType (BreakpointSite::eHardware); - return error; - } - } - } - - if (m_gdb_comm.SupportsGDBStoppointPacket (eBreakpointSoftware)) - { - if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, true, addr, bp_op_size) == 0) - { - bp_site->SetEnabled(true); - bp_site->SetType (BreakpointSite::eExternal); - return error; - } - } - - return EnableSoftwareBreakpoint (bp_site); - } - - if (log) - { - const char *err_string = error.AsCString(); - log->Printf ("ProcessGDBRemote::EnableBreakpoint() error for breakpoint at 0x%8.8llx: %s", - bp_site->GetLoadAddress(), - err_string ? err_string : "NULL"); - } - // We shouldn't reach here on a successful breakpoint enable... - if (error.Success()) - error.SetErrorToGenericError(); - return error; -} - -Error -ProcessGDBRemote::DisableBreakpoint (BreakpointSite *bp_site) -{ - Error error; - assert (bp_site != NULL); - addr_t addr = bp_site->GetLoadAddress(); - user_id_t site_id = bp_site->GetID(); - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS)); - if (log) - log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %llu) addr = 0x%8.8llx", site_id, (uint64_t)addr); - - if (bp_site->IsEnabled()) - { - const size_t bp_op_size = GetSoftwareBreakpointTrapOpcode (bp_site); - - BreakpointSite::Type bp_type = bp_site->GetType(); - switch (bp_type) - { - case BreakpointSite::eSoftware: - error = DisableSoftwareBreakpoint (bp_site); - break; - - case BreakpointSite::eHardware: - if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, false, addr, bp_op_size)) - error.SetErrorToGenericError(); - break; - - case BreakpointSite::eExternal: - if (m_gdb_comm.SendGDBStoppointTypePacket(eBreakpointSoftware, false, addr, bp_op_size)) - error.SetErrorToGenericError(); - break; - } - if (error.Success()) - bp_site->SetEnabled(false); - } - else - { - if (log) - log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %llu) addr = 0x%8.8llx -- SUCCESS (already disabled)", site_id, (uint64_t)addr); - return error; - } - - if (error.Success()) - error.SetErrorToGenericError(); - return error; -} - -// Pre-requisite: wp != NULL. -static GDBStoppointType -GetGDBStoppointType (Watchpoint *wp) -{ - assert(wp); - bool watch_read = wp->WatchpointRead(); - bool watch_write = wp->WatchpointWrite(); - - // watch_read and watch_write cannot both be false. - assert(watch_read || watch_write); - if (watch_read && watch_write) - return eWatchpointReadWrite; - else if (watch_read) - return eWatchpointRead; - else // Must be watch_write, then. - return eWatchpointWrite; -} - -Error -ProcessGDBRemote::EnableWatchpoint (Watchpoint *wp) -{ - Error error; - if (wp) - { - user_id_t watchID = wp->GetID(); - addr_t addr = wp->GetLoadAddress(); - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS)); - if (log) - log->Printf ("ProcessGDBRemote::EnableWatchpoint(watchID = %llu)", watchID); - if (wp->IsEnabled()) - { - if (log) - log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %llu) addr = 0x%8.8llx: watchpoint already enabled.", watchID, (uint64_t)addr); - return error; - } - - GDBStoppointType type = GetGDBStoppointType(wp); - // Pass down an appropriate z/Z packet... - if (m_gdb_comm.SupportsGDBStoppointPacket (type)) - { - if (m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr, wp->GetByteSize()) == 0) - { - wp->SetEnabled(true); - return error; - } - else - error.SetErrorString("sending gdb watchpoint packet failed"); - } - else - error.SetErrorString("watchpoints not supported"); - } - else - { - error.SetErrorString("Watchpoint argument was NULL."); - } - if (error.Success()) - error.SetErrorToGenericError(); - return error; -} - -Error -ProcessGDBRemote::DisableWatchpoint (Watchpoint *wp) -{ - Error error; - if (wp) - { - user_id_t watchID = wp->GetID(); - - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS)); - - addr_t addr = wp->GetLoadAddress(); - if (log) - log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %llu) addr = 0x%8.8llx", watchID, (uint64_t)addr); - - if (!wp->IsEnabled()) - { - if (log) - log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %llu) addr = 0x%8.8llx -- SUCCESS (already disabled)", watchID, (uint64_t)addr); - return error; - } - - if (wp->IsHardware()) - { - GDBStoppointType type = GetGDBStoppointType(wp); - // Pass down an appropriate z/Z packet... - if (m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr, wp->GetByteSize()) == 0) - { - wp->SetEnabled(false); - return error; - } - else - error.SetErrorString("sending gdb watchpoint packet failed"); - } - // TODO: clear software watchpoints if we implement them - } - else - { - error.SetErrorString("Watchpoint argument was NULL."); - } - if (error.Success()) - error.SetErrorToGenericError(); - return error; -} - -void -ProcessGDBRemote::Clear() -{ - m_flags = 0; - m_thread_list.Clear(); -} - -Error -ProcessGDBRemote::DoSignal (int signo) -{ - Error error; - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - if (log) - log->Printf ("ProcessGDBRemote::DoSignal (signal = %d)", signo); - - if (!m_gdb_comm.SendAsyncSignal (signo)) - error.SetErrorStringWithFormat("failed to send signal %i", signo); - return error; -} - -Error -ProcessGDBRemote::StartDebugserverProcess (const char *debugserver_url) -{ - ProcessLaunchInfo launch_info; - return StartDebugserverProcess(debugserver_url, launch_info); -} - -Error -ProcessGDBRemote::StartDebugserverProcess (const char *debugserver_url, const ProcessInfo &process_info) // The connection string to use in the spawned debugserver ("localhost:1234" or "/dev/tty...") -{ - Error error; - if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID) - { - // If we locate debugserver, keep that located version around - static FileSpec g_debugserver_file_spec; - - ProcessLaunchInfo debugserver_launch_info; - char debugserver_path[PATH_MAX]; - FileSpec &debugserver_file_spec = debugserver_launch_info.GetExecutableFile(); - - // Always check to see if we have an environment override for the path - // to the debugserver to use and use it if we do. - const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH"); - if (env_debugserver_path) - debugserver_file_spec.SetFile (env_debugserver_path, false); - else - debugserver_file_spec = g_debugserver_file_spec; - bool debugserver_exists = debugserver_file_spec.Exists(); - if (!debugserver_exists) - { - // The debugserver binary is in the LLDB.framework/Resources - // directory. - if (Host::GetLLDBPath (ePathTypeSupportExecutableDir, debugserver_file_spec)) - { - debugserver_file_spec.GetFilename().SetCString(DEBUGSERVER_BASENAME); - debugserver_exists = debugserver_file_spec.Exists(); - if (debugserver_exists) - { - g_debugserver_file_spec = debugserver_file_spec; - } - else - { - g_debugserver_file_spec.Clear(); - debugserver_file_spec.Clear(); - } - } - } - - if (debugserver_exists) - { - debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path)); - - m_stdio_communication.Clear(); - - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); - - Args &debugserver_args = debugserver_launch_info.GetArguments(); - char arg_cstr[PATH_MAX]; - - // Start args with "debugserver /file/path -r --" - debugserver_args.AppendArgument(debugserver_path); - debugserver_args.AppendArgument(debugserver_url); - // use native registers, not the GDB registers - debugserver_args.AppendArgument("--native-regs"); - // make debugserver run in its own session so signals generated by - // special terminal key sequences (^C) don't affect debugserver - debugserver_args.AppendArgument("--setsid"); - - const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE"); - if (env_debugserver_log_file) - { - ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-file=%s", env_debugserver_log_file); - debugserver_args.AppendArgument(arg_cstr); - } - - const char *env_debugserver_log_flags = getenv("LLDB_DEBUGSERVER_LOG_FLAGS"); - if (env_debugserver_log_flags) - { - ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags); - debugserver_args.AppendArgument(arg_cstr); - } -// debugserver_args.AppendArgument("--log-file=/tmp/debugserver.txt"); -// debugserver_args.AppendArgument("--log-flags=0x802e0e"); - - // We currently send down all arguments, attach pids, or attach - // process names in dedicated GDB server packets, so we don't need - // to pass them as arguments. This is currently because of all the - // things we need to setup prior to launching: the environment, - // current working dir, file actions, etc. -#if 0 - // Now append the program arguments - if (inferior_argv) - { - // Terminate the debugserver args so we can now append the inferior args - debugserver_args.AppendArgument("--"); - - for (int i = 0; inferior_argv[i] != NULL; ++i) - debugserver_args.AppendArgument (inferior_argv[i]); - } - else if (attach_pid != LLDB_INVALID_PROCESS_ID) - { - ::snprintf (arg_cstr, sizeof(arg_cstr), "--attach=%u", attach_pid); - debugserver_args.AppendArgument (arg_cstr); - } - else if (attach_name && attach_name[0]) - { - if (wait_for_launch) - debugserver_args.AppendArgument ("--waitfor"); - else - debugserver_args.AppendArgument ("--attach"); - debugserver_args.AppendArgument (attach_name); - } -#endif - - ProcessLaunchInfo::FileAction file_action; - - // Close STDIN, STDOUT and STDERR. We might need to redirect them - // to "/dev/null" if we run into any problems. - file_action.Close (STDIN_FILENO); - debugserver_launch_info.AppendFileAction (file_action); - file_action.Close (STDOUT_FILENO); - debugserver_launch_info.AppendFileAction (file_action); - file_action.Close (STDERR_FILENO); - debugserver_launch_info.AppendFileAction (file_action); - - if (log) - { - StreamString strm; - debugserver_args.Dump (&strm); - log->Printf("%s arguments:\n%s", debugserver_args.GetArgumentAtIndex(0), strm.GetData()); - } - - debugserver_launch_info.SetMonitorProcessCallback (MonitorDebugserverProcess, this, false); - debugserver_launch_info.SetUserID(process_info.GetUserID()); - - error = Host::LaunchProcess(debugserver_launch_info); - - if (error.Success ()) - m_debugserver_pid = debugserver_launch_info.GetProcessID(); - else - m_debugserver_pid = LLDB_INVALID_PROCESS_ID; - - if (error.Fail() || log) - error.PutToLog(log.get(), "Host::LaunchProcess (launch_info) => pid=%llu, path='%s'", m_debugserver_pid, debugserver_path); - } - else - { - error.SetErrorStringWithFormat ("unable to locate " DEBUGSERVER_BASENAME); - } - - if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID) - StartAsyncThread (); - } - return error; -} - -bool -ProcessGDBRemote::MonitorDebugserverProcess -( - void *callback_baton, - lldb::pid_t debugserver_pid, - bool exited, // True if the process did exit - int signo, // Zero for no signal - int exit_status // Exit value of process if signal is zero -) -{ - // The baton is a "ProcessGDBRemote *". Now this class might be gone - // and might not exist anymore, so we need to carefully try to get the - // target for this process first since we have a race condition when - // we are done running between getting the notice that the inferior - // process has died and the debugserver that was debugging this process. - // In our test suite, we are also continually running process after - // process, so we must be very careful to make sure: - // 1 - process object hasn't been deleted already - // 2 - that a new process object hasn't been recreated in its place - - // "debugserver_pid" argument passed in is the process ID for - // debugserver that we are tracking... - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - - ProcessGDBRemote *process = (ProcessGDBRemote *)callback_baton; - - // Get a shared pointer to the target that has a matching process pointer. - // This target could be gone, or the target could already have a new process - // object inside of it - TargetSP target_sp (Debugger::FindTargetWithProcess(process)); - - if (log) - log->Printf ("ProcessGDBRemote::MonitorDebugserverProcess (baton=%p, pid=%llu, signo=%i (0x%x), exit_status=%i)", callback_baton, debugserver_pid, signo, signo, exit_status); - - if (target_sp) - { - // We found a process in a target that matches, but another thread - // might be in the process of launching a new process that will - // soon replace it, so get a shared pointer to the process so we - // can keep it alive. - ProcessSP process_sp (target_sp->GetProcessSP()); - // Now we have a shared pointer to the process that can't go away on us - // so we now make sure it was the same as the one passed in, and also make - // sure that our previous "process *" didn't get deleted and have a new - // "process *" created in its place with the same pointer. To verify this - // we make sure the process has our debugserver process ID. If we pass all - // of these tests, then we are sure that this process is the one we were - // looking for. - if (process_sp && process == process_sp.get() && process->m_debugserver_pid == debugserver_pid) - { - // Sleep for a half a second to make sure our inferior process has - // time to set its exit status before we set it incorrectly when - // both the debugserver and the inferior process shut down. - usleep (500000); - // If our process hasn't yet exited, debugserver might have died. - // If the process did exit, the we are reaping it. - const StateType state = process->GetState(); - - if (process->m_debugserver_pid != LLDB_INVALID_PROCESS_ID && - state != eStateInvalid && - state != eStateUnloaded && - state != eStateExited && - state != eStateDetached) - { - char error_str[1024]; - if (signo) - { - const char *signal_cstr = process->GetUnixSignals().GetSignalAsCString (signo); - if (signal_cstr) - ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr); - else - ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %i", signo); - } - else - { - ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with an exit status of 0x%8.8x", exit_status); - } - - process->SetExitStatus (-1, error_str); - } - // Debugserver has exited we need to let our ProcessGDBRemote - // know that it no longer has a debugserver instance - process->m_debugserver_pid = LLDB_INVALID_PROCESS_ID; - } - } - return true; -} - -void -ProcessGDBRemote::KillDebugserverProcess () -{ - if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID) - { - ::kill (m_debugserver_pid, SIGINT); - m_debugserver_pid = LLDB_INVALID_PROCESS_ID; - } -} - -void -ProcessGDBRemote::Initialize() -{ - static bool g_initialized = false; - - if (g_initialized == false) - { - g_initialized = true; - PluginManager::RegisterPlugin (GetPluginNameStatic(), - GetPluginDescriptionStatic(), - CreateInstance); - - Log::Callbacks log_callbacks = { - ProcessGDBRemoteLog::DisableLog, - ProcessGDBRemoteLog::EnableLog, - ProcessGDBRemoteLog::ListLogCategories - }; - - Log::RegisterLogChannel (ProcessGDBRemote::GetPluginNameStatic(), log_callbacks); - } -} - -bool -ProcessGDBRemote::StartAsyncThread () -{ - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - - if (log) - log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__); - - // Create a thread that watches our internal state and controls which - // events make it to clients (into the DCProcess event queue). - m_async_thread = Host::ThreadCreate ("<lldb.process.gdb-remote.async>", ProcessGDBRemote::AsyncThread, this, NULL); - return IS_VALID_LLDB_HOST_THREAD(m_async_thread); -} - -void -ProcessGDBRemote::StopAsyncThread () -{ - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); - - if (log) - log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__); - - m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncThreadShouldExit); - - // This will shut down the async thread. - m_gdb_comm.Disconnect(); // Disconnect from the debug server. - - // Stop the stdio thread - if (IS_VALID_LLDB_HOST_THREAD(m_async_thread)) - { - Host::ThreadJoin (m_async_thread, NULL, NULL); - } -} - - -void * -ProcessGDBRemote::AsyncThread (void *arg) -{ - ProcessGDBRemote *process = (ProcessGDBRemote*) arg; - - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS)); - if (log) - log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) thread starting...", __FUNCTION__, arg, process->GetID()); - - Listener listener ("ProcessGDBRemote::AsyncThread"); - EventSP event_sp; - const uint32_t desired_event_mask = eBroadcastBitAsyncContinue | - eBroadcastBitAsyncThreadShouldExit; - - if (listener.StartListeningForEvents (&process->m_async_broadcaster, desired_event_mask) == desired_event_mask) - { - listener.StartListeningForEvents (&process->m_gdb_comm, Communication::eBroadcastBitReadThreadDidExit); - - bool done = false; - while (!done) - { - if (log) - log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID()); - if (listener.WaitForEvent (NULL, event_sp)) - { - const uint32_t event_type = event_sp->GetType(); - if (event_sp->BroadcasterIs (&process->m_async_broadcaster)) - { - if (log) - log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) Got an event of type: %d...", __FUNCTION__, arg, process->GetID(), event_type); - - switch (event_type) - { - case eBroadcastBitAsyncContinue: - { - const EventDataBytes *continue_packet = EventDataBytes::GetEventDataFromEvent(event_sp.get()); - - if (continue_packet) - { - const char *continue_cstr = (const char *)continue_packet->GetBytes (); - const size_t continue_cstr_len = continue_packet->GetByteSize (); - if (log) - log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr); - - if (::strstr (continue_cstr, "vAttach") == NULL) - process->SetPrivateState(eStateRunning); - StringExtractorGDBRemote response; - StateType stop_state = process->GetGDBRemote().SendContinuePacketAndWaitForResponse (process, continue_cstr, continue_cstr_len, response); - - switch (stop_state) - { - case eStateStopped: - case eStateCrashed: - case eStateSuspended: - process->SetLastStopPacket (response); - process->SetPrivateState (stop_state); - break; - - case eStateExited: - process->SetLastStopPacket (response); - process->ClearThreadIDList(); - response.SetFilePos(1); - process->SetExitStatus(response.GetHexU8(), NULL); - done = true; - break; - - case eStateInvalid: - process->SetExitStatus(-1, "lost connection"); - break; - - default: - process->SetPrivateState (stop_state); - break; - } - } - } - break; - - case eBroadcastBitAsyncThreadShouldExit: - if (log) - log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID()); - done = true; - break; - - default: - if (log) - log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type); - done = true; - break; - } - } - else if (event_sp->BroadcasterIs (&process->m_gdb_comm)) - { - if (event_type & Communication::eBroadcastBitReadThreadDidExit) - { - process->SetExitStatus (-1, "lost connection"); - done = true; - } - } - } - else - { - if (log) - log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID()); - done = true; - } - } - } - - if (log) - log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) thread exiting...", __FUNCTION__, arg, process->GetID()); - - process->m_async_thread = LLDB_INVALID_HOST_THREAD; - return NULL; -} - -const char * -ProcessGDBRemote::GetDispatchQueueNameForThread -( - addr_t thread_dispatch_qaddr, - std::string &dispatch_queue_name -) -{ - dispatch_queue_name.clear(); - if (thread_dispatch_qaddr != 0 && thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) - { - // Cache the dispatch_queue_offsets_addr value so we don't always have - // to look it up - if (m_dispatch_queue_offsets_addr == LLDB_INVALID_ADDRESS) - { - static ConstString g_dispatch_queue_offsets_symbol_name ("dispatch_queue_offsets"); - const Symbol *dispatch_queue_offsets_symbol = NULL; - ModuleSpec libSystem_module_spec (FileSpec("libSystem.B.dylib", false)); - ModuleSP module_sp(GetTarget().GetImages().FindFirstModule (libSystem_module_spec)); - if (module_sp) - dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData); - - if (dispatch_queue_offsets_symbol == NULL) - { - ModuleSpec libdispatch_module_spec (FileSpec("libdispatch.dylib", false)); - module_sp = GetTarget().GetImages().FindFirstModule (libdispatch_module_spec); - if (module_sp) - dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData); - } - if (dispatch_queue_offsets_symbol) - m_dispatch_queue_offsets_addr = dispatch_queue_offsets_symbol->GetAddress().GetLoadAddress(&m_target); - - if (m_dispatch_queue_offsets_addr == LLDB_INVALID_ADDRESS) - return NULL; - } - - uint8_t memory_buffer[8]; - DataExtractor data (memory_buffer, - sizeof(memory_buffer), - m_target.GetArchitecture().GetByteOrder(), - m_target.GetArchitecture().GetAddressByteSize()); - - // Excerpt from src/queue_private.h - struct dispatch_queue_offsets_s - { - uint16_t dqo_version; - uint16_t dqo_label; - uint16_t dqo_label_size; - } dispatch_queue_offsets; - - - Error error; - if (ReadMemory (m_dispatch_queue_offsets_addr, memory_buffer, sizeof(dispatch_queue_offsets), error) == sizeof(dispatch_queue_offsets)) - { - uint32_t data_offset = 0; - if (data.GetU16(&data_offset, &dispatch_queue_offsets.dqo_version, sizeof(dispatch_queue_offsets)/sizeof(uint16_t))) - { - if (ReadMemory (thread_dispatch_qaddr, &memory_buffer, data.GetAddressByteSize(), error) == data.GetAddressByteSize()) - { - data_offset = 0; - lldb::addr_t queue_addr = data.GetAddress(&data_offset); - lldb::addr_t label_addr = queue_addr + dispatch_queue_offsets.dqo_label; - dispatch_queue_name.resize(dispatch_queue_offsets.dqo_label_size, '\0'); - size_t bytes_read = ReadMemory (label_addr, &dispatch_queue_name[0], dispatch_queue_offsets.dqo_label_size, error); - if (bytes_read < dispatch_queue_offsets.dqo_label_size) - dispatch_queue_name.erase (bytes_read); - } - } - } - } - if (dispatch_queue_name.empty()) - return NULL; - return dispatch_queue_name.c_str(); -} - -//uint32_t -//ProcessGDBRemote::ListProcessesMatchingName (const char *name, StringList &matches, std::vector<lldb::pid_t> &pids) -//{ -// // If we are planning to launch the debugserver remotely, then we need to fire up a debugserver -// // process and ask it for the list of processes. But if we are local, we can let the Host do it. -// if (m_local_debugserver) -// { -// return Host::ListProcessesMatchingName (name, matches, pids); -// } -// else -// { -// // FIXME: Implement talking to the remote debugserver. -// return 0; -// } -// -//} -// -bool -ProcessGDBRemote::NewThreadNotifyBreakpointHit (void *baton, - lldb_private::StoppointCallbackContext *context, - lldb::user_id_t break_id, - lldb::user_id_t break_loc_id) -{ - // I don't think I have to do anything here, just make sure I notice the new thread when it starts to - // run so I can stop it if that's what I want to do. - LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); - if (log) - log->Printf("Hit New Thread Notification breakpoint."); - return false; -} - - -bool -ProcessGDBRemote::StartNoticingNewThreads() -{ - static const char *bp_names[] = - { - "start_wqthread", - "_pthread_wqthread", - "_pthread_start", - NULL - }; - - LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); - size_t num_bps = m_thread_observation_bps.size(); - if (num_bps != 0) - { - for (int i = 0; i < num_bps; i++) - { - lldb::BreakpointSP break_sp = m_target.GetBreakpointByID(m_thread_observation_bps[i]); - if (break_sp) - { - if (log && log->GetVerbose()) - log->Printf("Enabled noticing new thread breakpoint."); - break_sp->SetEnabled(true); - } - } - } - else - { - for (int i = 0; bp_names[i] != NULL; i++) - { - Breakpoint *breakpoint = m_target.CreateBreakpoint (NULL, NULL, bp_names[i], eFunctionNameTypeFull, true).get(); - if (breakpoint) - { - if (log && log->GetVerbose()) - log->Printf("Successfully created new thread notification breakpoint at \"%s\".", bp_names[i]); - m_thread_observation_bps.push_back(breakpoint->GetID()); - breakpoint->SetCallback (ProcessGDBRemote::NewThreadNotifyBreakpointHit, this, true); - } - else - { - if (log) - log->Printf("Failed to create new thread notification breakpoint."); - return false; - } - } - } - - return true; -} - -bool -ProcessGDBRemote::StopNoticingNewThreads() -{ - LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); - if (log && log->GetVerbose()) - log->Printf ("Disabling new thread notification breakpoint."); - size_t num_bps = m_thread_observation_bps.size(); - if (num_bps != 0) - { - for (int i = 0; i < num_bps; i++) - { - - lldb::BreakpointSP break_sp = m_target.GetBreakpointByID(m_thread_observation_bps[i]); - if (break_sp) - { - break_sp->SetEnabled(false); - } - } - } - return true; -} - - diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h deleted file mode 100644 index 1c9e845e35b1..000000000000 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ /dev/null @@ -1,382 +0,0 @@ -//===-- ProcessGDBRemote.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_ProcessGDBRemote_h_ -#define liblldb_ProcessGDBRemote_h_ - -// C Includes - -// C++ Includes -#include <list> -#include <vector> - -// Other libraries and framework includes -#include "lldb/Core/ArchSpec.h" -#include "lldb/Core/Broadcaster.h" -#include "lldb/Core/Error.h" -#include "lldb/Core/InputReader.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Core/StringList.h" -#include "lldb/Core/ThreadSafeValue.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/Thread.h" - -#include "GDBRemoteCommunicationClient.h" -#include "Utility/StringExtractor.h" -#include "GDBRemoteRegisterContext.h" - -class ThreadGDBRemote; - -class ProcessGDBRemote : public lldb_private::Process -{ -public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - static lldb::ProcessSP - CreateInstance (lldb_private::Target& target, - lldb_private::Listener &listener, - const lldb_private::FileSpec *crash_file_path); - - static void - Initialize(); - - static void - Terminate(); - - static const char * - GetPluginNameStatic(); - - static const char * - GetPluginDescriptionStatic(); - - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - ProcessGDBRemote(lldb_private::Target& target, lldb_private::Listener &listener); - - virtual - ~ProcessGDBRemote(); - - //------------------------------------------------------------------ - // Check if a given Process - //------------------------------------------------------------------ - virtual bool - CanDebug (lldb_private::Target &target, - bool plugin_specified_by_name); - -// virtual uint32_t -// ListProcessesMatchingName (const char *name, lldb_private::StringList &matches, std::vector<lldb::pid_t> &pids); - - //------------------------------------------------------------------ - // Creating a new process, or attaching to an existing one - //------------------------------------------------------------------ - virtual lldb_private::Error - WillLaunch (lldb_private::Module* module); - - virtual lldb_private::Error - DoLaunch (lldb_private::Module *exe_module, - const lldb_private::ProcessLaunchInfo &launch_info); - - virtual void - DidLaunch (); - - virtual lldb_private::Error - WillAttachToProcessWithID (lldb::pid_t pid); - - virtual lldb_private::Error - WillAttachToProcessWithName (const char *process_name, bool wait_for_launch); - - virtual lldb_private::Error - DoConnectRemote (const char *remote_url); - - lldb_private::Error - WillLaunchOrAttach (); - - virtual lldb_private::Error - DoAttachToProcessWithID (lldb::pid_t pid); - - virtual lldb_private::Error - DoAttachToProcessWithID (lldb::pid_t pid, const lldb_private::ProcessAttachInfo &attach_info); - - virtual lldb_private::Error - DoAttachToProcessWithName (const char *process_name, - bool wait_for_launch, - const lldb_private::ProcessAttachInfo &attach_info); - - virtual void - DidAttach (); - - //------------------------------------------------------------------ - // PluginInterface protocol - //------------------------------------------------------------------ - virtual const char * - GetPluginName(); - - virtual const char * - GetShortPluginName(); - - virtual uint32_t - GetPluginVersion(); - - //------------------------------------------------------------------ - // Process Control - //------------------------------------------------------------------ - virtual lldb_private::Error - WillResume (); - - virtual lldb_private::Error - DoResume (); - - virtual lldb_private::Error - DoHalt (bool &caused_stop); - - virtual lldb_private::Error - WillDetach (); - - virtual lldb_private::Error - DoDetach (); - - virtual lldb_private::Error - DoSignal (int signal); - - virtual lldb_private::Error - DoDestroy (); - - virtual void - RefreshStateAfterStop(); - - //------------------------------------------------------------------ - // Process Queries - //------------------------------------------------------------------ - virtual bool - IsAlive (); - - virtual lldb::addr_t - GetImageInfoAddress(); - - //------------------------------------------------------------------ - // Process Memory - //------------------------------------------------------------------ - virtual size_t - DoReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error); - - virtual size_t - DoWriteMemory (lldb::addr_t addr, const void *buf, size_t size, lldb_private::Error &error); - - virtual lldb::addr_t - DoAllocateMemory (size_t size, uint32_t permissions, lldb_private::Error &error); - - virtual lldb_private::Error - GetMemoryRegionInfo (lldb::addr_t load_addr, - lldb_private::MemoryRegionInfo ®ion_info); - - virtual lldb_private::Error - DoDeallocateMemory (lldb::addr_t ptr); - - //------------------------------------------------------------------ - // Process STDIO - //------------------------------------------------------------------ - virtual size_t - PutSTDIN (const char *buf, size_t buf_size, lldb_private::Error &error); - - //---------------------------------------------------------------------- - // Process Breakpoints - //---------------------------------------------------------------------- - virtual lldb_private::Error - EnableBreakpoint (lldb_private::BreakpointSite *bp_site); - - virtual lldb_private::Error - DisableBreakpoint (lldb_private::BreakpointSite *bp_site); - - //---------------------------------------------------------------------- - // Process Watchpoints - //---------------------------------------------------------------------- - virtual lldb_private::Error - EnableWatchpoint (lldb_private::Watchpoint *wp); - - virtual lldb_private::Error - DisableWatchpoint (lldb_private::Watchpoint *wp); - - virtual bool - StartNoticingNewThreads(); - - virtual bool - StopNoticingNewThreads(); - - GDBRemoteCommunicationClient & - GetGDBRemote() - { - return m_gdb_comm; - } - -protected: - friend class ThreadGDBRemote; - friend class GDBRemoteCommunicationClient; - friend class GDBRemoteRegisterContext; - - //---------------------------------------------------------------------- - // 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 - ProcessIDIsValid ( ) const; - - void - Clear ( ); - - lldb_private::Flags & - GetFlags () - { - return m_flags; - } - - const lldb_private::Flags & - GetFlags () const - { - return m_flags; - } - - virtual bool - UpdateThreadList (lldb_private::ThreadList &old_thread_list, - lldb_private::ThreadList &new_thread_list); - - lldb_private::Error - StartDebugserverProcess (const char *debugserver_url); - - lldb_private::Error - StartDebugserverProcess (const char *debugserver_url, const lldb_private::ProcessInfo &process_info); - - void - KillDebugserverProcess (); - - void - BuildDynamicRegisterInfo (bool force); - - void - SetLastStopPacket (const StringExtractorGDBRemote &response) - { - lldb_private::Mutex::Locker locker (m_last_stop_packet_mutex); - m_last_stop_packet = response; - } - //------------------------------------------------------------------ - /// Broadcaster event bits definitions. - //------------------------------------------------------------------ - enum - { - eBroadcastBitAsyncContinue = (1 << 0), - eBroadcastBitAsyncThreadShouldExit = (1 << 1), - eBroadcastBitAsyncThreadDidExit = (1 << 2) - }; - - lldb_private::Flags m_flags; // Process specific flags (see eFlags enums) - GDBRemoteCommunicationClient m_gdb_comm; - lldb::pid_t m_debugserver_pid; - StringExtractorGDBRemote m_last_stop_packet; - lldb_private::Mutex m_last_stop_packet_mutex; - GDBRemoteDynamicRegisterInfo m_register_info; - lldb_private::Broadcaster m_async_broadcaster; - lldb::thread_t m_async_thread; - typedef std::vector<lldb::tid_t> tid_collection; - typedef std::vector< std::pair<lldb::tid_t,int> > tid_sig_collection; - typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap; - tid_collection m_thread_ids; // Thread IDs for all threads. This list gets updated after stopping - tid_collection m_continue_c_tids; // 'c' for continue - tid_sig_collection m_continue_C_tids; // 'C' for continue with signal - tid_collection m_continue_s_tids; // 's' for step - tid_sig_collection m_continue_S_tids; // 'S' for step with signal - lldb::addr_t m_dispatch_queue_offsets_addr; - size_t m_max_memory_size; // The maximum number of bytes to read/write when reading and writing memory - bool m_waiting_for_attach; - std::vector<lldb::user_id_t> m_thread_observation_bps; - MMapMap m_addr_to_mmap_size; - bool - StartAsyncThread (); - - void - StopAsyncThread (); - - static void * - AsyncThread (void *arg); - - static bool - MonitorDebugserverProcess (void *callback_baton, - lldb::pid_t pid, - bool exited, - int signo, - int exit_status); - - lldb::StateType - SetThreadStopInfo (StringExtractor& stop_packet); - - void - ClearThreadIDList (); - - bool - UpdateThreadIDList (); - - void - DidLaunchOrAttach (); - - lldb_private::Error - ConnectToDebugserver (const char *host_port); - - const char * - GetDispatchQueueNameForThread (lldb::addr_t thread_dispatch_qaddr, - std::string &dispatch_queue_name); - - static size_t - AttachInputReaderCallback (void *baton, - lldb_private::InputReader *reader, - lldb::InputReaderAction notification, - const char *bytes, - size_t bytes_len); - - lldb_private::Error - InterruptIfRunning (bool discard_thread_plans, - bool catch_stop_event, - lldb::EventSP &stop_event_sp); - -private: - //------------------------------------------------------------------ - // For ProcessGDBRemote only - //------------------------------------------------------------------ - static bool - NewThreadNotifyBreakpointHit (void *baton, - lldb_private::StoppointCallbackContext *context, - lldb::user_id_t break_id, - lldb::user_id_t break_loc_id); - - DISALLOW_COPY_AND_ASSIGN (ProcessGDBRemote); - -}; - -#endif // liblldb_ProcessGDBRemote_h_ diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp deleted file mode 100644 index cb7642386834..000000000000 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp +++ /dev/null @@ -1,190 +0,0 @@ -//===-- ProcessGDBRemoteLog.cpp ---------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "ProcessGDBRemoteLog.h" - -#include "lldb/Interpreter/Args.h" -#include "lldb/Core/StreamFile.h" - -#include "ProcessGDBRemote.h" - -using namespace lldb; -using namespace lldb_private; - - -// We want to avoid global constructors where code needs to be run so here we -// control access to our static g_log_sp by hiding it in a singleton function -// that will construct the static g_lob_sp the first time this function is -// called. -static LogSP & -GetLog () -{ - static LogSP g_log_sp; - return g_log_sp; -} - -LogSP -ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (uint32_t mask) -{ - LogSP log(GetLog ()); - if (log && mask) - { - uint32_t log_mask = log->GetMask().Get(); - if ((log_mask & mask) != mask) - return LogSP(); - } - return log; -} - -LogSP -ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (uint32_t mask) -{ - LogSP log(GetLog ()); - if (log && log->GetMask().Get() & mask) - return log; - return LogSP(); -} - -void -ProcessGDBRemoteLog::DisableLog (const char **categories, Stream *feedback_strm) -{ - LogSP log (GetLog ()); - if (log) - { - uint32_t flag_bits = 0; - - if (categories[0] != NULL) - { - flag_bits = log->GetMask().Get(); - for (size_t i = 0; categories[i] != NULL; ++i) - { - const char *arg = categories[i]; - - - if (::strcasecmp (arg, "all") == 0 ) flag_bits &= ~GDBR_LOG_ALL; - else if (::strcasecmp (arg, "async") == 0 ) flag_bits &= ~GDBR_LOG_ASYNC; - else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits &= ~GDBR_LOG_BREAKPOINTS; - else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits &= ~GDBR_LOG_COMM; - else if (::strcasecmp (arg, "default") == 0 ) flag_bits &= ~GDBR_LOG_DEFAULT; - else if (::strcasecmp (arg, "packets") == 0 ) flag_bits &= ~GDBR_LOG_PACKETS; - else if (::strcasecmp (arg, "memory") == 0 ) flag_bits &= ~GDBR_LOG_MEMORY; - else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits &= ~GDBR_LOG_MEMORY_DATA_SHORT; - else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits &= ~GDBR_LOG_MEMORY_DATA_LONG; - else if (::strcasecmp (arg, "process") == 0 ) flag_bits &= ~GDBR_LOG_PROCESS; - else if (::strcasecmp (arg, "step") == 0 ) flag_bits &= ~GDBR_LOG_STEP; - else if (::strcasecmp (arg, "thread") == 0 ) flag_bits &= ~GDBR_LOG_THREAD; - else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits &= ~GDBR_LOG_VERBOSE; - else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits &= ~GDBR_LOG_WATCHPOINTS; - else - { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - ListLogCategories (feedback_strm); - } - - } - } - - if (flag_bits == 0) - GetLog ().reset(); - else - log->GetMask().Reset (flag_bits); - } - - return; -} - -LogSP -ProcessGDBRemoteLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **categories, Stream *feedback_strm) -{ - // Try see if there already is a log - that way we can reuse its settings. - // We could reuse the log in toto, but we don't know that the stream is the same. - uint32_t flag_bits = 0; - LogSP log(GetLog ()); - if (log) - flag_bits = log->GetMask().Get(); - - // Now make a new log with this stream if one was provided - if (log_stream_sp) - { - log.reset (new Log(log_stream_sp)); - GetLog () = log; - } - - if (log) - { - bool got_unknown_category = false; - for (size_t i=0; categories[i] != NULL; ++i) - { - const char *arg = categories[i]; - - if (::strcasecmp (arg, "all") == 0 ) flag_bits |= GDBR_LOG_ALL; - else if (::strcasecmp (arg, "async") == 0 ) flag_bits |= GDBR_LOG_ASYNC; - else if (::strncasecmp (arg, "break", 5) == 0 ) flag_bits |= GDBR_LOG_BREAKPOINTS; - else if (::strncasecmp (arg, "comm", 4) == 0 ) flag_bits |= GDBR_LOG_COMM; - else if (::strcasecmp (arg, "default") == 0 ) flag_bits |= GDBR_LOG_DEFAULT; - else if (::strcasecmp (arg, "packets") == 0 ) flag_bits |= GDBR_LOG_PACKETS; - else if (::strcasecmp (arg, "memory") == 0 ) flag_bits |= GDBR_LOG_MEMORY; - else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits |= GDBR_LOG_MEMORY_DATA_SHORT; - else if (::strcasecmp (arg, "data-long") == 0 ) flag_bits |= GDBR_LOG_MEMORY_DATA_LONG; - else if (::strcasecmp (arg, "process") == 0 ) flag_bits |= GDBR_LOG_PROCESS; - else if (::strcasecmp (arg, "step") == 0 ) flag_bits |= GDBR_LOG_STEP; - else if (::strcasecmp (arg, "thread") == 0 ) flag_bits |= GDBR_LOG_THREAD; - else if (::strcasecmp (arg, "verbose") == 0 ) flag_bits |= GDBR_LOG_VERBOSE; - else if (::strncasecmp (arg, "watch", 5) == 0 ) flag_bits |= GDBR_LOG_WATCHPOINTS; - else - { - feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); - if (got_unknown_category == false) - { - got_unknown_category = true; - ListLogCategories (feedback_strm); - } - } - } - if (flag_bits == 0) - flag_bits = GDBR_LOG_DEFAULT; - log->GetMask().Reset(flag_bits); - log->GetOptions().Reset(log_options); - } - return log; -} - -void -ProcessGDBRemoteLog::ListLogCategories (Stream *strm) -{ - strm->Printf ("Logging categories for '%s':\n" - " all - turn on all available logging categories\n" - " async - log asynchronous activity\n" - " break - log breakpoints\n" - " communication - log communication activity\n" - " default - enable the default set of logging categories for liblldb\n" - " packets - log gdb remote packets\n" - " memory - log memory reads and writes\n" - " data-short - log memory bytes for memory reads and writes for short transactions only\n" - " data-long - log memory bytes for memory reads and writes for all transactions\n" - " process - log process events and activities\n" - " thread - log thread events and activities\n" - " step - log step related activities\n" - " verbose - enable verbose logging\n" - " watch - log watchpoint related activities\n", ProcessGDBRemote::GetPluginNameStatic()); -} - - -void -ProcessGDBRemoteLog::LogIf (uint32_t mask, const char *format, ...) -{ - LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (mask)); - if (log) - { - va_list args; - va_start (args, format); - log->VAPrintf (format, args); - va_end (args); - } -} diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h deleted file mode 100644 index cf5e176a2138..000000000000 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h +++ /dev/null @@ -1,57 +0,0 @@ -//===-- ProcessGDBRemoteLog.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_ProcessGDBRemoteLog_h_ -#define liblldb_ProcessGDBRemoteLog_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes - -// Project includes -#include "lldb/Core/Log.h" - -#define GDBR_LOG_VERBOSE (1u << 0) -#define GDBR_LOG_PROCESS (1u << 1) -#define GDBR_LOG_THREAD (1u << 2) -#define GDBR_LOG_PACKETS (1u << 3) -#define GDBR_LOG_MEMORY (1u << 4) // Log memory reads/writes calls -#define GDBR_LOG_MEMORY_DATA_SHORT (1u << 5) // Log short memory reads/writes bytes -#define GDBR_LOG_MEMORY_DATA_LONG (1u << 6) // Log all memory reads/writes bytes -#define GDBR_LOG_BREAKPOINTS (1u << 7) -#define GDBR_LOG_WATCHPOINTS (1u << 8) -#define GDBR_LOG_STEP (1u << 9) -#define GDBR_LOG_COMM (1u << 10) -#define GDBR_LOG_ASYNC (1u << 11) -#define GDBR_LOG_ALL (UINT32_MAX) -#define GDBR_LOG_DEFAULT GDBR_LOG_PACKETS - -class ProcessGDBRemoteLog -{ -public: - static lldb::LogSP - GetLogIfAllCategoriesSet(uint32_t mask = 0); - - static lldb::LogSP - GetLogIfAnyCategoryIsSet (uint32_t mask); - - static void - DisableLog (const char **categories, lldb_private::Stream *feedback_strm); - - static lldb::LogSP - EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options, const char **categories, lldb_private::Stream *feedback_strm); - - static void - ListLogCategories (lldb_private::Stream *strm); - - static void - LogIf (uint32_t mask, const char *format, ...); -}; - -#endif // liblldb_ProcessGDBRemoteLog_h_ diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp deleted file mode 100644 index 55cb222ce477..000000000000 --- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ /dev/null @@ -1,243 +0,0 @@ -//===-- ThreadGDBRemote.cpp -------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - - -#include "ThreadGDBRemote.h" - -#include "lldb/Core/ArchSpec.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Core/State.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/Breakpoint/Watchpoint.h" - -#include "ProcessGDBRemote.h" -#include "ProcessGDBRemoteLog.h" -#include "Utility/StringExtractorGDBRemote.h" - -using namespace lldb; -using namespace lldb_private; - -//---------------------------------------------------------------------- -// Thread Registers -//---------------------------------------------------------------------- - -ThreadGDBRemote::ThreadGDBRemote (const ProcessSP &process_sp, lldb::tid_t tid) : - Thread(process_sp, tid), - m_thread_name (), - m_dispatch_queue_name (), - m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS) -{ - ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", - this, - process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID, - GetID()); -} - -ThreadGDBRemote::~ThreadGDBRemote () -{ - ProcessSP process_sp(GetProcess()); - ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::~ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", - this, - process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID, - GetID()); - DestroyThread(); -} - -const char * -ThreadGDBRemote::GetName () -{ - if (m_thread_name.empty()) - return NULL; - return m_thread_name.c_str(); -} - - -const char * -ThreadGDBRemote::GetQueueName () -{ - // Always re-fetch the dispatch queue name since it can change - - if (m_thread_dispatch_qaddr != 0 || m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS) - { - ProcessSP process_sp (GetProcess()); - if (process_sp) - { - ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get()); - return gdb_process->GetDispatchQueueNameForThread (m_thread_dispatch_qaddr, m_dispatch_queue_name); - } - } - return NULL; -} - -bool -ThreadGDBRemote::WillResume (StateType resume_state) -{ - ClearStackFrames(); - // Call the Thread::WillResume first. If we stop at a signal, the stop info - // class for signal will set the resume signal that we need below. The signal - // stuff obeys the Process::UnixSignal defaults. - Thread::WillResume(resume_state); - - int signo = GetResumeSignal(); - lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (GDBR_LOG_THREAD)); - if (log) - log->Printf ("Resuming thread: %4.4llx with state: %s.", GetID(), StateAsCString(resume_state)); - - ProcessSP process_sp (GetProcess()); - if (process_sp) - { - ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get()); - switch (resume_state) - { - case eStateSuspended: - case eStateStopped: - // Don't append anything for threads that should stay stopped. - break; - - case eStateRunning: - if (gdb_process->GetUnixSignals().SignalIsValid (signo)) - gdb_process->m_continue_C_tids.push_back(std::make_pair(GetID(), signo)); - else - gdb_process->m_continue_c_tids.push_back(GetID()); - break; - - case eStateStepping: - if (gdb_process->GetUnixSignals().SignalIsValid (signo)) - gdb_process->m_continue_S_tids.push_back(std::make_pair(GetID(), signo)); - else - gdb_process->m_continue_s_tids.push_back(GetID()); - break; - - default: - break; - } - return true; - } - return false; -} - -void -ThreadGDBRemote::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 GDBRemoteRegisterContext - // 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); -} - -void -ThreadGDBRemote::ClearStackFrames () -{ - Unwind *unwinder = GetUnwinder (); - if (unwinder) - unwinder->Clear(); - Thread::ClearStackFrames(); -} - - -bool -ThreadGDBRemote::ThreadIDIsValid (lldb::tid_t thread) -{ - return thread != 0; -} - -void -ThreadGDBRemote::Dump(Log *log, uint32_t index) -{ -} - - -bool -ThreadGDBRemote::ShouldStop (bool &step_more) -{ - return true; -} -lldb::RegisterContextSP -ThreadGDBRemote::GetRegisterContext () -{ - if (m_reg_context_sp.get() == NULL) - m_reg_context_sp = CreateRegisterContextForFrame (NULL); - return m_reg_context_sp; -} - -lldb::RegisterContextSP -ThreadGDBRemote::CreateRegisterContextForFrame (StackFrame *frame) -{ - lldb::RegisterContextSP reg_ctx_sp; - const bool read_all_registers_at_once = false; - uint32_t concrete_frame_idx = 0; - - if (frame) - concrete_frame_idx = frame->GetConcreteFrameIndex (); - - - if (concrete_frame_idx == 0) - { - ProcessSP process_sp (GetProcess()); - if (process_sp) - { - ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get()); - reg_ctx_sp.reset (new GDBRemoteRegisterContext (*this, concrete_frame_idx, gdb_process->m_register_info, read_all_registers_at_once)); - } - } - else if (m_unwinder_ap.get()) - reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame); - return reg_ctx_sp; -} - -bool -ThreadGDBRemote::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response) -{ - GDBRemoteRegisterContext *gdb_reg_ctx = static_cast<GDBRemoteRegisterContext *>(GetRegisterContext ().get()); - assert (gdb_reg_ctx); - return gdb_reg_ctx->PrivateSetRegisterValue (reg, response); -} - -lldb::StopInfoSP -ThreadGDBRemote::GetPrivateStopReason () -{ - ProcessSP process_sp (GetProcess()); - if (process_sp) - { - const uint32_t process_stop_id = process_sp->GetStopID(); - if (m_thread_stop_reason_stop_id != process_stop_id || - (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid())) - { - // If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason - // for this thread, then m_actual_stop_info_sp will not ever contain - // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false" - // check will never be able to tell us if we have the correct stop info - // for this thread and we will continually send qThreadStopInfo packets - // down to the remote GDB server, so we need to keep our own notion - // of the stop ID that m_actual_stop_info_sp is valid for (even if it - // contains nothing). We use m_thread_stop_reason_stop_id for this below. - m_thread_stop_reason_stop_id = process_stop_id; - m_actual_stop_info_sp.reset(); - - StringExtractorGDBRemote stop_packet; - ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get()); - if (gdb_process->GetGDBRemote().GetThreadStopInfo(GetID(), stop_packet)) - gdb_process->SetThreadStopInfo (stop_packet); - } - } - return m_actual_stop_info_sp; -} - - diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h deleted file mode 100644 index 3eb6295f1f4b..000000000000 --- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h +++ /dev/null @@ -1,110 +0,0 @@ -//===-- ThreadGDBRemote.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_ThreadGDBRemote_h_ -#define liblldb_ThreadGDBRemote_h_ - -#include <string> - -#include "lldb/Target/Process.h" -#include "lldb/Target/Thread.h" - -class StringExtractor; -class ProcessGDBRemote; - -class ThreadGDBRemote : public lldb_private::Thread -{ -public: - ThreadGDBRemote (const lldb::ProcessSP &process_sp, lldb::tid_t tid); - - virtual - ~ThreadGDBRemote (); - - virtual bool - WillResume (lldb::StateType resume_state); - - virtual void - RefreshStateAfterStop(); - - virtual const char * - GetName (); - - virtual const char * - GetQueueName (); - - virtual lldb::RegisterContextSP - GetRegisterContext (); - - virtual lldb::RegisterContextSP - CreateRegisterContextForFrame (lldb_private::StackFrame *frame); - - virtual void - ClearStackFrames (); - - 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; - } - -protected: - - friend class ProcessGDBRemote; - - bool - PrivateSetRegisterValue (uint32_t reg, - StringExtractor &response); - - //------------------------------------------------------------------ - // Member variables. - //------------------------------------------------------------------ - std::string m_thread_name; - std::string m_dispatch_queue_name; - lldb::addr_t m_thread_dispatch_qaddr; - //------------------------------------------------------------------ - // Member variables. - //------------------------------------------------------------------ - - void - SetStopInfoFromPacket (StringExtractor &stop_packet, uint32_t stop_id); - - virtual lldb::StopInfoSP - GetPrivateStopReason (); - - -}; - -#endif // liblldb_ThreadGDBRemote_h_ diff --git a/lldb/source/Plugins/Process/mach-core/Makefile b/lldb/source/Plugins/Process/mach-core/Makefile deleted file mode 100644 index 6db849872267..000000000000 --- a/lldb/source/Plugins/Process/mach-core/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -##===- source/Plugins/Process/mach-core/Makefile -----------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLDB_LEVEL := ../../../.. -LIBRARYNAME := lldbPluginProcessMachCore -BUILD_ARCHIVE = 1 - -include $(LLDB_LEVEL)/Makefile diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp deleted file mode 100644 index abff31688d02..000000000000 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ /dev/null @@ -1,455 +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. -// -//===----------------------------------------------------------------------===// - -// C Includes -#include <errno.h> -#include <stdlib.h> - -// C++ Includes -#include "llvm/Support/MachO.h" -#include "llvm/Support/MathExtras.h" - -// Other libraries and framework includes -#include "lldb/Core/Debugger.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" -#include "lldb/Host/Host.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/Thread.h" - -// Project includes -#include "ProcessMachCore.h" -#include "ThreadMachCore.h" -#include "StopInfoMachException.h" - -#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h" -#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h" - -using namespace lldb; -using namespace lldb_private; - -const char * -ProcessMachCore::GetPluginNameStatic() -{ - return "mach-o-core"; -} - -const char * -ProcessMachCore::GetPluginDescriptionStatic() -{ - return "Mach-O core file debugging plug-in."; -} - -void -ProcessMachCore::Terminate() -{ - PluginManager::UnregisterPlugin (ProcessMachCore::CreateInstance); -} - - -lldb::ProcessSP -ProcessMachCore::CreateInstance (Target &target, Listener &listener, const FileSpec *crash_file) -{ - lldb::ProcessSP process_sp; - if (crash_file) - process_sp.reset(new ProcessMachCore (target, listener, *crash_file)); - return process_sp; -} - -bool -ProcessMachCore::CanDebug(Target &target, 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 && m_core_file.Exists()) - { - ModuleSpec core_module_spec(m_core_file, target.GetArchitecture()); - Error error (ModuleList::GetSharedModule (core_module_spec, - m_core_module_sp, - NULL, - NULL, - NULL)); - - if (m_core_module_sp) - { - const llvm::Triple &triple_ref = m_core_module_sp->GetArchitecture().GetTriple(); - if (triple_ref.getOS() == llvm::Triple::Darwin && - triple_ref.getVendor() == llvm::Triple::Apple) - { - ObjectFile *core_objfile = m_core_module_sp->GetObjectFile(); - if (core_objfile && core_objfile->GetType() == ObjectFile::eTypeCoreFile) - return true; - } - } - } - return false; -} - -//---------------------------------------------------------------------- -// ProcessMachCore constructor -//---------------------------------------------------------------------- -ProcessMachCore::ProcessMachCore(Target& target, Listener &listener, const FileSpec &core_file) : - Process (target, listener), - m_core_aranges (), - m_core_module_sp (), - m_core_file (core_file), - m_dyld_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 -//---------------------------------------------------------------------- -const char * -ProcessMachCore::GetPluginName() -{ - return "Process debugging plug-in that loads mach-o core files."; -} - -const char * -ProcessMachCore::GetShortPluginName() -{ - return GetPluginNameStatic(); -} - -uint32_t -ProcessMachCore::GetPluginVersion() -{ - return 1; -} - -bool -ProcessMachCore::GetDynamicLoaderAddress (lldb::addr_t addr) -{ - llvm::MachO::mach_header header; - Error error; - if (DoReadMemory (addr, &header, sizeof(header), error) != sizeof(header)) - return false; - if (header.magic == llvm::MachO::HeaderMagic32Swapped || - header.magic == llvm::MachO::HeaderMagic64Swapped) - { - 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.16llx: magic = 0x%8.8x, file_type= %u\n", vaddr, header.magic, header.filetype); - if (header.magic == llvm::MachO::HeaderMagic32 || - header.magic == llvm::MachO::HeaderMagic64) - { - // 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::HeaderFileTypeDynamicLinkEditor: - //printf("0x%16.16llx: file_type = MH_DYLINKER\n", vaddr); - // Address of dyld "struct mach_header" in the core file - m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic(); - m_dyld_addr = addr; - return true; - - case llvm::MachO::HeaderFileTypeExecutable: - //printf("0x%16.16llx: 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::HeaderFlagBitIsDynamicLinkObject) == 0) - { - m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic(); - // Address of the mach kernel "struct mach_header" in the core file. - m_dyld_addr = addr; - return true; - } - break; - } - } - return false; -} - -//---------------------------------------------------------------------- -// Process Control -//---------------------------------------------------------------------- -Error -ProcessMachCore::DoLoadCore () -{ - Error 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; - } - 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; - } - - 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.16llx - 0x%16.16llx), 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); - } - - // After we have added this section to our m_core_aranges map, - // we can check the start of the section to see if it might - // contain dyld for user space apps, or the mach kernel file - // for kernel cores. - if (m_dyld_addr == LLDB_INVALID_ADDRESS) - GetDynamicLoaderAddress (section_vm_addr); - } - } - if (!ranges_are_sorted) - { - m_core_aranges.Sort(); - } - - // 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.SetTriple ("i386", m_target.GetPlatform().get()); - } - if (arch.IsValid()) - m_target.SetArchitecture(arch); - - if (m_dyld_addr == LLDB_INVALID_ADDRESS) - { - // Check the magic kernel address for the mach image header address in case - // it is there. - if (arch.GetAddressByteSize() == 8) - { - Error header_addr_error; - addr_t header_addr = ReadPointerFromMemory (0xffffff8000002010ull, header_addr_error); - if (header_addr != LLDB_INVALID_ADDRESS) - GetDynamicLoaderAddress (header_addr); - } - -// if (m_dyld_addr == LLDB_INVALID_ADDRESS) -// { -// // We haven't found our dyld or mach_kernel yet, -// // so we need to exhaustively look -// const size_t num_core_aranges = m_core_aranges.GetSize(); -// bool done = false; -// for (size_t i=0; !done && i<num_core_aranges; ++i) -// { -// const addr_t start_vaddr = m_core_aranges.GetEntryRef(i).GetRangeBase(); -// const addr_t end_vaddr = m_core_aranges.GetEntryRef(i).GetRangeEnd(); -// // printf("core_arange[%u] [0x%16.16llx - 0x%16.16llx)\n", (uint32_t)i, start_vaddr, end_vaddr); -// -// for (addr_t vaddr = start_vaddr; !done && start_vaddr < end_vaddr; vaddr += 0x1000) -// { -// done = GetDynamicLoaderAddress (vaddr); -// } -// } -// } - } - - return error; -} - -lldb_private::DynamicLoader * -ProcessMachCore::GetDynamicLoader () -{ - if (m_dyld_ap.get() == NULL) - m_dyld_ap.reset (DynamicLoader::FindPlugin(this, m_dyld_plugin_name.empty() ? NULL : m_dyld_plugin_name.c_str())); - 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 (shared_from_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)); - } - 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); -} - -Error -ProcessMachCore::DoDestroy () -{ - return Error(); -} - -//------------------------------------------------------------------ -// Process Queries -//------------------------------------------------------------------ - -bool -ProcessMachCore::IsAlive () -{ - return true; -} - -//------------------------------------------------------------------ -// Process Memory -//------------------------------------------------------------------ -size_t -ProcessMachCore::ReadMemory (addr_t addr, void *buf, size_t size, Error &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, Error &error) -{ - ObjectFile *core_objfile = m_core_module_sp->GetObjectFile(); - - if (core_objfile) - { - const VMRangeToFileOffset::Entry *core_memory_entry = m_core_aranges.FindEntryThatContains (addr); - if (core_memory_entry) - { - const addr_t offset = addr - core_memory_entry->GetRangeBase(); - const addr_t bytes_left = core_memory_entry->GetRangeEnd() - addr; - size_t bytes_to_read = size; - if (bytes_to_read > bytes_left) - bytes_to_read = bytes_left; - return core_objfile->CopyData (core_memory_entry->data.GetRangeBase() + offset, bytes_to_read, buf); - } - else - { - error.SetErrorStringWithFormat ("core file does not contain 0x%llx", addr); - } - } - return 0; -} - -void -ProcessMachCore::Clear() -{ - m_thread_list.Clear(); -} - -void -ProcessMachCore::Initialize() -{ - static bool g_initialized = false; - - if (g_initialized == false) - { - g_initialized = true; - PluginManager::RegisterPlugin (GetPluginNameStatic(), - GetPluginDescriptionStatic(), - CreateInstance); - } -} - -addr_t -ProcessMachCore::GetImageInfoAddress() -{ - return m_dyld_addr; -} - - diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h deleted file mode 100644 index e20276f1da27..000000000000 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h +++ /dev/null @@ -1,147 +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_ - -// C Includes - -// C++ Includes -#include <list> -#include <vector> - -// Other libraries and framework includes -#include "lldb/Core/Error.h" -#include "lldb/Target/Process.h" - -class ThreadKDP; - -class ProcessMachCore : public lldb_private::Process -{ -public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - static lldb::ProcessSP - CreateInstance (lldb_private::Target& target, - lldb_private::Listener &listener, - const lldb_private::FileSpec *crash_file_path); - - static void - Initialize(); - - static void - Terminate(); - - static const char * - GetPluginNameStatic(); - - static const char * - GetPluginDescriptionStatic(); - - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - ProcessMachCore(lldb_private::Target& target, - lldb_private::Listener &listener, - const lldb_private::FileSpec &core_file); - - virtual - ~ProcessMachCore(); - - //------------------------------------------------------------------ - // Check if a given Process - //------------------------------------------------------------------ - virtual bool - CanDebug (lldb_private::Target &target, - bool plugin_specified_by_name); - - //------------------------------------------------------------------ - // Creating a new process, or attaching to an existing one - //------------------------------------------------------------------ - virtual lldb_private::Error - DoLoadCore (); - - virtual lldb_private::DynamicLoader * - GetDynamicLoader (); - - //------------------------------------------------------------------ - // PluginInterface protocol - //------------------------------------------------------------------ - virtual const char * - GetPluginName(); - - virtual const char * - GetShortPluginName(); - - virtual uint32_t - GetPluginVersion(); - - //------------------------------------------------------------------ - // Process Control - //------------------------------------------------------------------ - virtual lldb_private::Error - DoDestroy (); - - virtual void - RefreshStateAfterStop(); - - //------------------------------------------------------------------ - // Process Queries - //------------------------------------------------------------------ - virtual bool - IsAlive (); - - //------------------------------------------------------------------ - // Process Memory - //------------------------------------------------------------------ - virtual size_t - ReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error); - - virtual size_t - DoReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error); - - virtual lldb::addr_t - GetImageInfoAddress (); - -protected: - friend class ThreadMachCore; - - void - Clear ( ); - - virtual bool - UpdateThreadList (lldb_private::ThreadList &old_thread_list, - lldb_private::ThreadList &new_thread_list); - - lldb_private::ObjectFile * - GetCoreObjectFile () - { - return m_core_module_sp->GetObjectFile(); - } -private: - bool - GetDynamicLoaderAddress (lldb::addr_t addr); - - //------------------------------------------------------------------ - // For ProcessMachCore only - //------------------------------------------------------------------ - typedef lldb_private::Range<uint32_t, uint32_t> FileRange; - typedef lldb_private::RangeDataArray<lldb::addr_t, lldb::addr_t, FileRange, 1> VMRangeToFileOffset; - - VMRangeToFileOffset m_core_aranges; - lldb::ModuleSP m_core_module_sp; - lldb_private::FileSpec m_core_file; - lldb::addr_t m_dyld_addr; - std::string m_dyld_plugin_name; - DISALLOW_COPY_AND_ASSIGN (ProcessMachCore); - -}; - -#endif // liblldb_ProcessMachCore_h_ diff --git a/lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp deleted file mode 100644 index c0eefe125b17..000000000000 --- a/lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp +++ /dev/null @@ -1,159 +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 "llvm/Support/MachO.h" - -#include "lldb/Core/ArchSpec.h" -#include "lldb/Core/DataExtractor.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Core/State.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/Breakpoint/Watchpoint.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 (const lldb::ProcessSP &process_sp, lldb::tid_t tid) : - Thread(process_sp, 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 NULL; - 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); -} - -void -ThreadMachCore::ClearStackFrames () -{ - Unwind *unwinder = GetUnwinder (); - if (unwinder) - unwinder->Clear(); - Thread::ClearStackFrames(); -} - - -bool -ThreadMachCore::ThreadIDIsValid (lldb::tid_t thread) -{ - return thread != 0; -} - -lldb::RegisterContextSP -ThreadMachCore::GetRegisterContext () -{ - if (m_reg_context_sp.get() == NULL) - m_reg_context_sp = CreateRegisterContextForFrame (NULL); - 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 if (m_unwinder_ap.get()) - { - reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame); - } - return reg_ctx_sp; -} - -lldb::StopInfoSP -ThreadMachCore::GetPrivateStopReason () -{ - ProcessSP process_sp (GetProcess()); - - if (process_sp) - { - const uint32_t process_stop_id = process_sp->GetStopID(); - if (m_thread_stop_reason_stop_id != process_stop_id || - (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid())) - { - // TODO: can we query the initial state of the thread here? - // For now I am just going to pretend that a SIGSTOP happened. - - SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP)); - - // If GetKDPProcess().SetThreadStopInfo() doesn't find a stop reason - // for this thread, then m_actual_stop_info_sp will not ever contain - // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false" - // check will never be able to tell us if we have the correct stop info - // for this thread and we will continually send qThreadStopInfo packets - // down to the remote KDP server, so we need to keep our own notion - // of the stop ID that m_actual_stop_info_sp is valid for (even if it - // contains nothing). We use m_thread_stop_reason_stop_id for this below. - // m_thread_stop_reason_stop_id = process_stop_id; - // m_actual_stop_info_sp.reset(); - - } - } - return m_actual_stop_info_sp; -} - - diff --git a/lldb/source/Plugins/Process/mach-core/ThreadMachCore.h b/lldb/source/Plugins/Process/mach-core/ThreadMachCore.h deleted file mode 100644 index 497620cdb0ff..000000000000 --- a/lldb/source/Plugins/Process/mach-core/ThreadMachCore.h +++ /dev/null @@ -1,92 +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 (const lldb::ProcessSP &process_sp, - lldb::tid_t tid); - - virtual - ~ThreadMachCore (); - - virtual void - RefreshStateAfterStop(); - - virtual const char * - GetName (); - - virtual lldb::RegisterContextSP - GetRegisterContext (); - - virtual lldb::RegisterContextSP - CreateRegisterContextForFrame (lldb_private::StackFrame *frame); - - virtual void - ClearStackFrames (); - - 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; - } - -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; - //------------------------------------------------------------------ - // Member variables. - //------------------------------------------------------------------ - - virtual lldb::StopInfoSP - GetPrivateStopReason (); -}; - -#endif // liblldb_ThreadMachCore_h_ |
