diff options
author | Tamas Berghammer <tberghammer@google.com> | 2015-05-26 11:58:52 +0000 |
---|---|---|
committer | Tamas Berghammer <tberghammer@google.com> | 2015-05-26 11:58:52 +0000 |
commit | 068f8a7e2d7ece12cc00726bb2e6df180b217848 (patch) | |
tree | 3ac16e6c32a2a44799ad79fa0f141f30c990c66a /lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp | |
parent | b2b901c607ae3149b6d3a0c53a45f22e3542fb04 (diff) | |
download | bcm5719-llvm-068f8a7e2d7ece12cc00726bb2e6df180b217848.tar.gz bcm5719-llvm-068f8a7e2d7ece12cc00726bb2e6df180b217848.zip |
Move register reading form NativeProcessLinux to NativeRegisterContextLinux*
This change reorganize the register read/write code inside lldb-server on Linux
with moving the architecture independent code into a new class called
NativeRegisterContextLinux and all of the architecture dependent code into the
appropriate NativeRegisterContextLinux_* class. As part of it the compilation of
the architecture specific register contexts are only compiled on the specific
architecture because they can't be used in other cases.
The purpose of this change is to remove a lot of duplicated code from the different
register contexts and to remove the architecture dependent codes from the global
NativeProcessLinux class.
Differential revision: http://reviews.llvm.org/D9935
llvm-svn: 238196
Diffstat (limited to 'lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp')
-rw-r--r-- | lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp | 730 |
1 files changed, 67 insertions, 663 deletions
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp index 048819c904f..325fdde029d 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -61,11 +61,6 @@ #include <sys/user.h> #include <sys/wait.h> -#if defined (__arm64__) || defined (__aarch64__) -// NT_PRSTATUS and NT_FPREGSET definition -#include <elf.h> -#endif - #include "lldb/Host/linux/Personality.h" #include "lldb/Host/linux/Ptrace.h" #include "lldb/Host/linux/Signalfd.h" @@ -78,16 +73,6 @@ #define TRAP_HWBKPT 4 #endif -// We disable the tracing of ptrace calls for integration builds to -// avoid the additional indirection and checks. -#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION -#define PTRACE(req, pid, addr, data, data_size, error) \ - PtraceWrapper((req), (pid), (addr), (data), (data_size), (error), #req, __FILE__, __LINE__) -#else -#define PTRACE(req, pid, addr, data, data_size, error) \ - PtraceWrapper((req), (pid), (addr), (data), (data_size), (error)) -#endif - using namespace lldb; using namespace lldb_private; using namespace lldb_private::process_linux; @@ -204,72 +189,6 @@ namespace } } - // Wrapper for ptrace to catch errors and log calls. - // Note that ptrace sets errno on error because -1 can be a valid result (i.e. for PTRACE_PEEK*) - long - PtraceWrapper(int req, lldb::pid_t pid, void *addr, void *data, size_t data_size, Error& error, - const char* reqName, const char* file, int line) - { - long int result; - - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PTRACE)); - - PtraceDisplayBytes(req, data, data_size); - - error.Clear(); - errno = 0; - if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET) - result = ptrace(static_cast<__ptrace_request>(req), static_cast< ::pid_t>(pid), *(unsigned int *)addr, data); - else - result = ptrace(static_cast<__ptrace_request>(req), static_cast< ::pid_t>(pid), addr, data); - - if (result == -1) - error.SetErrorToErrno(); - - if (log) - log->Printf("ptrace(%s, %" PRIu64 ", %p, %p, %zu)=%lX called from file %s line %d", - reqName, pid, addr, data, data_size, result, file, line); - - PtraceDisplayBytes(req, data, data_size); - - if (log && error.GetError() != 0) - { - const char* str; - switch (error.GetError()) - { - case ESRCH: str = "ESRCH"; break; - case EINVAL: str = "EINVAL"; break; - case EBUSY: str = "EBUSY"; break; - case EPERM: str = "EPERM"; break; - default: str = error.AsCString(); - } - log->Printf("ptrace() failed; errno=%d (%s)", error.GetError(), str); - } - - return result; - } - -#ifdef LLDB_CONFIGURATION_BUILDANDINTEGRATION - // Wrapper for ptrace when logging is not required. - // Sets errno to 0 prior to calling ptrace. - long - PtraceWrapper(int req, lldb::pid_t pid, void *addr, void *data, size_t data_size, Error& error) - { - long result = 0; - - error.Clear(); - errno = 0; - if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET) - result = ptrace(static_cast<__ptrace_request>(req), static_cast< ::pid_t>(pid), *(unsigned int *)addr, data); - else - result = ptrace(static_cast<__ptrace_request>(req), static_cast< ::pid_t>(pid), addr, data); - - if (result == -1) - error.SetErrorToErrno(); - return result; - } -#endif - //------------------------------------------------------------------------------ // Static implementations of NativeProcessLinux::ReadMemory and // NativeProcessLinux::WriteMemory. This enables mutual recursion between these @@ -300,7 +219,7 @@ namespace assert(sizeof(data) >= word_size); for (bytes_read = 0; bytes_read < size; bytes_read += remainder) { - data = PTRACE(PTRACE_PEEKDATA, pid, (void*)vm_addr, nullptr, 0, error); + data = NativeProcessLinux::PtraceWrapper(PTRACE_PEEKDATA, pid, (void*)vm_addr, nullptr, 0, error); if (error.Fail()) { if (log) @@ -377,7 +296,7 @@ namespace log->Printf ("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__, (void*)vm_addr, *(const unsigned long*)src, data); - if (PTRACE(PTRACE_POKEDATA, pid, (void*)vm_addr, (void*)data, 0, error)) + if (NativeProcessLinux::PtraceWrapper(PTRACE_POKEDATA, pid, (void*)vm_addr, (void*)data, 0, error)) { if (log) ProcessPOSIXLog::DecNestLevel(); @@ -422,38 +341,9 @@ namespace } //------------------------------------------------------------------------------ - /// @class Operation - /// @brief Represents a NativeProcessLinux 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 NativeProcessLinux 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 - /// NativeProcessLinux must perform via the single virtual function Execute, thus - /// encapsulating the code that needs to run in the privileged context. - class Operation - { - public: - Operation () : m_error() { } - - virtual - ~Operation() {} - - virtual void - Execute (NativeProcessLinux *process) = 0; - - const Error & - GetError () const { return m_error; } - - protected: - Error m_error; - }; - - //------------------------------------------------------------------------------ /// @class ReadOperation /// @brief Implements NativeProcessLinux::ReadMemory. - class ReadOperation : public Operation + class ReadOperation : public NativeProcessLinux::Operation { public: ReadOperation( @@ -487,7 +377,7 @@ namespace //------------------------------------------------------------------------------ /// @class WriteOperation /// @brief Implements NativeProcessLinux::WriteMemory. - class WriteOperation : public Operation + class WriteOperation : public NativeProcessLinux::Operation { public: WriteOperation( @@ -519,463 +409,9 @@ namespace } //------------------------------------------------------------------------------ - /// @class ReadRegOperation - /// @brief Implements NativeProcessLinux::ReadRegisterValue. - class ReadRegOperation : public Operation - { - public: - ReadRegOperation(lldb::tid_t tid, uint32_t offset, const char *reg_name, - RegisterValue &value) - : m_tid(tid), - m_offset(static_cast<uintptr_t> (offset)), - m_reg_name(reg_name), - m_value(value) - { } - - void Execute(NativeProcessLinux *monitor) override; - - private: - lldb::tid_t m_tid; - uintptr_t m_offset; - const char *m_reg_name; - RegisterValue &m_value; - }; - - void - ReadRegOperation::Execute(NativeProcessLinux *monitor) - { -#if defined (__arm64__) || defined (__aarch64__) - if (m_offset > sizeof(struct user_pt_regs)) - { - uintptr_t offset = m_offset - sizeof(struct user_pt_regs); - if (offset > sizeof(struct user_fpsimd_state)) - { - m_error.SetErrorString("invalid offset value"); - return; - } - elf_fpregset_t regs; - int regset = NT_FPREGSET; - struct iovec ioVec; - - ioVec.iov_base = ®s; - ioVec.iov_len = sizeof regs; - PTRACE(PTRACE_GETREGSET, m_tid, ®set, &ioVec, sizeof regs, m_error); - if (m_error.Success()) - { - ArchSpec arch; - if (monitor->GetArchitecture(arch)) - m_value.SetBytes((void *)(((unsigned char *)(®s)) + offset), 16, arch.GetByteOrder()); - else - m_error.SetErrorString("failed to get architecture"); - } - } - else - { - elf_gregset_t regs; - int regset = NT_PRSTATUS; - struct iovec ioVec; - - ioVec.iov_base = ®s; - ioVec.iov_len = sizeof regs; - PTRACE(PTRACE_GETREGSET, m_tid, ®set, &ioVec, sizeof regs, m_error); - if (m_error.Success()) - { - ArchSpec arch; - if (monitor->GetArchitecture(arch)) - m_value.SetBytes((void *)(((unsigned char *)(regs)) + m_offset), 8, arch.GetByteOrder()); - else - m_error.SetErrorString("failed to get architecture"); - } - } -#elif defined (__mips__) - elf_gregset_t regs; - PTRACE(PTRACE_GETREGS, m_tid, NULL, ®s, sizeof regs, m_error); - if (m_error.Success()) - { - lldb_private::ArchSpec arch; - if (monitor->GetArchitecture(arch)) - m_value.SetBytes((void *)(((unsigned char *)(regs)) + m_offset), 8, arch.GetByteOrder()); - else - m_error.SetErrorString("failed to get architecture"); - } -#else - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS)); - - lldb::addr_t data = static_cast<unsigned long>(PTRACE(PTRACE_PEEKUSER, m_tid, (void*)m_offset, nullptr, 0, m_error)); - if (m_error.Success()) - m_value = data; - - if (log) - log->Printf ("NativeProcessLinux::%s() reg %s: 0x%" PRIx64, __FUNCTION__, - m_reg_name, data); -#endif - } - - //------------------------------------------------------------------------------ - /// @class WriteRegOperation - /// @brief Implements NativeProcessLinux::WriteRegisterValue. - class WriteRegOperation : public Operation - { - public: - WriteRegOperation(lldb::tid_t tid, unsigned offset, const char *reg_name, - const RegisterValue &value) - : m_tid(tid), - m_offset(offset), - m_reg_name(reg_name), - m_value(value) - { } - - void Execute(NativeProcessLinux *monitor) override; - - private: - lldb::tid_t m_tid; - uintptr_t m_offset; - const char *m_reg_name; - const RegisterValue &m_value; - }; - - void - WriteRegOperation::Execute(NativeProcessLinux *monitor) - { -#if defined (__arm64__) || defined (__aarch64__) - if (m_offset > sizeof(struct user_pt_regs)) - { - uintptr_t offset = m_offset - sizeof(struct user_pt_regs); - if (offset > sizeof(struct user_fpsimd_state)) - { - m_error.SetErrorString("invalid offset value"); - return; - } - elf_fpregset_t regs; - int regset = NT_FPREGSET; - struct iovec ioVec; - - ioVec.iov_base = ®s; - ioVec.iov_len = sizeof regs; - PTRACE(PTRACE_GETREGSET, m_tid, ®set, &ioVec, sizeof regs, m_error); - if (m_error.Success()) - { - ::memcpy((void *)(((unsigned char *)(®s)) + offset), m_value.GetBytes(), 16); - PTRACE(PTRACE_SETREGSET, m_tid, ®set, &ioVec, sizeof regs, m_error); - } - } - else - { - elf_gregset_t regs; - int regset = NT_PRSTATUS; - struct iovec ioVec; - - ioVec.iov_base = ®s; - ioVec.iov_len = sizeof regs; - PTRACE(PTRACE_GETREGSET, m_tid, ®set, &ioVec, sizeof regs, m_error); - if (m_error.Success()) - { - ::memcpy((void *)(((unsigned char *)(®s)) + m_offset), m_value.GetBytes(), 8); - PTRACE(PTRACE_SETREGSET, m_tid, ®set, &ioVec, sizeof regs, m_error); - } - } -#elif defined (__mips__) - elf_gregset_t regs; - PTRACE(PTRACE_GETREGS, m_tid, NULL, ®s, sizeof regs, m_error); - if (m_error.Success()) - { - ::memcpy((void *)(((unsigned char *)(®s)) + m_offset), m_value.GetBytes(), 8); - PTRACE(PTRACE_SETREGS, m_tid, NULL, ®s, sizeof regs, m_error); - } -#else - void* buf; - Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS)); - - buf = (void*) m_value.GetAsUInt64(); - - if (log) - log->Printf ("NativeProcessLinux::%s() reg %s: %p", __FUNCTION__, m_reg_name, buf); - PTRACE(PTRACE_POKEUSER, m_tid, (void*)m_offset, buf, 0, m_error); -#endif - } - - //------------------------------------------------------------------------------ - /// @class ReadGPROperation - /// @brief Implements NativeProcessLinux::ReadGPR. - class ReadGPROperation : public Operation - { - public: - ReadGPROperation(lldb::tid_t tid, void *buf, size_t buf_size) - : m_tid(tid), m_buf(buf), m_buf_size(buf_size) - { } - - void Execute(NativeProcessLinux *monitor) override; - - private: - lldb::tid_t m_tid; - void *m_buf; - size_t m_buf_size; - }; - - void - ReadGPROperation::Execute(NativeProcessLinux *monitor) - { -#if defined (__arm64__) || defined (__aarch64__) - int regset = NT_PRSTATUS; - struct iovec ioVec; - - ioVec.iov_base = m_buf; - ioVec.iov_len = m_buf_size; - PTRACE(PTRACE_GETREGSET, m_tid, ®set, &ioVec, m_buf_size, m_error); -#else - PTRACE(PTRACE_GETREGS, m_tid, nullptr, m_buf, m_buf_size, m_error); -#endif - } - - //------------------------------------------------------------------------------ - /// @class ReadFPROperation - /// @brief Implements NativeProcessLinux::ReadFPR. - class ReadFPROperation : public Operation - { - public: - ReadFPROperation(lldb::tid_t tid, void *buf, size_t buf_size) - : m_tid(tid), - m_buf(buf), - m_buf_size(buf_size) - { } - - void Execute(NativeProcessLinux *monitor) override; - - private: - lldb::tid_t m_tid; - void *m_buf; - size_t m_buf_size; - }; - - void - ReadFPROperation::Execute(NativeProcessLinux *monitor) - { -#if defined (__arm64__) || defined (__aarch64__) - int regset = NT_FPREGSET; - struct iovec ioVec; - - ioVec.iov_base = m_buf; - ioVec.iov_len = m_buf_size; - PTRACE(PTRACE_GETREGSET, m_tid, ®set, &ioVec, m_buf_size, m_error); -#else - PTRACE(PTRACE_GETFPREGS, m_tid, nullptr, m_buf, m_buf_size, m_error); -#endif - } - - //------------------------------------------------------------------------------ - /// @class ReadDBGROperation - /// @brief Implements NativeProcessLinux::ReadHardwareDebugInfo. - class ReadDBGROperation : public Operation - { - public: - ReadDBGROperation(lldb::tid_t tid, unsigned int &count_wp, unsigned int &count_bp) - : m_tid(tid), - m_count_wp(count_wp), - m_count_bp(count_bp) - { } - - void Execute(NativeProcessLinux *monitor) override; - - private: - lldb::tid_t m_tid; - unsigned int &m_count_wp; - unsigned int &m_count_bp; - }; - - void - ReadDBGROperation::Execute(NativeProcessLinux *monitor) - { -#if defined (__arm64__) || defined (__aarch64__) - int regset = NT_ARM_HW_WATCH; - struct iovec ioVec; - struct user_hwdebug_state dreg_state; - - ioVec.iov_base = &dreg_state; - ioVec.iov_len = sizeof (dreg_state); - - PTRACE(PTRACE_GETREGSET, m_tid, ®set, &ioVec, ioVec.iov_len, m_error); - - m_count_wp = dreg_state.dbg_info & 0xff; - regset = NT_ARM_HW_BREAK; - - PTRACE(PTRACE_GETREGSET, m_tid, ®set, &ioVec, ioVec.iov_len, m_error); - m_count_bp = dreg_state.dbg_info & 0xff; -#endif - } - - - //------------------------------------------------------------------------------ - /// @class ReadRegisterSetOperation - /// @brief Implements NativeProcessLinux::ReadRegisterSet. - class ReadRegisterSetOperation : public Operation - { - public: - ReadRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset) - : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset) - { } - - void Execute(NativeProcessLinux *monitor) override; - - private: - lldb::tid_t m_tid; - void *m_buf; - size_t m_buf_size; - const unsigned int m_regset; - }; - - void - ReadRegisterSetOperation::Execute(NativeProcessLinux *monitor) - { - PTRACE(PTRACE_GETREGSET, m_tid, (void *)&m_regset, m_buf, m_buf_size, m_error); - } - - //------------------------------------------------------------------------------ - /// @class WriteGPROperation - /// @brief Implements NativeProcessLinux::WriteGPR. - class WriteGPROperation : public Operation - { - public: - WriteGPROperation(lldb::tid_t tid, void *buf, size_t buf_size) - : m_tid(tid), m_buf(buf), m_buf_size(buf_size) - { } - - void Execute(NativeProcessLinux *monitor) override; - - private: - lldb::tid_t m_tid; - void *m_buf; - size_t m_buf_size; - }; - - void - WriteGPROperation::Execute(NativeProcessLinux *monitor) - { -#if defined (__arm64__) || defined (__aarch64__) - int regset = NT_PRSTATUS; - struct iovec ioVec; - - ioVec.iov_base = m_buf; - ioVec.iov_len = m_buf_size; - PTRACE(PTRACE_SETREGSET, m_tid, ®set, &ioVec, m_buf_size, m_error); -#else - PTRACE(PTRACE_SETREGS, m_tid, NULL, m_buf, m_buf_size, m_error); -#endif - } - - //------------------------------------------------------------------------------ - /// @class WriteFPROperation - /// @brief Implements NativeProcessLinux::WriteFPR. - class WriteFPROperation : public Operation - { - public: - WriteFPROperation(lldb::tid_t tid, void *buf, size_t buf_size) - : m_tid(tid), m_buf(buf), m_buf_size(buf_size) - { } - - void Execute(NativeProcessLinux *monitor) override; - - private: - lldb::tid_t m_tid; - void *m_buf; - size_t m_buf_size; - }; - - void - WriteFPROperation::Execute(NativeProcessLinux *monitor) - { -#if defined (__arm64__) || defined (__aarch64__) - int regset = NT_FPREGSET; - struct iovec ioVec; - - ioVec.iov_base = m_buf; - ioVec.iov_len = m_buf_size; - PTRACE(PTRACE_SETREGSET, m_tid, ®set, &ioVec, m_buf_size, m_error); -#else - PTRACE(PTRACE_SETFPREGS, m_tid, NULL, m_buf, m_buf_size, m_error); -#endif - } - - //------------------------------------------------------------------------------ - /// @class WriteDBGROperation - /// @brief Implements NativeProcessLinux::WriteHardwareDebugRegs. - class WriteDBGROperation : public Operation - { - public: - WriteDBGROperation(lldb::tid_t tid, lldb::addr_t *addr_buf, - uint32_t *cntrl_buf, int type, int count) - : m_tid(tid), - m_address(addr_buf), - m_control(cntrl_buf), - m_type(type), - m_count(count) - { } - - void Execute(NativeProcessLinux *monitor) override; - - private: - lldb::tid_t m_tid; - lldb::addr_t * m_address; - uint32_t * m_control; - int m_type; - int m_count; - }; - - void - WriteDBGROperation::Execute(NativeProcessLinux *monitor) - { -#if defined (__arm64__) || defined (__aarch64__) - struct iovec ioVec; - struct user_hwdebug_state dreg_state; - - memset (&dreg_state, 0, sizeof (dreg_state)); - ioVec.iov_base = &dreg_state; - ioVec.iov_len = sizeof (dreg_state); - - if (m_type == 0) - m_type = NT_ARM_HW_WATCH; - else - m_type = NT_ARM_HW_BREAK; - - for (int i = 0; i < m_count; i++) - { - dreg_state.dbg_regs[i].addr = m_address[i]; - dreg_state.dbg_regs[i].ctrl = m_control[i]; - } - - PTRACE(PTRACE_SETREGSET, m_tid, &m_type, &ioVec, ioVec.iov_len, m_error); -#endif - } - - - //------------------------------------------------------------------------------ - /// @class WriteRegisterSetOperation - /// @brief Implements NativeProcessLinux::WriteRegisterSet. - class WriteRegisterSetOperation : public Operation - { - public: - WriteRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset) - : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset) - { } - - void Execute(NativeProcessLinux *monitor) override; - - private: - lldb::tid_t m_tid; - void *m_buf; - size_t m_buf_size; - const unsigned int m_regset; - }; - - void - WriteRegisterSetOperation::Execute(NativeProcessLinux *monitor) - { - PTRACE(PTRACE_SETREGSET, m_tid, (void *)&m_regset, m_buf, m_buf_size, m_error); - } - - //------------------------------------------------------------------------------ /// @class ResumeOperation /// @brief Implements NativeProcessLinux::Resume. - class ResumeOperation : public Operation + class ResumeOperation : public NativeProcessLinux::Operation { public: ResumeOperation(lldb::tid_t tid, uint32_t signo) : @@ -996,7 +432,7 @@ namespace if (m_signo != LLDB_INVALID_SIGNAL_NUMBER) data = m_signo; - PTRACE(PTRACE_CONT, m_tid, nullptr, (void*)data, 0, m_error); + NativeProcessLinux::PtraceWrapper(PTRACE_CONT, m_tid, nullptr, (void*)data, 0, m_error); if (m_error.Fail()) { Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); @@ -1009,7 +445,7 @@ namespace //------------------------------------------------------------------------------ /// @class SingleStepOperation /// @brief Implements NativeProcessLinux::SingleStep. - class SingleStepOperation : public Operation + class SingleStepOperation : public NativeProcessLinux::Operation { public: SingleStepOperation(lldb::tid_t tid, uint32_t signo) @@ -1030,13 +466,13 @@ namespace if (m_signo != LLDB_INVALID_SIGNAL_NUMBER) data = m_signo; - PTRACE(PTRACE_SINGLESTEP, m_tid, nullptr, (void*)data, 0, m_error); + NativeProcessLinux::PtraceWrapper(PTRACE_SINGLESTEP, m_tid, nullptr, (void*)data, 0, m_error); } //------------------------------------------------------------------------------ /// @class SiginfoOperation /// @brief Implements NativeProcessLinux::GetSignalInfo. - class SiginfoOperation : public Operation + class SiginfoOperation : public NativeProcessLinux::Operation { public: SiginfoOperation(lldb::tid_t tid, void *info) @@ -1052,13 +488,13 @@ namespace void SiginfoOperation::Execute(NativeProcessLinux *monitor) { - PTRACE(PTRACE_GETSIGINFO, m_tid, nullptr, m_info, 0, m_error); + NativeProcessLinux::PtraceWrapper(PTRACE_GETSIGINFO, m_tid, nullptr, m_info, 0, m_error); } //------------------------------------------------------------------------------ /// @class EventMessageOperation /// @brief Implements NativeProcessLinux::GetEventMessage. - class EventMessageOperation : public Operation + class EventMessageOperation : public NativeProcessLinux::Operation { public: EventMessageOperation(lldb::tid_t tid, unsigned long *message) @@ -1074,10 +510,10 @@ namespace void EventMessageOperation::Execute(NativeProcessLinux *monitor) { - PTRACE(PTRACE_GETEVENTMSG, m_tid, nullptr, m_message, 0, m_error); + NativeProcessLinux::PtraceWrapper(PTRACE_GETEVENTMSG, m_tid, nullptr, m_message, 0, m_error); } - class DetachOperation : public Operation + class DetachOperation : public NativeProcessLinux::Operation { public: DetachOperation(lldb::tid_t tid) : m_tid(tid) { } @@ -1091,7 +527,7 @@ namespace void DetachOperation::Execute(NativeProcessLinux *monitor) { - PTRACE(PTRACE_DETACH, m_tid, nullptr, 0, 0, m_error); + NativeProcessLinux::PtraceWrapper(PTRACE_DETACH, m_tid, nullptr, 0, 0, m_error); } } // end of anonymous namespace @@ -1833,7 +1269,7 @@ NativeProcessLinux::Launch(LaunchArgs *args, Error &error) // send log info to parent re: launch status, in place of the log lines removed here. // Start tracing this child that is about to exec. - PTRACE(PTRACE_TRACEME, 0, nullptr, nullptr, 0, error); + NativeProcessLinux::PtraceWrapper(PTRACE_TRACEME, 0, nullptr, nullptr, 0, error); if (error.Fail()) exit(ePtraceFailed); @@ -2070,7 +1506,7 @@ NativeProcessLinux::Attach(lldb::pid_t pid, Error &error) // Attach to the requested process. // An attach will cause the thread to stop with a SIGSTOP. - PTRACE(PTRACE_ATTACH, tid, nullptr, nullptr, 0, error); + NativeProcessLinux::PtraceWrapper(PTRACE_ATTACH, tid, nullptr, nullptr, 0, error); if (error.Fail()) { // No such thread. The thread may have exited. @@ -2162,7 +1598,7 @@ NativeProcessLinux::SetDefaultPtraceOpts(lldb::pid_t pid) ptrace_opts |= PTRACE_O_TRACEEXEC; Error error; - PTRACE(PTRACE_SETOPTIONS, pid, nullptr, (void*)ptrace_opts, 0, error); + NativeProcessLinux::PtraceWrapper(PTRACE_SETOPTIONS, pid, nullptr, (void*)ptrace_opts, 0, error); return error; } @@ -3842,88 +3278,6 @@ NativeProcessLinux::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, } Error -NativeProcessLinux::ReadRegisterValue(lldb::tid_t tid, uint32_t offset, const char* reg_name, - uint32_t size, RegisterValue &value) -{ - ReadRegOperation op(tid, offset, reg_name, value); - m_monitor_up->DoOperation(&op); - return op.GetError(); -} - -Error -NativeProcessLinux::WriteRegisterValue(lldb::tid_t tid, unsigned offset, - const char* reg_name, const RegisterValue &value) -{ - WriteRegOperation op(tid, offset, reg_name, value); - m_monitor_up->DoOperation(&op); - return op.GetError(); -} - -Error -NativeProcessLinux::ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size) -{ - ReadGPROperation op(tid, buf, buf_size); - m_monitor_up->DoOperation(&op); - return op.GetError(); -} - -Error -NativeProcessLinux::ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size) -{ - ReadFPROperation op(tid, buf, buf_size); - m_monitor_up->DoOperation(&op); - return op.GetError(); -} - -Error -NativeProcessLinux::ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset) -{ - ReadRegisterSetOperation op(tid, buf, buf_size, regset); - m_monitor_up->DoOperation(&op); - return op.GetError(); -} - -Error -NativeProcessLinux::ReadHardwareDebugInfo (lldb::tid_t tid, unsigned int &watch_count , unsigned int &break_count) -{ - ReadDBGROperation op(tid, watch_count, break_count); - m_monitor_up->DoOperation(&op); - return op.GetError(); -} - -Error -NativeProcessLinux::WriteHardwareDebugRegs (lldb::tid_t tid, lldb::addr_t *addr_buf, uint32_t *cntrl_buf, int type, int count) -{ - WriteDBGROperation op(tid, addr_buf, cntrl_buf, type, count); - m_monitor_up->DoOperation(&op); - return op.GetError(); -} - -Error -NativeProcessLinux::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size) -{ - WriteGPROperation op(tid, buf, buf_size); - m_monitor_up->DoOperation(&op); - return op.GetError(); -} - -Error -NativeProcessLinux::WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size) -{ - WriteFPROperation op(tid, buf, buf_size); - m_monitor_up->DoOperation(&op); - return op.GetError(); -} - -Error -NativeProcessLinux::WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset) -{ - WriteRegisterSetOperation op(tid, buf, buf_size, regset); - m_monitor_up->DoOperation(&op); - return op.GetError(); -} - -Error NativeProcessLinux::Resume (lldb::tid_t tid, uint32_t signo) { Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); @@ -4431,3 +3785,53 @@ NativeProcessLinux::ThreadWasCreated (lldb::tid_t tid) thread_sp->RequestStop(); } } + +Error +NativeProcessLinux::DoOperation(Operation* op) +{ + m_monitor_up->DoOperation(op); + return op->GetError(); +} + +// Wrapper for ptrace to catch errors and log calls. +// Note that ptrace sets errno on error because -1 can be a valid result (i.e. for PTRACE_PEEK*) +long +NativeProcessLinux::PtraceWrapper(int req, lldb::pid_t pid, void *addr, void *data, size_t data_size, Error& error) +{ + long int result; + + Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PTRACE)); + + PtraceDisplayBytes(req, data, data_size); + + error.Clear(); + errno = 0; + if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET) + result = ptrace(static_cast<__ptrace_request>(req), static_cast< ::pid_t>(pid), *(unsigned int *)addr, data); + else + result = ptrace(static_cast<__ptrace_request>(req), static_cast< ::pid_t>(pid), addr, data); + + if (result == -1) + error.SetErrorToErrno(); + + if (log) + log->Printf("ptrace(%d, %" PRIu64 ", %p, %p, %zu)=%lX", req, pid, addr, data, data_size, result); + + PtraceDisplayBytes(req, data, data_size); + + if (log && error.GetError() != 0) + { + const char* str; + switch (error.GetError()) + { + case ESRCH: str = "ESRCH"; break; + case EINVAL: str = "EINVAL"; break; + case EBUSY: str = "EBUSY"; break; + case EPERM: str = "EPERM"; break; + default: str = error.AsCString(); + } + log->Printf("ptrace() failed; errno=%d (%s)", error.GetError(), str); + } + + return result; +} |