Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Prichard <rprichard@google.com>2022-03-15 01:43:50 +0300
committerRyan Prichard <rprichard@google.com>2022-03-15 01:44:35 +0300
commit659029302dfb16a29219f931f66e9ad483ad1445 (patch)
treee35fe546a94cb669d25e58c0f7681400d54d6c48 /libcxxabi/src
parent56e7d6bd444cef8d879adc35dcf461cb4d2ed6d5 (diff)
[ARM] __cxa_end_cleanup: avoid clobbering r4
The fix for D111703 clobbered r4 both to: - Save/restore the original lr. - Load the address of _Unwind_Resume for LIBCXXABI_BAREMETAL. This patch saves and restores lr without clobbering any extra registers. For LIBCXXABI_BAREMETAL, it is still necessary to clobber one extra register to hold the address of _Unwind_Resume, but it seems better to use ip/r12 (intended for linker veneers/trampolines) than r4 for this purpose. The function also clobbers r0 for the _Unwind_Resume function's parameter, but that is unavoidable. Reviewed By: danielkiss, logan, MaskRay Differential Revision: https://reviews.llvm.org/D121432
Diffstat (limited to 'libcxxabi/src')
-rw-r--r--libcxxabi/src/cxa_exception.cpp21
1 files changed, 13 insertions, 8 deletions
diff --git a/libcxxabi/src/cxa_exception.cpp b/libcxxabi/src/cxa_exception.cpp
index 36388d50dad2..059d75ca2ab4 100644
--- a/libcxxabi/src/cxa_exception.cpp
+++ b/libcxxabi/src/cxa_exception.cpp
@@ -341,10 +341,11 @@ unwinding with _Unwind_Resume.
According to ARM EHABI 8.4.1, __cxa_end_cleanup() should not clobber any
register, thus we have to write this function in assembly so that we can save
{r1, r2, r3}. We don't have to save r0 because it is the return value and the
-first argument to _Unwind_Resume(). In addition, we are saving lr in order to
-align the stack to 16 bytes and lr will be used to identify the caller and its
-frame information. _Unwind_Resume never return and we need to keep the original
-lr so just branch to it.
+first argument to _Unwind_Resume(). The function also saves/restores r4 to
+keep the stack aligned and to provide a temp register. _Unwind_Resume never
+returns and we need to keep the original lr so just branch to it. When
+targeting bare metal, the function also clobbers ip/r12 to hold the address of
+_Unwind_Resume, which may be too far away for an ordinary branch.
*/
__attribute__((used)) static _Unwind_Exception *
__cxa_end_cleanup_impl()
@@ -381,15 +382,19 @@ asm(" .pushsection .text.__cxa_end_cleanup,\"ax\",%progbits\n"
#if defined(__ARM_FEATURE_BTI_DEFAULT)
" bti\n"
#endif
- " push {r1, r2, r3, lr}\n"
+ " push {r1, r2, r3, r4}\n"
+ " mov r4, lr\n"
" bl __cxa_end_cleanup_impl\n"
- " pop {r1, r2, r3, r4}\n"
" mov lr, r4\n"
#if defined(LIBCXXABI_BAREMETAL)
" ldr r4, =_Unwind_Resume\n"
- " bx r4\n"
+ " mov ip, r4\n"
+#endif
+ " pop {r1, r2, r3, r4}\n"
+#if defined(LIBCXXABI_BAREMETAL)
+ " bx ip\n"
#else
- " b _Unwind_Resume\n"
+ " b _Unwind_Resume\n"
#endif
" .popsection");
#endif // defined(_LIBCXXABI_ARM_EHABI)