-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[libc] implement sigsetjmp for thumb/thumb2/armv7-a #138147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[libc] implement sigsetjmp for thumb/thumb2/armv7-a #138147
Conversation
SchrodingerZhu
commented
May 1, 2025
•
edited
Loading
edited
@llvm/pr-subscribers-libc Author: Schrodinger ZHU Yifan (SchrodingerZhu) Changes#if defined(__thumb__) && __ARM_ARCH_ISA_THUMB == 1
// Thumb1 does not support the high registers > r7 in stmia, so move them
// into lower GPRs first.
asm(R"(
tst r1, r1
bne .Ldosave
b %c[setjmp]
.Ldosave:
str r4, [r0, #%c[extra]]
mov r4, lr
str r4, [r0, #%c[retaddr]]
mov r4, r0
bl %c[setjmp]
mov r1, r0
mov r0, r4
ldr r4, [r0, #%c[retaddr]]
mov lr, r4
ldr r4, [r0, #%c[extra]]
b %c[epilogue]
)" ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),
[extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "i"(setjmp),
[epilogue] "i"(sigsetjmp_epilogue)
: "r0", "r1", "r4");
#else
// Some thumb2 linkers do not support conditional branch to PLT.
// We branch to local labels instead.
asm(R"(
tst r1, r1
bne .Ldosave
b %c[setjmp]
.Ldosave:
str r4, [r0, #%c[extra]]
str lr, [r0, #%c[retaddr]]
mov r4, r0
bl %c[setjmp]
mov r1, r0
mov r0, r4
ldr r4, [r0, #%c[retaddr]]
ldr lr, [r0, #%c[extra]]
b %c[epilogue]
)" ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),
[extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "i"(setjmp),
[epilogue] "i"(sigsetjmp_epilogue)
: "r0", "r1", "r4");
#endif Full diff: https://github.com/llvm/llvm-project/pull/138147.diff 3 Files Affected:
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index b5e2f59d25a54..607bb359a2321 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -198,6 +198,8 @@ if(LLVM_LIBC_FULL_BUILD)
# setjmp.h entrypoints
libc.src.setjmp.longjmp
libc.src.setjmp.setjmp
+ libc.src.setjmp.siglongjmp
+ libc.src.setjmp.sigsetjmp
)
endif()
diff --git a/libc/src/setjmp/arm/CMakeLists.txt b/libc/src/setjmp/arm/CMakeLists.txt
index 55c80b0bede0d..77f8471c06bb8 100644
--- a/libc/src/setjmp/arm/CMakeLists.txt
+++ b/libc/src/setjmp/arm/CMakeLists.txt
@@ -8,6 +8,22 @@ add_entrypoint_object(
libc.hdr.types.jmp_buf
)
+if (TARGET libc.src.setjmp.sigsetjmp_epilogue)
+ add_entrypoint_object(
+ sigsetjmp
+ SRCS
+ sigsetjmp.cpp
+ HDRS
+ ../sigsetjmp.h
+ DEPENDS
+ libc.hdr.types.jmp_buf
+ libc.hdr.types.sigset_t
+ libc.hdr.offsetof_macros
+ libc.src.setjmp.sigsetjmp_epilogue
+ libc.src.setjmp.setjmp
+ )
+endif()
+
add_entrypoint_object(
longjmp
SRCS
diff --git a/libc/src/setjmp/arm/sigsetjmp.cpp b/libc/src/setjmp/arm/sigsetjmp.cpp
new file mode 100644
index 0000000000000..3f68e8562bd08
--- /dev/null
+++ b/libc/src/setjmp/arm/sigsetjmp.cpp
@@ -0,0 +1,65 @@
+//===-- Implementation of sigsetjmp ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/setjmp/sigsetjmp.h"
+#include "hdr/offsetof_macros.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/setjmp/setjmp_impl.h"
+#include "src/setjmp/sigsetjmp_epilogue.h"
+
+namespace LIBC_NAMESPACE_DECL {
+[[gnu::naked]]
+LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf buf)) {
+#if defined(__thumb__) && __ARM_ARCH_ISA_THUMB == 1
+ // Thumb1 does not support the high registers > r7 in stmia, so move them
+ // into lower GPRs first.
+ asm(R"(
+ tst r1, r1
+ bne .Ldosave
+ b %c[setjmp]
+.Ldosave:
+ str r4, [r0, #%c[extra]]
+ mov r4, lr
+ str r4, [r0, #%c[retaddr]]
+ mov r4, r0
+ bl %c[setjmp]
+ mov r1, r0
+ mov r0, r4
+ ldr r4, [r0, #%c[retaddr]]
+ mov lr, r4
+ ldr r4, [r0, #%c[extra]]
+ b %c[epilogue]
+ )" ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),
+ [extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "i"(setjmp),
+ [epilogue] "i"(sigsetjmp_epilogue)
+ : "r0", "r1", "r4");
+#else
+ // Some thumb2 linkers do not support conditional branch to PLT.
+ // We branch to local labels instead.
+ asm(R"(
+ tst r1, r1
+ bne .Ldosave
+ b %c[setjmp]
+.Ldosave:
+ str r4, [r0, #%c[extra]]
+ str lr, [r0, #%c[retaddr]]
+ mov r4, r0
+ bl %c[setjmp]
+ mov r1, r0
+ mov r0, r4
+ ldr r4, [r0, #%c[retaddr]]
+ ldr lr, [r0, #%c[extra]]
+ b %c[epilogue]
+ )" ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),
+ [extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "i"(setjmp),
+ [epilogue] "i"(sigsetjmp_epilogue)
+ : "r0", "r1", "r4");
+#endif
+}
+} // namespace LIBC_NAMESPACE_DECL
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds a new implementation of sigsetjmp for ARM targets (thumb, thumb2, armv7-a) in the libc project. It introduces a new source file implementing the inline assembly for sigsetjmp and updates the Linux ARM entrypoints configuration to register the new sigsetjmp and siglongjmp functions.
Reviewed Changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated no comments.
File | Description |
---|---|
libc/src/setjmp/arm/sigsetjmp.cpp | Added inline assembly implementations for sigsetjmp supporting both Thumb1 and Thumb2 variants |
libc/config/linux/arm/entrypoints.txt | Updated the ARM entrypoints to include sigsetjmp and siglongjmp |
Files not reviewed (1)
- libc/src/setjmp/arm/CMakeLists.txt: Language not supported