[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