Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions lldb/source/Plugins/ABI/AArch64/ABISysV_arm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,7 @@ static Status PushToLinuxGuardedControlStack(addr_t return_addr,
size_t wrote = thread.GetProcess()->WriteMemory(gcspr_el0, &return_addr,
sizeof(return_addr), error);
if ((wrote != sizeof(return_addr) || error.Fail())) {
// When PrepareTrivialCall fails, the register context is not restored,
// unlike when an expression fails to execute. This is arguably a bug,
// see https://github.com/llvm/llvm-project/issues/124269.
// For now we are handling this here specifically. We can assume this
// write will work as the one to decrement the register did.
reg_ctx->WriteRegisterFromUnsigned(gcspr_el0_info, gcspr_el0 + 8);
// gcspr_el0 will be restored by the ThreadPlan's DoTakedown.
return Status("Failed to write new Guarded Control Stack entry.");
}

Expand Down Expand Up @@ -150,8 +145,6 @@ bool ABISysV_arm64::PrepareTrivialCall(Thread &thread, addr_t sp,
if (args.size() > 8)
return false;

// Do this first, as it's got the most chance of failing (though still very
// low).
if (GetProcessSP()->GetTarget().GetArchitecture().GetTriple().isOSLinux()) {
Status err = PushToLinuxGuardedControlStack(return_addr, reg_ctx, thread);
// If we could not manage the GCS, the expression will certainly fail,
Expand Down
13 changes: 12 additions & 1 deletion lldb/source/Target/ThreadPlanCallFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,20 @@ void ThreadPlanCallFunction::ReportRegisterState(const char *message) {

void ThreadPlanCallFunction::DoTakedown(bool success) {
Log *log = GetLog(LLDBLog::Step);
Thread &thread = GetThread();

if (!m_valid) {
// If ConstructorSetup was succesfull but PrepareTrivialCall was not,
// we will have a saved register state and potentially modified registers.
// Restore those.
if (m_stored_thread_state.register_backup_sp)
if (!thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state))
LLDB_LOGF(
log,
"ThreadPlanCallFunction(%p): Failed to restore register state from "
"invalid plan that contained a saved register state.",
static_cast<void *>(this));

// Don't call DoTakedown if we were never valid to begin with.
LLDB_LOGF(log,
"ThreadPlanCallFunction(%p): Log called on "
Expand All @@ -185,7 +197,6 @@ void ThreadPlanCallFunction::DoTakedown(bool success) {
}

if (!m_takedown_done) {
Thread &thread = GetThread();
if (success) {
SetReturnValue();
}
Expand Down
Loading