Fix unwinding for art_quick_generic_jni_trampoline
DELIVER_PENDING_EXCEPTION spills LR which is unused/garbage.
This breaks backtraces when the unwinder tries to follow it.
Add trivial call so that the LR is initialized.
(spills at the start of method are expected and working)
Bug: 187632012
Test: test.py -r --gcstress --all-run -t 1927 -t 178
Change-Id: I151aa7595f9fd90169402187066a04efba5d54c9
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S
index e4fc48d..f5f1274 100644
--- a/runtime/arch/arm/quick_entrypoints_arm.S
+++ b/runtime/arch/arm/quick_entrypoints_arm.S
@@ -1498,6 +1498,7 @@
// Tear down the alloca.
mov sp, r10
+ .cfi_remember_state
.cfi_def_cfa_register sp
// Tear down the callee-save frame. Skip arg registers.
@@ -1509,18 +1510,21 @@
// store into fpr, for when it's a fpr return...
vmov d0, r0, r1
bx lr // ret
- // Undo the unwinding information from above since it doesn't apply below.
- .cfi_def_cfa_register r10
- .cfi_adjust_cfa_offset FRAME_SIZE_SAVE_REFS_AND_ARGS-FRAME_SIZE_SAVE_REFS_ONLY
+ // Undo the unwinding information from above since it doesn't apply below.
+ .cfi_restore_state
+ .cfi_def_cfa r10, FRAME_SIZE_SAVE_REFS_AND_ARGS
.Lexception_in_native:
ldr ip, [rSELF, #THREAD_TOP_QUICK_FRAME_OFFSET]
add ip, ip, #-1 // Remove the GenericJNI tag. ADD/SUB writing directly to SP is UNPREDICTABLE.
mov sp, ip
- .cfi_def_cfa_register sp
+ bl art_deliver_pending_exception
+END art_quick_generic_jni_trampoline
+
+ENTRY art_deliver_pending_exception
# This will create a new save-all frame, required by the runtime.
DELIVER_PENDING_EXCEPTION
-END art_quick_generic_jni_trampoline
+END art_deliver_pending_exception
.extern artQuickToInterpreterBridge
ENTRY art_quick_to_interpreter_bridge
diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S
index 263b30e..022a0e4 100644
--- a/runtime/arch/arm64/quick_entrypoints_arm64.S
+++ b/runtime/arch/arm64/quick_entrypoints_arm64.S
@@ -1874,6 +1874,7 @@
// Tear down the alloca.
mov sp, x28
+ .cfi_remember_state
.cfi_def_cfa_register sp
// Tear down the callee-save frame.
@@ -1884,14 +1885,20 @@
fmov d0, x0
ret
+ // Undo the unwinding information from above since it doesn't apply below.
+ .cfi_restore_state
+ .cfi_def_cfa x28, FRAME_SIZE_SAVE_REFS_AND_ARGS
.Lexception_in_native:
// Move to x1 then sp to please assembler.
ldr x1, [xSELF, # THREAD_TOP_QUICK_FRAME_OFFSET]
add sp, x1, #-1 // Remove the GenericJNI tag.
- .cfi_def_cfa_register sp
+ bl art_deliver_pending_exception
+END art_quick_generic_jni_trampoline
+
+ENTRY art_deliver_pending_exception
# This will create a new save-all frame, required by the runtime.
DELIVER_PENDING_EXCEPTION
-END art_quick_generic_jni_trampoline
+END art_deliver_pending_exception
/*
* Called to bridge from the quick to interpreter ABI. On entry the arguments match those
diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S
index 70441b7..2bf92bb 100644
--- a/runtime/arch/x86/quick_entrypoints_x86.S
+++ b/runtime/arch/x86/quick_entrypoints_x86.S
@@ -1826,9 +1826,9 @@
// Tear down the alloca.
movl %ebp, %esp
+ CFI_REMEMBER_STATE
CFI_DEF_CFA_REGISTER(esp)
-
// Tear down the callee-save frame.
// Remove space for FPR args and EAX
addl LITERAL(4 + 4 * 8), %esp
@@ -1846,16 +1846,21 @@
movd %edx, %xmm1
punpckldq %xmm1, %xmm0
ret
+
+ // Undo the unwinding information from above since it doesn't apply below.
+ CFI_RESTORE_STATE_AND_DEF_CFA(ebp, 64)
.Lexception_in_native:
pushl %fs:THREAD_TOP_QUICK_FRAME_OFFSET
addl LITERAL(-1), (%esp) // Remove the GenericJNI tag.
movl (%esp), %esp
- // Do a call to push a new save-all frame required by the runtime.
- call .Lexception_call
-.Lexception_call:
- DELIVER_PENDING_EXCEPTION
+ call art_deliver_pending_exception
END_FUNCTION art_quick_generic_jni_trampoline
+DEFINE_FUNCTION art_deliver_pending_exception
+ // This will create a new save-all frame, required by the runtime.
+ DELIVER_PENDING_EXCEPTION
+END_FUNCTION art_deliver_pending_exception
+
DEFINE_FUNCTION art_quick_to_interpreter_bridge
SETUP_SAVE_REFS_AND_ARGS_FRAME ebx, ebx // save frame
mov %esp, %edx // remember SP
diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
index f5324c5..9a4edd2 100644
--- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S
+++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
@@ -1623,6 +1623,7 @@
// Tear down the alloca.
movq %rbp, %rsp
+ CFI_REMEMBER_STATE
CFI_DEF_CFA_REGISTER(rsp)
// Tear down the callee-save frame.
@@ -1657,17 +1658,21 @@
// store into fpr, for when it's a fpr return...
movq %rax, %xmm0
ret
+
+ // Undo the unwinding information from above since it doesn't apply below.
+ CFI_RESTORE_STATE_AND_DEF_CFA(rbp, 208)
.Lexception_in_native:
pushq %gs:THREAD_TOP_QUICK_FRAME_OFFSET
addq LITERAL(-1), (%rsp) // Remove the GenericJNI tag.
movq (%rsp), %rsp
- CFI_DEF_CFA_REGISTER(rsp)
- // Do a call to push a new save-all frame required by the runtime.
- call .Lexception_call
-.Lexception_call:
- DELIVER_PENDING_EXCEPTION
+ call art_deliver_pending_exception
END_FUNCTION art_quick_generic_jni_trampoline
+DEFINE_FUNCTION art_deliver_pending_exception
+ // This will create a new save-all frame, required by the runtime.
+ DELIVER_PENDING_EXCEPTION
+END_FUNCTION art_deliver_pending_exception
+
/*
* Called to bridge from the quick to interpreter ABI. On entry the arguments match those
* of a quick call: