Make the unwinding of the stack part of "thread return" work, and add the thread return command.
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@163867 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
index 72c5261..c75b9c9 100644
--- a/source/Target/Thread.cpp
+++ b/source/Target/Thread.cpp
@@ -1273,7 +1273,7 @@
Error
-Thread::ReturnToFrameWithIndex (uint32_t frame_idx, lldb::ValueObjectSP return_value_sp)
+Thread::ReturnFromFrameWithIndex (uint32_t frame_idx, lldb::ValueObjectSP return_value_sp)
{
StackFrameSP frame_sp = GetStackFrameAtIndex (frame_idx);
Error return_error;
@@ -1283,11 +1283,11 @@
return_error.SetErrorStringWithFormat("Could not find frame with index %d in thread 0x%llx.", frame_idx, GetID());
}
- return ReturnToFrame(frame_sp, return_value_sp);
+ return ReturnFromFrame(frame_sp, return_value_sp);
}
Error
-Thread::ReturnToFrame (lldb::StackFrameSP frame_sp, lldb::ValueObjectSP return_value_sp)
+Thread::ReturnFromFrame (lldb::StackFrameSP frame_sp, lldb::ValueObjectSP return_value_sp)
{
Error return_error;
@@ -1298,32 +1298,37 @@
}
Thread *thread = frame_sp->GetThread().get();
+ uint32_t older_frame_idx = frame_sp->GetFrameIndex() + 1;
+ StackFrameSP older_frame_sp = thread->GetStackFrameAtIndex(older_frame_idx);
if (return_value_sp)
{
+ // TODO: coerce the return_value_sp to the type of the function in frame_sp.
+
lldb::ABISP abi = thread->GetProcess()->GetABI();
if (!abi)
{
return_error.SetErrorString("Could not find ABI to set return value.");
}
- return_error = abi->SetReturnValueObject(frame_sp, return_value_sp);
+ return_error = abi->SetReturnValueObject(older_frame_sp, return_value_sp);
if (!return_error.Success())
return return_error;
}
// Now write the return registers for the chosen frame:
- lldb::DataBufferSP register_values_sp;
- frame_sp->GetRegisterContext()->ReadAllRegisterValues (register_values_sp);
- if (thread->ResetFrameZeroRegisters(register_values_sp))
+ // Note, we can't use ReadAllRegisterValues->WriteAllRegisterValues, since the read & write
+ // cook their data
+ bool copy_success = thread->GetStackFrameAtIndex(0)->GetRegisterContext()->CopyFromRegisterContext(older_frame_sp->GetRegisterContext());
+ if (copy_success)
{
thread->DiscardThreadPlans(true);
+ thread->ClearStackFrames();
return return_error;
}
else
{
return_error.SetErrorString("Could not reset register values.");
return return_error;
-
}
}