Skip to content

[LibC] Add sigsetjmp and siglongjmp for arm/x64 darwin #138417

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions libc/config/darwin/arm/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.inttypes.strtoimax
libc.src.inttypes.strtoumax

# setjmp.h entrypoints
libc.src.setjmp.sigsetjmp

# stdlib.h entrypoints
libc.src.stdlib.abs
libc.src.stdlib.atoi
Expand Down
12 changes: 12 additions & 0 deletions libc/src/setjmp/darwin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
add_object_library(
sigsetjmp_epilogue
HDRS
../sigsetjmp_epilogue.h
SRCS
sigsetjmp_epilogue.cpp
DEPENDS
libc.src.__support.common
libc.src.__support.OSUtil.osutil
libc.hdr.types.jmp_buf
libc.hdr.types.sigset_t
)
44 changes: 44 additions & 0 deletions libc/src/setjmp/darwin/X86_64/sigsetjmp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//===-- 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"
#if !defined(LIBC_TARGET_ARCH_IS_X86_64)
#error "Invalid file include"
#endif
namespace LIBC_NAMESPACE_DECL {

[[gnu::naked]]
LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf buf, int save_mask)) {
asm(R"(
test %%esi, %%esi
jz .Lnosave

pop %c[retaddr](%%rdi) // pop the return address into the buffer
mov %%rbx, %c[extra](%%rdi) // move the value in %rbx to the 'extra' field in the buffer
mov %%rdi, %%rbx // move the buffer address to %rbx
call %P[setjmp] // call setjmp
push %c[retaddr](%%rbx) // push return address back into buffer
mov %%rbx, %%rdi // move buffer address back into %rdi
mov %%eax, %%esi // move setjmp return value to %esi (for save_mask)
mov %c[extra](%%rdi), %%rbx // restore the extra field
jmp %P[epilogue] // jump to epilogue

.Lnosave:
jmp %P[setjmp] // jump directly to setjmp if no save mask is provided
)" :: [retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),
[extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "X"(setjmp),
[epilogue] "X"(sigsetjmp_epilogue)
: "rax", "rbx", "rdi", "rsi");
}

} // namespace LIBC_NAMESPACE_DECL
36 changes: 36 additions & 0 deletions libc/src/setjmp/darwin/arm/sigsetjmp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//===-- 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, int)) {
asm(R"(
cbz w1, %c[setjmp]

str x30, [x0, %c[retaddr]]
str x19, [x0, %c[extra]]
mov x19, x0
bl %c[setjmp]

mov w1, w0
mov x0, x19
ldr x30, [x0, %c[retaddr]]
ldr x19, [x0, %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)
: "x0", "x1", "x19", "x30");
}
} // namespace LIBC_NAMESPACE_DECL
25 changes: 25 additions & 0 deletions libc/src/setjmp/darwin/sigsetjmp_epilogue.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//===-- Implementation of sigsetjmp_epilogue ------------------------------===//
//
// 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_epilogue.h"
#include "src/__support/OSUtil/syscall.h"
#include "src/__support/common.h"
#include "src/signal/sigprocmask.h"

namespace LIBC_NAMESPACE_DECL {
[[gnu::returns_twice]] int sigsetjmp_epilogue(jmp_buf buffer, int retval) {
if (retval) {
// Restore signal mask from the buffer using syscall_impl for macOS
syscall_impl<long>(SYS_rt_sigprocmask, SIG_SETMASK, &buffer->sigmask, nullptr, sizeof(sigset_t));
} else {
// Save the current signal mask to the buffer using syscall_impl for macOS
syscall_impl<long>(SYS_rt_sigprocmask, SIG_BLOCK, nullptr, &buffer->sigmask, sizeof(sigset_t));
}
return retval;
}
} // namespace LIBC_NAMESPACE_DECL
Loading