llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lldb

Author: Jason Molenda (jasonmolenda)

<details>
<summary>Changes</summary>

In RegisterContextUnwind::SavedLocationForRegister we have special logic for 
retrieving the Return Address register when it has the caller's return address 
in it. An example would be the lr register on AArch64.

This register is never retrieved from a newer stack frame because it is 
necessarly overwritten by a normal ABI function call.  We allow frame 0 to 
provide its lr value to get the caller's return address, if it has not been 
overwritten/saved to stack yet.

When a function is interrupted asynchronously by a POSIX signal (sigtramp), or 
a fault handler more generally, the sigtramp/fault handler has the entire 
register context available. In this situation, if the fault handler is frame 0, 
the function that was async interrupted is frame 1 and frame 2's return address 
may still be stored in lr.  We need to get the lr value for frame 1 from the 
fault handler in frame 0, to get the return address for frame 2.

Without this fix, a frameless function that faults in a firmware environment 
(that's where we've seen this issue most commonly) hasn't spilled lr to stack, 
so we need to retrieve it from the fault handler's full-register-context to 
find the caller of the frameless function that faulted.

It's an unsurprising fix, all of the work was finding exactly where in 
RegisterContextUnwind we were only allowing RA register use for frame 0, when 
it should have been frame 0 or above a fault handler function.

rdar://127518945

---
Full diff: https://github.com/llvm/llvm-project/pull/98566.diff


1 Files Affected:

- (modified) lldb/source/Target/RegisterContextUnwind.cpp (+1-1) 


``````````diff
diff --git a/lldb/source/Target/RegisterContextUnwind.cpp 
b/lldb/source/Target/RegisterContextUnwind.cpp
index 95e8abd763d53..bc8081f4e3b31 100644
--- a/lldb/source/Target/RegisterContextUnwind.cpp
+++ b/lldb/source/Target/RegisterContextUnwind.cpp
@@ -1401,7 +1401,7 @@ RegisterContextUnwind::SavedLocationForRegister(
       // it's still live in the actual register. Handle this specially.
 
       if (!have_unwindplan_regloc && return_address_reg.IsValid() &&
-          IsFrameZero()) {
+          BehavesLikeZerothFrame()) {
         if (return_address_reg.GetAsKind(eRegisterKindLLDB) !=
             LLDB_INVALID_REGNUM) {
           lldb_private::UnwindLLDB::RegisterLocation new_regloc;

``````````

</details>


https://github.com/llvm/llvm-project/pull/98566
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to