[libc-commits] [libc] [LibC] Add `sigsetjmp` and `siglongjmp` for arm/x64 darwin (PR #138417)
Aly ElAshram via libc-commits
libc-commits at lists.llvm.org
Sat May 3 10:25:37 PDT 2025
https://github.com/AlyElashram created https://github.com/llvm/llvm-project/pull/138417
None
>From 823045588f2d2fc2d2891b2b08639df1259a376d Mon Sep 17 00:00:00 2001
From: AlyElashram <alyahelashram at gmail.com>
Date: Sat, 3 May 2025 20:24:29 +0300
Subject: [PATCH] SigSetJmp.cpp and epilogue for arm and x86_64 (error prone)
---
libc/config/darwin/arm/entrypoints.txt | 3 ++
libc/src/setjmp/darwin/CMakeLists.txt | 12 +++++
libc/src/setjmp/darwin/X86_64/sigsetjmp.cpp | 44 +++++++++++++++++++
libc/src/setjmp/darwin/arm/sigsetjmp.cpp | 36 +++++++++++++++
libc/src/setjmp/darwin/sigsetjmp_epilogue.cpp | 25 +++++++++++
5 files changed, 120 insertions(+)
create mode 100644 libc/src/setjmp/darwin/CMakeLists.txt
create mode 100644 libc/src/setjmp/darwin/X86_64/sigsetjmp.cpp
create mode 100644 libc/src/setjmp/darwin/arm/sigsetjmp.cpp
create mode 100644 libc/src/setjmp/darwin/sigsetjmp_epilogue.cpp
diff --git a/libc/config/darwin/arm/entrypoints.txt b/libc/config/darwin/arm/entrypoints.txt
index 70c888aec064c..11fd9bda04b17 100644
--- a/libc/config/darwin/arm/entrypoints.txt
+++ b/libc/config/darwin/arm/entrypoints.txt
@@ -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
diff --git a/libc/src/setjmp/darwin/CMakeLists.txt b/libc/src/setjmp/darwin/CMakeLists.txt
new file mode 100644
index 0000000000000..63cfc11115488
--- /dev/null
+++ b/libc/src/setjmp/darwin/CMakeLists.txt
@@ -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
+)
\ No newline at end of file
diff --git a/libc/src/setjmp/darwin/X86_64/sigsetjmp.cpp b/libc/src/setjmp/darwin/X86_64/sigsetjmp.cpp
new file mode 100644
index 0000000000000..b358e5d95525d
--- /dev/null
+++ b/libc/src/setjmp/darwin/X86_64/sigsetjmp.cpp
@@ -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
\ No newline at end of file
diff --git a/libc/src/setjmp/darwin/arm/sigsetjmp.cpp b/libc/src/setjmp/darwin/arm/sigsetjmp.cpp
new file mode 100644
index 0000000000000..734591b2aca4c
--- /dev/null
+++ b/libc/src/setjmp/darwin/arm/sigsetjmp.cpp
@@ -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
diff --git a/libc/src/setjmp/darwin/sigsetjmp_epilogue.cpp b/libc/src/setjmp/darwin/sigsetjmp_epilogue.cpp
new file mode 100644
index 0000000000000..4f8e4c39af413
--- /dev/null
+++ b/libc/src/setjmp/darwin/sigsetjmp_epilogue.cpp
@@ -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
More information about the libc-commits
mailing list