diff options
Diffstat (limited to 'lldb/tools/debugserver/source/MacOSX/i386')
| -rw-r--r-- | lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp | 58 | ||||
| -rw-r--r-- | lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h | 11 |
2 files changed, 68 insertions, 1 deletions
diff --git a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp index f76ec0da021..9c708f31359 100644 --- a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp +++ b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp @@ -515,6 +515,10 @@ DNBArchImplI386::GetEXCState(bool force) kern_return_t DNBArchImplI386::SetGPRState() { + kern_return_t kret = ::thread_abort_safely(m_thread->MachPortNumber()); + DNBLogThreadedIf (LOG_THREAD, "thread = 0x%4.4x calling thread_abort_safely (tid) => %u (SetGPRState() for stop_count = %u)", m_thread->MachPortNumber(), kret, m_thread->Process()->StopCount()); + + m_state.SetError(e_regSetGPR, Write, ::thread_set_state(m_thread->MachPortNumber(), __i386_THREAD_STATE, (thread_state_t)&m_state.context.gpr, e_regSetWordSizeGPR)); return m_state.GetError(e_regSetGPR, Write); } @@ -1793,6 +1797,60 @@ DNBArchImplI386::SetRegisterContext (const void *buf, nub_size_t buf_len) } +uint32_t +DNBArchImplI386::SaveRegisterState () +{ + kern_return_t kret = ::thread_abort_safely(m_thread->MachPortNumber()); + DNBLogThreadedIf (LOG_THREAD, "thread = 0x%4.4x calling thread_abort_safely (tid) => %u (SetGPRState() for stop_count = %u)", m_thread->MachPortNumber(), kret, m_thread->Process()->StopCount()); + + bool force = true; + + if ((kret = GetGPRState(force)) != KERN_SUCCESS) + { + DNBLogThreadedIf (LOG_THREAD, "DNBArchImplI386::SaveRegisterState () error: GPR regs failed to read: %u ", kret); + } + else if ((kret = GetFPUState(force)) != KERN_SUCCESS) + { + DNBLogThreadedIf (LOG_THREAD, "DNBArchImplI386::SaveRegisterState () error: %s regs failed to read: %u", CPUHasAVX() ? "AVX" : "FPU", kret); + } + else + { + const uint32_t save_id = GetNextRegisterStateSaveID (); + m_saved_register_states[save_id] = m_state.context; + return save_id; + } + return 0; +} +bool +DNBArchImplI386::RestoreRegisterState (uint32_t save_id) +{ + SaveRegiterStates::iterator pos = m_saved_register_states.find(save_id); + if (pos != m_saved_register_states.end()) + { + m_state.context.gpr = pos->second.gpr; + m_state.context.fpu = pos->second.fpu; + m_state.context.exc = pos->second.exc; + m_state.SetError(e_regSetGPR, Read, 0); + m_state.SetError(e_regSetFPU, Read, 0); + m_state.SetError(e_regSetEXC, Read, 0); + kern_return_t kret; + bool success = true; + if ((kret = SetGPRState()) != KERN_SUCCESS) + { + DNBLogThreadedIf (LOG_THREAD, "DNBArchImplI386::RestoreRegisterState (save_id = %u) error: GPR regs failed to write: %u", save_id, kret); + success = false; + } + else if ((kret = SetFPUState()) != KERN_SUCCESS) + { + DNBLogThreadedIf (LOG_THREAD, "DNBArchImplI386::RestoreRegisterState (save_id = %u) error: %s regs failed to write: %u", save_id, CPUHasAVX() ? "AVX" : "FPU", kret); + success = false; + } + m_saved_register_states.erase(pos); + return success; + } + return false; +} + kern_return_t DNBArchImplI386::GetRegisterState(int set, bool force) diff --git a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h index 6b526f35914..ae9ef4980fc 100644 --- a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h +++ b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h @@ -20,16 +20,20 @@ #include "../HasAVX.h" #include "MachRegisterStatesI386.h" +#include <map> + class MachThread; class DNBArchImplI386 : public DNBArchProtocol { public: DNBArchImplI386(MachThread *thread) : + DNBArchProtocol(), m_thread(thread), m_state(), m_2pc_dbg_checkpoint(), - m_2pc_trans_state(Trans_Done) + m_2pc_trans_state(Trans_Done), + m_saved_register_states() { } virtual ~DNBArchImplI386() @@ -42,6 +46,9 @@ public: virtual bool SetRegisterValue(int set, int reg, const DNBRegisterValue *value); virtual nub_size_t GetRegisterContext (void *buf, nub_size_t buf_len); virtual nub_size_t SetRegisterContext (const void *buf, nub_size_t buf_len); + virtual uint32_t SaveRegisterState (); + virtual bool RestoreRegisterState (uint32_t save_id); + virtual kern_return_t GetRegisterState (int set, bool force); virtual kern_return_t SetRegisterState (int set); virtual bool RegisterSetStateIsValid (int set) const; @@ -240,6 +247,8 @@ protected: State m_state; DBG m_2pc_dbg_checkpoint; uint32_t m_2pc_trans_state; // Is transaction of DBG state change: Pedning (0), Done (1), or Rolled Back (2)? + typedef std::map<uint32_t, Context> SaveRegiterStates; + SaveRegiterStates m_saved_register_states; }; #endif // #if defined (__i386__) || defined (__x86_64__) |

