diff options
| author | Peter Collingbourne <peter@pcc.me.uk> | 2011-06-03 20:41:02 +0000 |
|---|---|---|
| committer | Peter Collingbourne <peter@pcc.me.uk> | 2011-06-03 20:41:02 +0000 |
| commit | 10bc01032c9a099d4e5a438cfdd66431c6749dc0 (patch) | |
| tree | bfa12bea5f1d75ea0fbfadde6b6fff1d00a8c02f /lldb/source/Plugins/Process/Linux | |
| parent | 5a6fa540dcc0a86b6e4412ad27bbb0a732bc859b (diff) | |
| download | bcm5719-llvm-10bc01032c9a099d4e5a438cfdd66431c6749dc0.tar.gz bcm5719-llvm-10bc01032c9a099d4e5a438cfdd66431c6749dc0.zip | |
Implement RegisterContextLinux_x86_64::{Read,Write}AllRegisterValues
llvm-svn: 132587
Diffstat (limited to 'lldb/source/Plugins/Process/Linux')
4 files changed, 118 insertions, 1 deletions
diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp index f482c014ee1..af8d7c39c35 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp +++ b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp @@ -334,6 +334,58 @@ ReadFPROperation::Execute(ProcessMonitor *monitor) } //------------------------------------------------------------------------------ +/// @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 @@ -1134,6 +1186,24 @@ ProcessMonitor::ReadFPR(void *buf) } 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; diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.h b/lldb/source/Plugins/Process/Linux/ProcessMonitor.h index 0f2f61c8d58..9b8051b7bd9 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.h +++ b/lldb/source/Plugins/Process/Linux/ProcessMonitor.h @@ -117,6 +117,14 @@ public: 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 diff --git a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.cpp b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.cpp index a3ce221383d..51a2545ec1c 100644 --- a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.cpp +++ b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.cpp @@ -11,6 +11,7 @@ #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" @@ -324,6 +325,8 @@ g_reg_sets[k_num_register_sets] = { gcc_dwarf_fpu_##reg##i, gcc_dwarf_fpu_##reg##i, \ LLDB_INVALID_REGNUM, gdb_fpu_##reg##i, fpu_##reg##i } } +#define REG_CONTEXT_SIZE (sizeof(RegisterContextLinux_x86_64::GPR) + sizeof(RegisterContextLinux_x86_64::FPU)) + static RegisterInfo g_register_infos[k_num_registers] = { @@ -487,6 +490,16 @@ RegisterContextLinux_x86_64::ReadRegister(const RegisterInfo *reg_info, bool RegisterContextLinux_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; } @@ -500,8 +513,17 @@ RegisterContextLinux_x86_64::WriteRegister(const lldb_private::RegisterInfo *reg } bool -RegisterContextLinux_x86_64::WriteAllRegisterValues(const DataBufferSP &data) +RegisterContextLinux_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; } @@ -699,3 +721,17 @@ RegisterContextLinux_x86_64::ReadFPR() ProcessMonitor &monitor = GetMonitor(); return monitor.ReadFPR(&user.i387); } + +bool +RegisterContextLinux_x86_64::WriteGPR() +{ + ProcessMonitor &monitor = GetMonitor(); + return monitor.WriteGPR(&user.regs); +} + +bool +RegisterContextLinux_x86_64::WriteFPR() +{ + ProcessMonitor &monitor = GetMonitor(); + return monitor.WriteFPR(&user.i387); +} diff --git a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h index d288d53685a..5ffef194b7e 100644 --- a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h +++ b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h @@ -151,6 +151,9 @@ private: bool ReadGPR(); bool ReadFPR(); + + bool WriteGPR(); + bool WriteFPR(); }; #endif // #ifndef liblldb_RegisterContextLinux_x86_64_H_ |

