<rdar://problem/15172417>
Added two new GDB server packets to debugserver: "QSaveRegisterState" and "QRestoreRegiterState".
"QSaveRegisterState" makes the remote GDB server save all register values and it returns a save identifier as an unsigned integer. This packet can be used prior to running expressions to save all registers.
All registers can them we later restored with "QRestoreRegiterState:SAVEID" what SAVEID is the integer identifier that was returned from the call to QSaveRegisterState.
Cleaned up redundant code in lldb_private::Thread, lldb_private::ThreadPlanCallFunction.
Moved the lldb_private::Thread::RegisterCheckpoint into its own header file and it is now in the lldb_private namespace. Trimmed down the RegisterCheckpoint class to omit stuff that wasn't used (the stack ID).
Added a few new virtual methods to lldb_private::RegisterContext that allow subclasses to efficiently save/restore register states and changed the RegisterContextGDBRemote to take advantage of these new calls.
llvm-svn: 194621
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp
index a43301f..07f5321 100644
--- a/lldb/source/Target/Thread.cpp
+++ b/lldb/source/Target/Thread.cpp
@@ -496,7 +496,19 @@
bool
Thread::CheckpointThreadState (ThreadStateCheckpoint &saved_state)
{
- if (!SaveFrameZeroState(saved_state.register_backup))
+ saved_state.register_backup_sp.reset();
+ lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0));
+ if (frame_sp)
+ {
+ lldb::RegisterCheckpointSP reg_checkpoint_sp(new RegisterCheckpoint(RegisterCheckpoint::Reason::eExpression));
+ if (reg_checkpoint_sp)
+ {
+ lldb::RegisterContextSP reg_ctx_sp (frame_sp->GetRegisterContext());
+ if (reg_ctx_sp && reg_ctx_sp->ReadAllRegisterValues (*reg_checkpoint_sp))
+ saved_state.register_backup_sp = reg_checkpoint_sp;
+ }
+ }
+ if (!saved_state.register_backup_sp)
return false;
saved_state.stop_info_sp = GetStopInfo();
@@ -511,7 +523,26 @@
bool
Thread::RestoreRegisterStateFromCheckpoint (ThreadStateCheckpoint &saved_state)
{
- return RestoreSaveFrameZero(saved_state.register_backup);
+ if (saved_state.register_backup_sp)
+ {
+ lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0));
+ if (frame_sp)
+ {
+ lldb::RegisterContextSP reg_ctx_sp (frame_sp->GetRegisterContext());
+ if (reg_ctx_sp)
+ {
+ bool ret = reg_ctx_sp->WriteAllRegisterValues (*saved_state.register_backup_sp);
+
+ // Clear out all stack frames as our world just changed.
+ ClearStackFrames();
+ reg_ctx_sp->InvalidateIfNeeded(true);
+ if (m_unwinder_ap.get())
+ m_unwinder_ap->Clear();
+ return ret;
+ }
+ }
+ }
+ return false;
}
bool
@@ -1966,48 +1997,6 @@
num_frames_with_source);
}
-bool
-Thread::SaveFrameZeroState (RegisterCheckpoint &checkpoint)
-{
- lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0));
- if (frame_sp)
- {
- checkpoint.SetStackID(frame_sp->GetStackID());
- lldb::RegisterContextSP reg_ctx_sp (frame_sp->GetRegisterContext());
- if (reg_ctx_sp)
- return reg_ctx_sp->ReadAllRegisterValues (checkpoint.GetData());
- }
- return false;
-}
-
-bool
-Thread::RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint)
-{
- return ResetFrameZeroRegisters (checkpoint.GetData());
-}
-
-bool
-Thread::ResetFrameZeroRegisters (lldb::DataBufferSP register_data_sp)
-{
- lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0));
- if (frame_sp)
- {
- lldb::RegisterContextSP reg_ctx_sp (frame_sp->GetRegisterContext());
- if (reg_ctx_sp)
- {
- bool ret = reg_ctx_sp->WriteAllRegisterValues (register_data_sp);
-
- // Clear out all stack frames as our world just changed.
- ClearStackFrames();
- reg_ctx_sp->InvalidateIfNeeded(true);
- if (m_unwinder_ap.get())
- m_unwinder_ap->Clear();
- return ret;
- }
- }
- return false;
-}
-
Unwind *
Thread::GetUnwinder ()
{