Skip to content

Commit 8230455

Browse files
committed
SigSetJmp.cpp and epilogue for arm and x86_64 (error prone)
1 parent b4fac94 commit 8230455

File tree

5 files changed

+120
-0
lines changed

5 files changed

+120
-0
lines changed

libc/config/darwin/arm/entrypoints.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ set(TARGET_LIBC_ENTRYPOINTS
7070
libc.src.inttypes.strtoimax
7171
libc.src.inttypes.strtoumax
7272

73+
# setjmp.h entrypoints
74+
libc.src.setjmp.sigsetjmp
75+
7376
# stdlib.h entrypoints
7477
libc.src.stdlib.abs
7578
libc.src.stdlib.atoi
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
add_object_library(
2+
sigsetjmp_epilogue
3+
HDRS
4+
../sigsetjmp_epilogue.h
5+
SRCS
6+
sigsetjmp_epilogue.cpp
7+
DEPENDS
8+
libc.src.__support.common
9+
libc.src.__support.OSUtil.osutil
10+
libc.hdr.types.jmp_buf
11+
libc.hdr.types.sigset_t
12+
)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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+
#if !defined(LIBC_TARGET_ARCH_IS_X86_64)
16+
#error "Invalid file include"
17+
#endif
18+
namespace LIBC_NAMESPACE_DECL {
19+
20+
[[gnu::naked]]
21+
LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf buf, int save_mask)) {
22+
asm(R"(
23+
test %%esi, %%esi
24+
jz .Lnosave
25+
26+
pop %c[retaddr](%%rdi) // pop the return address into the buffer
27+
mov %%rbx, %c[extra](%%rdi) // move the value in %rbx to the 'extra' field in the buffer
28+
mov %%rdi, %%rbx // move the buffer address to %rbx
29+
call %P[setjmp] // call setjmp
30+
push %c[retaddr](%%rbx) // push return address back into buffer
31+
mov %%rbx, %%rdi // move buffer address back into %rdi
32+
mov %%eax, %%esi // move setjmp return value to %esi (for save_mask)
33+
mov %c[extra](%%rdi), %%rbx // restore the extra field
34+
jmp %P[epilogue] // jump to epilogue
35+
36+
.Lnosave:
37+
jmp %P[setjmp] // jump directly to setjmp if no save mask is provided
38+
)" :: [retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),
39+
[extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "X"(setjmp),
40+
[epilogue] "X"(sigsetjmp_epilogue)
41+
: "rax", "rbx", "rdi", "rsi");
42+
}
43+
44+
} // namespace LIBC_NAMESPACE_DECL
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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, int)) {
19+
asm(R"(
20+
cbz w1, %c[setjmp]
21+
22+
str x30, [x0, %c[retaddr]]
23+
str x19, [x0, %c[extra]]
24+
mov x19, x0
25+
bl %c[setjmp]
26+
27+
mov w1, w0
28+
mov x0, x19
29+
ldr x30, [x0, %c[retaddr]]
30+
ldr x19, [x0, %c[extra]]
31+
b %c[epilogue])" ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),
32+
[extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "i"(setjmp),
33+
[epilogue] "i"(sigsetjmp_epilogue)
34+
: "x0", "x1", "x19", "x30");
35+
}
36+
} // namespace LIBC_NAMESPACE_DECL
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===-- Implementation of sigsetjmp_epilogue ------------------------------===//
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_epilogue.h"
10+
#include "src/__support/OSUtil/syscall.h"
11+
#include "src/__support/common.h"
12+
#include "src/signal/sigprocmask.h"
13+
14+
namespace LIBC_NAMESPACE_DECL {
15+
[[gnu::returns_twice]] int sigsetjmp_epilogue(jmp_buf buffer, int retval) {
16+
if (retval) {
17+
// Restore signal mask from the buffer using syscall_impl for macOS
18+
syscall_impl<long>(SYS_rt_sigprocmask, SIG_SETMASK, &buffer->sigmask, nullptr, sizeof(sigset_t));
19+
} else {
20+
// Save the current signal mask to the buffer using syscall_impl for macOS
21+
syscall_impl<long>(SYS_rt_sigprocmask, SIG_BLOCK, nullptr, &buffer->sigmask, sizeof(sigset_t));
22+
}
23+
return retval;
24+
}
25+
} // namespace LIBC_NAMESPACE_DECL

0 commit comments

Comments
 (0)