Skip to content

Commit 98df2fc

Browse files
SchrodingerZhurlavaee
authored andcommitted
[libc] implement sigsetjmp for thumb/thumb2/armv7-a (llvm#138147)
1 parent 7a8f2d9 commit 98df2fc

File tree

4 files changed

+84
-1
lines changed

4 files changed

+84
-1
lines changed

libc/config/linux/arm/entrypoints.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ if(LLVM_LIBC_FULL_BUILD)
201201
# setjmp.h entrypoints
202202
libc.src.setjmp.longjmp
203203
libc.src.setjmp.setjmp
204+
libc.src.setjmp.siglongjmp
205+
libc.src.setjmp.sigsetjmp
204206
)
205207
endif()
206208

libc/include/llvm-libc-types/jmp_buf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// Issue: https://github.com/llvm/llvm-project/issues/136358
1414
#if defined(__linux__)
1515
#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || \
16-
defined(__riscv)
16+
defined(__arm__) || defined(__riscv)
1717
#define __LIBC_HAS_SIGJMP_BUF
1818
#endif
1919
#endif

libc/src/setjmp/arm/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,22 @@ add_entrypoint_object(
88
libc.hdr.types.jmp_buf
99
)
1010

11+
if (TARGET libc.src.setjmp.sigsetjmp_epilogue)
12+
add_entrypoint_object(
13+
sigsetjmp
14+
SRCS
15+
sigsetjmp.cpp
16+
HDRS
17+
../sigsetjmp.h
18+
DEPENDS
19+
libc.hdr.types.jmp_buf
20+
libc.hdr.types.sigset_t
21+
libc.hdr.offsetof_macros
22+
libc.src.setjmp.sigsetjmp_epilogue
23+
libc.src.setjmp.setjmp
24+
)
25+
endif()
26+
1127
add_entrypoint_object(
1228
longjmp
1329
SRCS

libc/src/setjmp/arm/sigsetjmp.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//===-- Implementation of sigsetjmp ---------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/setjmp/sigsetjmp.h"
10+
#include "hdr/offsetof_macros.h"
11+
#include "src/__support/common.h"
12+
#include "src/__support/macros/config.h"
13+
#include "src/setjmp/setjmp_impl.h"
14+
#include "src/setjmp/sigsetjmp_epilogue.h"
15+
16+
namespace LIBC_NAMESPACE_DECL {
17+
[[gnu::naked]]
18+
LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf buf)) {
19+
#if defined(__thumb__) && __ARM_ARCH_ISA_THUMB == 1
20+
// Thumb1 does not support the high registers > r7 in stmia, so move them
21+
// into lower GPRs first.
22+
asm(R"(
23+
tst r1, r1
24+
bne .Ldosave
25+
b %c[setjmp]
26+
.Ldosave:
27+
str r4, [r0, #%c[extra]]
28+
mov r4, lr
29+
str r4, [r0, #%c[retaddr]]
30+
mov r4, r0
31+
bl %c[setjmp]
32+
mov r1, r0
33+
mov r0, r4
34+
ldr r4, [r0, #%c[retaddr]]
35+
mov lr, r4
36+
ldr r4, [r0, #%c[extra]]
37+
b %c[epilogue]
38+
)" ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),
39+
[extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "i"(setjmp),
40+
[epilogue] "i"(sigsetjmp_epilogue)
41+
: "r0", "r1", "r4");
42+
#else
43+
// Some thumb2 linkers do not support conditional branch to PLT.
44+
// We branch to local labels instead.
45+
asm(R"(
46+
tst r1, r1
47+
bne .Ldosave
48+
b %c[setjmp]
49+
.Ldosave:
50+
str r4, [r0, #%c[extra]]
51+
str lr, [r0, #%c[retaddr]]
52+
mov r4, r0
53+
bl %c[setjmp]
54+
mov r1, r0
55+
mov r0, r4
56+
ldr lr, [r0, #%c[retaddr]]
57+
ldr r4, [r0, #%c[extra]]
58+
b %c[epilogue]
59+
)" ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),
60+
[extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "X"(setjmp),
61+
[epilogue] "X"(sigsetjmp_epilogue)
62+
: "r0", "r1", "r4");
63+
#endif
64+
}
65+
} // namespace LIBC_NAMESPACE_DECL

0 commit comments

Comments
 (0)