Skip to content

[libc] implement sigsetjmp/siglongjmp for x86-64 #136072

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

Merged
merged 13 commits into from
Apr 23, 2025

Conversation

SchrodingerZhu
Copy link
Contributor

This PR adds siglongjmp and sigsetjmp for x86-64 targets.

The behavior of this implementation aligns with musl and mlibc where the siglongjmp is the same as longjmp and the signal mask saving and recovering is handled
by an epilogue trampoline inside sigsetjmp. When savesigs=1, sigsetjmp acts as a callee of setjmp and stores the real return address in extra fields of the jump
buffer. Otherwise, it tail calls setjmp directly. sigsetjmp does not spill anything to the stack which makes it safer to use in signal handlers.

@llvmbot llvmbot added the libc label Apr 17, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 17, 2025

@llvm/pr-subscribers-libc

Author: Schrodinger ZHU Yifan (SchrodingerZhu)

Changes

This PR adds siglongjmp and sigsetjmp for x86-64 targets.

The behavior of this implementation aligns with musl and mlibc where the siglongjmp is the same as longjmp and the signal mask saving and recovering is handled
by an epilogue trampoline inside sigsetjmp. When savesigs=1, sigsetjmp acts as a callee of setjmp and stores the real return address in extra fields of the jump
buffer. Otherwise, it tail calls setjmp directly. sigsetjmp does not spill anything to the stack which makes it safer to use in signal handlers.


Full diff: https://github.com/llvm/llvm-project/pull/136072.diff

15 Files Affected:

  • (modified) libc/config/linux/x86_64/entrypoints.txt (+2)
  • (modified) libc/include/llvm-libc-types/CMakeLists.txt (+1-1)
  • (modified) libc/include/llvm-libc-types/jmp_buf.h (+9)
  • (modified) libc/include/setjmp.yaml (+16)
  • (modified) libc/src/setjmp/CMakeLists.txt (+28)
  • (added) libc/src/setjmp/linux/CMakeLists.txt (+15)
  • (added) libc/src/setjmp/linux/sigsetjmp_epilogue.cpp (+25)
  • (added) libc/src/setjmp/siglongjmp.cpp (+21)
  • (added) libc/src/setjmp/siglongjmp.h (+25)
  • (added) libc/src/setjmp/sigsetjmp.h (+25)
  • (added) libc/src/setjmp/sigsetjmp_epilogue.h (+19)
  • (modified) libc/src/setjmp/x86_64/CMakeLists.txt (+15)
  • (added) libc/src/setjmp/x86_64/sigsetjmp.cpp (+70)
  • (modified) libc/test/src/setjmp/CMakeLists.txt (+17)
  • (added) libc/test/src/setjmp/sigsetjmp_test.cpp (+76)
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 73dfeae1a2c94..e3a96da615056 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -1049,6 +1049,8 @@ if(LLVM_LIBC_FULL_BUILD)
     # setjmp.h entrypoints
     libc.src.setjmp.longjmp
     libc.src.setjmp.setjmp
+    libc.src.setjmp.siglongjmp
+    libc.src.setjmp.sigsetjmp
 
     # stdio.h entrypoints
     libc.src.stdio.clearerr
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index 861b983b34219..26a3ed06b6f05 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -39,7 +39,6 @@ add_header(gid_t HDR gid_t.h)
 add_header(uid_t HDR uid_t.h)
 add_header(imaxdiv_t HDR imaxdiv_t.h)
 add_header(ino_t HDR ino_t.h)
-add_header(jmp_buf HDR jmp_buf.h)
 add_header(mbstate_t HDR mbstate_t.h)
 add_header(mode_t HDR mode_t.h)
 add_header(mtx_t HDR mtx_t.h DEPENDS .__futex_word .__mutex_type)
@@ -83,6 +82,7 @@ add_header(union_sigval HDR union_sigval.h)
 add_header(siginfo_t HDR siginfo_t.h DEPENDS .union_sigval .pid_t .uid_t .clock_t)
 add_header(sig_atomic_t HDR sig_atomic_t.h)
 add_header(sigset_t HDR sigset_t.h DEPENDS libc.include.llvm-libc-macros.signal_macros)
+add_header(jmp_buf HDR jmp_buf.h DEPENDS .sigset_t)
 add_header(struct_sigaction HDR struct_sigaction.h DEPENDS .sigset_t .siginfo_t)
 add_header(struct_timespec HDR struct_timespec.h DEPENDS .time_t)
 add_header(
diff --git a/libc/include/llvm-libc-types/jmp_buf.h b/libc/include/llvm-libc-types/jmp_buf.h
index f246e6491cf55..ccfe249c8ee91 100644
--- a/libc/include/llvm-libc-types/jmp_buf.h
+++ b/libc/include/llvm-libc-types/jmp_buf.h
@@ -9,6 +9,8 @@
 #ifndef LLVM_LIBC_TYPES_JMP_BUF_H
 #define LLVM_LIBC_TYPES_JMP_BUF_H
 
+#include "llvm-libc-types/sigset_t.h"
+
 typedef struct {
 #ifdef __x86_64__
   __UINT64_TYPE__ rbx;
@@ -50,8 +52,15 @@ typedef struct {
 #else
 #error "__jmp_buf not available for your target architecture."
 #endif
+  // return address
+  void *sig_retaddr;
+  // extra register buffer to avoid indefinite stack growth in sigsetjmp
+  void *sig_extra;
+  // signal masks
+  sigset_t sigmask;
 } __jmp_buf;
 
 typedef __jmp_buf jmp_buf[1];
+typedef __jmp_buf sigjmp_buf[1];
 
 #endif // LLVM_LIBC_TYPES_JMP_BUF_H
diff --git a/libc/include/setjmp.yaml b/libc/include/setjmp.yaml
index 5fbb9eb2a47e5..65eb51c2b17be 100644
--- a/libc/include/setjmp.yaml
+++ b/libc/include/setjmp.yaml
@@ -21,3 +21,19 @@ functions:
       - _Returns_twice
     arguments:
       - type: jmp_buf
+  - name: sigsetjmp
+    standards:
+      - stdc
+    return_type: int
+    attributes:
+      - _Returns_twice
+    arguments:
+      - type: sigjmp_buf
+      - type: int
+  - name: siglongjmp
+    standards:
+      - stdc
+    return_type: _Noreturn void
+    arguments:
+      - type: sigjmp_buf
+      - type: int
diff --git a/libc/src/setjmp/CMakeLists.txt b/libc/src/setjmp/CMakeLists.txt
index d85c532e8636c..3a3628bafe7ca 100644
--- a/libc/src/setjmp/CMakeLists.txt
+++ b/libc/src/setjmp/CMakeLists.txt
@@ -1,3 +1,14 @@
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+  add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+endif()
+
+add_object_library(
+  sigsetjmp_epilogue
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.sigsetjmp_epilogue
+)
+
 if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE})
   add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE})
 endif()
@@ -15,3 +26,20 @@ add_entrypoint_object(
   DEPENDS
     .${LIBC_TARGET_ARCHITECTURE}.longjmp
 )
+
+add_entrypoint_object(
+  siglongjmp
+  SRCS
+    siglongjmp.cpp
+  HDRS
+    siglongjmp.h
+  DEPENDS
+    .longjmp
+)
+
+add_entrypoint_object(
+  sigsetjmp
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_ARCHITECTURE}.sigsetjmp
+)
diff --git a/libc/src/setjmp/linux/CMakeLists.txt b/libc/src/setjmp/linux/CMakeLists.txt
new file mode 100644
index 0000000000000..fdf6cf3d4ee62
--- /dev/null
+++ b/libc/src/setjmp/linux/CMakeLists.txt
@@ -0,0 +1,15 @@
+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
+  COMPILE_OPTIONS
+    ${libc_opt_high_flag}
+    -fomit-frame-pointer
+)
diff --git a/libc/src/setjmp/linux/sigsetjmp_epilogue.cpp b/libc/src/setjmp/linux/sigsetjmp_epilogue.cpp
new file mode 100644
index 0000000000000..4718623c488ec
--- /dev/null
+++ b/libc/src/setjmp/linux/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 <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE_DECL {
+[[gnu::returns_twice]] int sigsetjmp_epilogue(jmp_buf buffer, int retval) {
+  // If set is NULL, then the signal mask is unchanged (i.e., how is
+  // ignored), but the current value of the signal mask is nevertheless
+  // returned in oldset (if it is not NULL).
+  syscall_impl<long>(SYS_rt_sigprocmask, SIG_SETMASK,
+                     /* set= */ retval ? &buffer->sigmask : nullptr,
+                     /* old_set= */ retval ? nullptr : &buffer->sigmask,
+                     sizeof(sigset_t));
+  return retval;
+}
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/setjmp/siglongjmp.cpp b/libc/src/setjmp/siglongjmp.cpp
new file mode 100644
index 0000000000000..1641fd9ae5522
--- /dev/null
+++ b/libc/src/setjmp/siglongjmp.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of lsigongjmp --------------------------------------===//
+//
+// 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/siglongjmp.h"
+#include "src/__support/common.h"
+#include "src/setjmp/longjmp.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+// siglongjmp is the same as longjmp. The additional recovery work is done in
+// the epilogue of the sigsetjmp function.
+LLVM_LIBC_FUNCTION(void, siglongjmp, (jmp_buf buf, int val)) {
+  return longjmp(buf, val);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/setjmp/siglongjmp.h b/libc/src/setjmp/siglongjmp.h
new file mode 100644
index 0000000000000..ea5bbb91df2ec
--- /dev/null
+++ b/libc/src/setjmp/siglongjmp.h
@@ -0,0 +1,25 @@
+//===-- Implementation header for siglongjmp --------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SETJMP_SIGLONGJMP_H
+#define LLVM_LIBC_SRC_SETJMP_SIGLONGJMP_H
+
+#include "hdr/types/jmp_buf.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/compiler.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+#ifdef LIBC_COMPILER_IS_GCC
+[[gnu::nothrow]]
+#endif
+void siglongjmp(jmp_buf buf, int val);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SETJMP_SIGLONGJMP_H
diff --git a/libc/src/setjmp/sigsetjmp.h b/libc/src/setjmp/sigsetjmp.h
new file mode 100644
index 0000000000000..5c6d143c3a7a3
--- /dev/null
+++ b/libc/src/setjmp/sigsetjmp.h
@@ -0,0 +1,25 @@
+//===-- Implementation header for sigsetjmp ---------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SETJMP_SIGSETJMP_H
+#define LLVM_LIBC_SRC_SETJMP_SIGSETJMP_H
+
+#include "hdr/types/jmp_buf.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/compiler.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+#ifdef LIBC_COMPILER_IS_GCC
+[[gnu::nothrow]]
+#endif
+__attribute__((returns_twice)) int sigsetjmp(sigjmp_buf buf, int savesigs);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SETJMP_SIGSETJMP_H
diff --git a/libc/src/setjmp/sigsetjmp_epilogue.h b/libc/src/setjmp/sigsetjmp_epilogue.h
new file mode 100644
index 0000000000000..88702b743940f
--- /dev/null
+++ b/libc/src/setjmp/sigsetjmp_epilogue.h
@@ -0,0 +1,19 @@
+//===-- Implementation header for sigsetjmp epilogue ------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SETJMP_SIGSETJMP_EPILOGUE_H
+#define LLVM_LIBC_SRC_SETJMP_SIGSETJMP_EPILOGUE_H
+
+#include "hdr/types/jmp_buf.h"
+#include "src/__support/common.h"
+
+namespace LIBC_NAMESPACE_DECL {
+[[gnu::returns_twice]] int sigsetjmp_epilogue(jmp_buf buffer, int retval);
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SETJMP_SIGSETJMP_EPILOGUE_H
diff --git a/libc/src/setjmp/x86_64/CMakeLists.txt b/libc/src/setjmp/x86_64/CMakeLists.txt
index 96d5751bc81dd..f831cc584838f 100644
--- a/libc/src/setjmp/x86_64/CMakeLists.txt
+++ b/libc/src/setjmp/x86_64/CMakeLists.txt
@@ -10,6 +10,21 @@ add_entrypoint_object(
     ${libc_opt_high_flag}
 )
 
+add_entrypoint_object(
+  sigsetjmp
+  SRCS
+    sigsetjmp.cpp
+  HDRS
+    ../sigsetjmp.h
+  DEPENDS
+    libc.hdr.types.jmp_buf
+    libc.hdr.types.sigset_t
+    libc.src.setjmp.sigsetjmp_epilogue
+    libc.src.setjmp.setjmp
+  COMPILE_OPTIONS
+    ${libc_opt_high_flag}
+)
+
 add_entrypoint_object(
   longjmp
   SRCS
diff --git a/libc/src/setjmp/x86_64/sigsetjmp.cpp b/libc/src/setjmp/x86_64/sigsetjmp.cpp
new file mode 100644
index 0000000000000..8b2ebb5af227c
--- /dev/null
+++ b/libc/src/setjmp/x86_64/sigsetjmp.cpp
@@ -0,0 +1,70 @@
+//===-- Implementation of setjmp ------------------------------------------===//
+//
+// 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 "include/llvm-libc-macros/offsetof-macro.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)
+#error "Invalid file include"
+#endif
+
+namespace LIBC_NAMESPACE_DECL {
+
+#ifdef __i386__
+[[gnu::naked]]
+LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf buf)) {
+  asm(R"(
+      mov 8(%%esp), %%ecx
+      jecxz .Lnosave
+
+      mov 4(%%esp), %%eax
+      pop %c[retaddr](%%eax)
+      mov %%ebx, %c[extra](%%eax)
+      mov %%eax, %%ebx
+      call %P[setjmp]
+      push %c[retaddr](%%ebx)
+      mov %%ebx,4(%%esp)
+      mov %%eax,8(%%esp)
+      mov %c[extra](%%ebx), %%ebx
+      jmp %P[epilogue]
+      
+.Lnosave:
+      jmp %P[setjmp])" ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),
+      [extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "i"(setjmp),
+      [epilogue] "i"(sigsetjmp_epilogue)
+      : "rax", "rbx");
+}
+#endif
+[[gnu::naked]]
+LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf, int)) {
+  asm(R"(
+      test %%esi, %%esi
+      jz .Lnosave
+
+      pop %c[retaddr](%%rdi)
+      mov %%rbx, %c[extra](%%rdi)
+      mov %%rdi, %%rbx
+      call %P[setjmp]
+      push %c[retaddr](%%rbx)
+      mov %%rbx, %%rdi
+      mov %%eax, %%esi
+      mov %c[extra](%%rdi), %%rbx
+      jmp %P[epilogue]
+      
+.Lnosave:
+      jmp %P[setjmp])" ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)),
+      [extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "i"(setjmp),
+      [epilogue] "i"(sigsetjmp_epilogue)
+      : "rax", "rbx");
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/setjmp/CMakeLists.txt b/libc/test/src/setjmp/CMakeLists.txt
index 392230784bd99..7c81ee366b67f 100644
--- a/libc/test/src/setjmp/CMakeLists.txt
+++ b/libc/test/src/setjmp/CMakeLists.txt
@@ -17,3 +17,20 @@ add_libc_unittest(
     libc.src.setjmp.longjmp
     libc.src.setjmp.setjmp
 )
+
+add_libc_unittest(
+  sigsetjmp_test
+  SUITE
+    libc_setjmp_unittests
+  SRCS
+    sigsetjmp_test.cpp
+  CXX_STANDARD
+    20
+  DEPENDS
+    libc.src.setjmp.sigsetjmp
+    libc.src.setjmp.siglongjmp
+    libc.src.signal.sigprocmask
+    libc.src.string.memory_utils.inline_memset
+    libc.src.string.memory_utils.inline_memcmp
+    libc.hdr.types.sigset_t
+)
diff --git a/libc/test/src/setjmp/sigsetjmp_test.cpp b/libc/test/src/setjmp/sigsetjmp_test.cpp
new file mode 100644
index 0000000000000..b11070a6f0f48
--- /dev/null
+++ b/libc/test/src/setjmp/sigsetjmp_test.cpp
@@ -0,0 +1,76 @@
+//===-- Unittests for sigsetjmp and siglongjmp ----------------------------===//
+//
+// 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/siglongjmp.h"
+#include "src/setjmp/sigsetjmp.h"
+#include "src/signal/sigprocmask.h"
+#include "src/string/memory_utils/inline_memcmp.h"
+#include "src/string/memory_utils/inline_memset.h"
+#include "test/UnitTest/Test.h"
+
+constexpr int MAX_LOOP = 123;
+int longjmp_called = 0;
+
+void jump_back(jmp_buf buf, int n) {
+  longjmp_called++;
+  LIBC_NAMESPACE::siglongjmp(buf, n); // Will return |n| out of setjmp
+}
+
+#define SMOKE_TESTS(SUFFIX, FLAG)                                              \
+  TEST(LlvmLibcSetJmpTest, SigSetAndJumpBack##SUFFIX) {                        \
+    jmp_buf buf;                                                               \
+    longjmp_called = 0;                                                        \
+    volatile int n = 0;                                                        \
+    sigset_t old;                                                              \
+    sigset_t mask_all;                                                         \
+    sigset_t recovered;                                                        \
+    LIBC_NAMESPACE::inline_memset(&mask_all, 0xFF, sizeof(mask_all));          \
+    LIBC_NAMESPACE::inline_memset(&old, 0, sizeof(old));                       \
+    LIBC_NAMESPACE::inline_memset(&recovered, 0, sizeof(recovered));           \
+    LIBC_NAMESPACE::sigprocmask(0, nullptr, &old);                             \
+    if (LIBC_NAMESPACE::sigsetjmp(buf, FLAG) <= MAX_LOOP) {                    \
+      if (FLAG) {                                                              \
+        LIBC_NAMESPACE::sigprocmask(0, nullptr, &recovered);                   \
+        ASSERT_EQ(                                                             \
+            0, LIBC_NAMESPACE::inline_memcmp(&old, &recovered, sizeof(old)));  \
+      }                                                                        \
+      n = n + 1;                                                               \
+      if (FLAG)                                                                \
+        LIBC_NAMESPACE::sigprocmask(SIG_BLOCK, &mask_all, nullptr);            \
+      jump_back(buf, n);                                                       \
+    }                                                                          \
+    ASSERT_EQ(longjmp_called, n);                                              \
+    ASSERT_EQ(n, MAX_LOOP + 1);                                                \
+  }                                                                            \
+  TEST(LlvmLibcSetJmpTest, SigSetAndJumpBackValOne##SUFFIX) {                  \
+    jmp_buf buf;                                                               \
+    longjmp_called = 0;                                                        \
+    sigset_t old;                                                              \
+    sigset_t mask_all;                                                         \
+    sigset_t recovered;                                                        \
+    LIBC_NAMESPACE::inline_memset(&mask_all, 0xFF, sizeof(mask_all));          \
+    LIBC_NAMESPACE::inline_memset(&old, 0, sizeof(old));                       \
+    LIBC_NAMESPACE::inline_memset(&recovered, 0, sizeof(recovered));           \
+    LIBC_NAMESPACE::sigprocmask(0, nullptr, &old);                             \
+    int val = LIBC_NAMESPACE::sigsetjmp(buf, FLAG);                            \
+    if (val == 0) {                                                            \
+      if (FLAG)                                                                \
+        LIBC_NAMESPACE::sigprocmask(SIG_BLOCK, &mask_all, nullptr);            \
+      jump_back(buf, val);                                                     \
+    }                                                                          \
+    if (FLAG) {                                                                \
+      LIBC_NAMESPACE::sigprocmask(0, nullptr, &recovered);                     \
+      ASSERT_EQ(0,                                                             \
+                LIBC_NAMESPACE::inline_memcmp(&old, &recovered, sizeof(old))); \
+    }                                                                          \
+    ASSERT_EQ(longjmp_called, 1);                                              \
+    ASSERT_EQ(val, 1);                                                         \
+  }
+
+SMOKE_TESTS(SaveSigs, 1)
+SMOKE_TESTS(NoSaveSigs, 0)

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements sigsetjmp and siglongjmp for the x86-64 target to provide signal-safe non-local jumps following the musl and mlibc behavior. Key changes include:

  • Adding new test cases in libc/test/src/setjmp/sigsetjmp_test.cpp to validate the sigsetjmp/siglongjmp behavior.
  • Introducing assembly implementations for sigsetjmp in libc/src/setjmp/x86_64/sigsetjmp.cpp, along with its epilogue in both architecture-specific and Linux-specific files.
  • Updating header files, YAML configuration, and entrypoints to expose the new functions.

Reviewed Changes

Copilot reviewed 10 out of 15 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
libc/test/src/setjmp/sigsetjmp_test.cpp Added unit tests for sigsetjmp and siglongjmp
libc/src/setjmp/x86_64/sigsetjmp.cpp Implemented sigsetjmp with inline assembly for x86-64
libc/src/setjmp/sigsetjmp_epilogue.h, linux/sigsetjmp_epilogue.cpp Provided epilogue support for sigsetjmp
libc/src/setjmp/sigsetjmp.h and siglongjmp.h Declared the new functions
libc/src/setjmp/siglongjmp.cpp Implemented siglongjmp as an alias for longjmp
libc/include/setjmp.yaml and jmp_buf.h Updated type definitions and configuration for new functions
libc/config/linux/x86_64/entrypoints.txt Added sigsetjmp and siglongjmp entrypoints
Files not reviewed (5)
  • libc/include/llvm-libc-types/CMakeLists.txt: Language not supported
  • libc/src/setjmp/CMakeLists.txt: Language not supported
  • libc/src/setjmp/linux/CMakeLists.txt: Language not supported
  • libc/src/setjmp/x86_64/CMakeLists.txt: Language not supported
  • libc/test/src/setjmp/CMakeLists.txt: Language not supported

@SchrodingerZhu SchrodingerZhu requested a review from Lancern April 17, 2025 02:16
@SchrodingerZhu SchrodingerZhu requested a review from lntue April 17, 2025 13:10
Copy link

github-actions bot commented Apr 17, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@michaelrj-google
Copy link
Contributor

Looks pretty much done, one last fix then I'll approve

Comment on lines 226 to 228
# offsetof is a macro inside compiler resource header stddef.h
# defining it directly as a header library
add_header_library(offsetof_macros HDRS offsetof_macros.h)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this also needs to be a proxy header library now

Copy link
Contributor

@michaelrj-google michaelrj-google left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for implementing this

@SchrodingerZhu SchrodingerZhu merged commit 5bb4cf9 into llvm:main Apr 23, 2025
14 of 15 checks passed
@SchrodingerZhu SchrodingerZhu deleted the libc/sigsetjmp branch April 23, 2025 18:20
@llvm-ci
Copy link
Collaborator

llvm-ci commented Apr 23, 2025

LLVM Buildbot has detected a new failure on builder libc-x86_64-debian-gcc-fullbuild-dbg running on libc-x86_64-debian-fullbuild while building libc at step 4 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/131/builds/20499

Here is the relevant piece of the build log for the reference
Step 4 (annotate) failure: 'python ../llvm-zorg/zorg/buildbot/builders/annotated/libc-linux.py ...' (failure)
...
[52/81] Generating header uchar.h from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/runtimes/../libc/include/uchar.yaml
[53/81] Generating header locale.h from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/runtimes/../libc/include/locale.yaml
[54/81] Generating header sys/wait.h from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/runtimes/../libc/include/sys/wait.yaml
[55/78] Generating header wchar.h from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/runtimes/../libc/include/wchar.yaml
[56/78] Generating header poll.h from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/runtimes/../libc/include/poll.yaml
[57/78] Generating header sys/utsname.h from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/runtimes/../libc/include/sys/utsname.yaml
[58/77] Generating header termios.h from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/runtimes/../libc/include/termios.yaml
[59/66] Generating header math.h from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/runtimes/../libc/include/math.yaml
[60/66] Generating header setjmp.h from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/runtimes/../libc/include/setjmp.yaml
[61/66] Building CXX object libc/src/setjmp/x86_64/CMakeFiles/libc.src.setjmp.x86_64.sigsetjmp.dir/sigsetjmp.cpp.o
FAILED: libc/src/setjmp/x86_64/CMakeFiles/libc.src.setjmp.x86_64.sigsetjmp.dir/sigsetjmp.cpp.o 
/usr/bin/g++ -DLIBC_NAMESPACE=__llvm_libc_20_0_0_git -D_DEBUG -I/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/libc -isystem /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/build/libc/include -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -Wimplicit-fallthrough -Wno-nonnull -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -g -DLIBC_QSORT_IMPL=LIBC_QSORT_QUICK_SORT -DLIBC_ADD_NULL_CHECKS -fpie -ffreestanding -DLIBC_FULL_BUILD -isystem/usr/lib/gcc/x86_64-linux-gnu/12//include -nostdinc -idirafter/usr/include -fno-builtin -fno-exceptions -fno-lax-vector-conversions -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-rtti -ftrivial-auto-var-init=pattern -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -Wall -Wextra -Werror -Wconversion -Wno-sign-conversion -Wdeprecated -fext-numeric-literals -Wno-pedantic -Wimplicit-fallthrough -Wwrite-strings -Wextra-semi -DLIBC_COPT_PUBLIC_PACKAGING -std=gnu++17 -MD -MT libc/src/setjmp/x86_64/CMakeFiles/libc.src.setjmp.x86_64.sigsetjmp.dir/sigsetjmp.cpp.o -MF libc/src/setjmp/x86_64/CMakeFiles/libc.src.setjmp.x86_64.sigsetjmp.dir/sigsetjmp.cpp.o.d -o libc/src/setjmp/x86_64/CMakeFiles/libc.src.setjmp.x86_64.sigsetjmp.dir/sigsetjmp.cpp.o -c /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/libc/src/setjmp/x86_64/sigsetjmp.cpp
/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/libc/src/setjmp/x86_64/sigsetjmp.cpp: In function ‘int __llvm_libc_20_0_0_git::__sigsetjmp_impl__(__jmp_buf*, int)’:
/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/libc/src/setjmp/x86_64/sigsetjmp.cpp:47:3: error: ‘asm’ operand 2 probably does not match constraints [-Werror]
   47 |   asm(R"(
      |   ^~~
/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/libc/src/setjmp/x86_64/sigsetjmp.cpp:47:3: error: ‘asm’ operand 3 probably does not match constraints [-Werror]
/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/libc/src/setjmp/x86_64/sigsetjmp.cpp:47:3: error: impossible constraint in ‘asm’
cc1plus: all warnings being treated as errors
[62/66] Building CXX object libc/src/setjmp/x86_64/CMakeFiles/libc.src.setjmp.x86_64.setjmp.dir/setjmp.cpp.o
[63/66] Building CXX object libc/src/setjmp/x86_64/CMakeFiles/libc.src.setjmp.x86_64.longjmp.dir/longjmp.cpp.o
[64/66] Building CXX object libc/src/setjmp/CMakeFiles/libc.src.setjmp.siglongjmp.dir/siglongjmp.cpp.o
[65/66] Building CXX object libc/src/setjmp/linux/CMakeFiles/libc.src.setjmp.linux.sigsetjmp_epilogue.dir/sigsetjmp_epilogue.cpp.o
ninja: build stopped: subcommand failed.
['ninja', 'libc'] exited with return code 1.
The build step threw an exception...
Traceback (most recent call last):
  File "/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/build/../llvm-zorg/zorg/buildbot/builders/annotated/libc-linux.py", line 164, in step
    yield
  File "/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/build/../llvm-zorg/zorg/buildbot/builders/annotated/libc-linux.py", line 126, in main
    run_command(['ninja', 'libc'])
  File "/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/build/../llvm-zorg/zorg/buildbot/builders/annotated/libc-linux.py", line 179, in run_command
    util.report_run_cmd(cmd, cwd=directory)
  File "/home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-zorg/zorg/buildbot/builders/annotated/util.py", line 49, in report_run_cmd
    subprocess.check_call(cmd, shell=shell, *args, **kwargs)
  File "/usr/lib/python3.11/subprocess.py", line 413, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['ninja', 'libc']' returned non-zero exit status 1.
@@@STEP_FAILURE@@@
@@@BUILD_STEP build libc-startup@@@
Running: ninja libc-startup
[1/19] Generating header float.h from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/runtimes/../libc/include/float.yaml
[2/19] Generating header errno.h from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/runtimes/../libc/include/errno.yaml
[3/19] Generating header fcntl.h from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/runtimes/../libc/include/fcntl.yaml
[4/19] Generating header sys/auxv.h from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/runtimes/../libc/include/sys/auxv.yaml
[5/19] Generating header sys/time.h from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/runtimes/../libc/include/sys/time.yaml
[6/19] Generating header stdint.h from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/runtimes/../libc/include/stdint.yaml
[7/18] Generating header limits.h from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/runtimes/../libc/include/limits.yaml
[8/18] Generating header sys/prctl.h from /home/llvm-libc-buildbot/buildbot-worker/libc-x86_64-debian-fullbuild/libc-x86_64-debian-gcc-fullbuild-dbg/llvm-project/runtimes/../libc/include/sys/prctl.yaml

@llvm-ci
Copy link
Collaborator

llvm-ci commented Apr 23, 2025

LLVM Buildbot has detected a new failure on builder openmp-offload-amdgpu-runtime-2 running on rocm-worker-hw-02 while building libc at step 5 "compile-openmp".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/10/builds/4007

Here is the relevant piece of the build log for the reference
Step 5 (compile-openmp) failure: build (failure)
...
  /home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.src/libc/cmake/modules/LLVMLibCObjectRules.cmake:107 (add_target_with_flags)
  /home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.src/libc/src/setjmp/CMakeLists.txt:5 (add_object_library)


-- Integration test for hdrgen added.
-- check-runtimes does nothing.
-- Configuring incomplete, errors occurred!
See also "/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/runtimes/runtimes-amdgcn-amd-amdhsa-bins/CMakeFiles/CMakeOutput.log".
See also "/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/runtimes/runtimes-amdgcn-amd-amdhsa-bins/CMakeFiles/CMakeError.log".
31.797 [11/2/4604] Creating library symlink lib/libclang-cpp.so
FAILED: runtimes/runtimes-amdgcn-amd-amdhsa-stamps/runtimes-amdgcn-amd-amdhsa-configure /home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/runtimes/runtimes-amdgcn-amd-amdhsa-stamps/runtimes-amdgcn-amd-amdhsa-configure 
cd /home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/runtimes/runtimes-amdgcn-amd-amdhsa-bins && /usr/bin/cmake --no-warn-unused-cli -DCMAKE_C_COMPILER=/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/./bin/clang -DCMAKE_CXX_COMPILER=/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/./bin/clang++ -DCMAKE_ASM_COMPILER=/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/./bin/clang -DCMAKE_LINKER=/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/./bin/ld.lld -DCMAKE_AR=/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/./bin/llvm-ar -DCMAKE_RANLIB=/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/./bin/llvm-ranlib -DCMAKE_NM=/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/./bin/llvm-nm -DCMAKE_OBJDUMP=/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/./bin/llvm-objdump -DCMAKE_OBJCOPY=/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/./bin/llvm-objcopy -DCMAKE_STRIP=/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/./bin/llvm-strip -DCMAKE_READELF=/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/./bin/llvm-readelf -DCMAKE_C_COMPILER_TARGET=amdgcn-amd-amdhsa -DCMAKE_CXX_COMPILER_TARGET=amdgcn-amd-amdhsa -DCMAKE_Fortran_COMPILER_TARGET=amdgcn-amd-amdhsa -DCMAKE_ASM_COMPILER_TARGET=amdgcn-amd-amdhsa -DCMAKE_INSTALL_PREFIX=/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.inst -DLLVM_BINARY_DIR=/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build -DLLVM_CONFIG_PATH=/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/bin/llvm-config -DLLVM_ENABLE_WERROR=OFF -DLLVM_HOST_TRIPLE=x86_64-unknown-linux-gnu -DLLVM_HAVE_LINK_VERSION_SCRIPT=1 -DLLVM_USE_RELATIVE_PATHS_IN_DEBUG_INFO=OFF -DLLVM_USE_RELATIVE_PATHS_IN_FILES=OFF "-DLLVM_LIT_ARGS=-vv --show-unsupported --show-xfail -j 64 --time-tests --timeout 100" -DLLVM_SOURCE_PREFIX= -DPACKAGE_VERSION=21.0.0git -DCMAKE_BUILD_TYPE=Release -DCMAKE_MAKE_PROGRAM=/usr/bin/ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCOMPILER_RT_BUILD_BUILTINS=OFF -DLLVM_INCLUDE_TESTS=ON -DLLVM_ENABLE_PROJECTS_USED=ON -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON -DCMAKE_C_COMPILER_WORKS=ON -DCMAKE_CXX_COMPILER_WORKS=ON -DCMAKE_Fortran_COMPILER_WORKS=ON -DCMAKE_ASM_COMPILER_WORKS=ON -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON -DLLVM_RUNTIMES_TARGET=amdgcn-amd-amdhsa -DHAVE_LLVM_LIT=ON -DCLANG_RESOURCE_DIR= -DLLVM_DEFAULT_TARGET_TRIPLE=amdgcn-amd-amdhsa -DLLVM_LIBC_GPU_BUILD=ON "-DLLVM_ENABLE_RUNTIMES=compiler-rt;libcxxabi;libcxx;libunwind;libc;openmp;offload" -DLLVM_USE_LINKER= -DLIBC_GPU_TEST_JOBS=4 -DLLVM_ENABLE_RUNTIMES=libc -GNinja -C/home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/projects/runtimes-amdgcn-amd-amdhsa/tmp/runtimes-amdgcn-amd-amdhsa-cache-Release.cmake /home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.src/llvm/runtimes/../../runtimes && /usr/bin/cmake -E touch /home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.build/runtimes/runtimes-amdgcn-amd-amdhsa-stamps//runtimes-amdgcn-amd-amdhsa-configure
ninja: build stopped: subcommand failed.

@jhuber6
Copy link
Contributor

jhuber6 commented Apr 23, 2025

@SchrodingerZhu Are you investigating the GPU failure?

CMake Error at /home/botworker/builds/openmp-offload-amdgpu-runtime-2/llvm.src/libc/cmake/modules/LLVMLibCObjectRules.cmake:35 (add_library):
  add_library cannot create ALIAS target "libc.src.setjmp.sigsetjmp_epilogue"
  because target "libc.src.setjmp.gpu.sigsetjmp_epilogue" does not already
  exist.

@Kewen12
Copy link
Contributor

Kewen12 commented Apr 23, 2025

Hi there, this PR breaks our buildbot. Would you please take a look? Thanks!

@SchrodingerZhu
Copy link
Contributor Author

Looking into it now.

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
endif()

add_object_library(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't do this, object libraries are built by default. Entrypoint libraries are only enabled if the corresponding entrypoint is present. This is why every target is now trying to build this and failing if it's not present.

@gulfemsavrun
Copy link
Contributor

We also started seeing a failure on our bots:

CMake Error at /b/s/w/ir/x/w/llvm-llvm-project/libc/cmake/modules/LLVMLibCObjectRules.cmake:35 (add_library):
  add_library cannot create ALIAS target "libc.src.setjmp.sigsetjmp_epilogue"
  because target "libc.src.setjmp.baremetal.sigsetjmp_epilogue" does not
  already exist.

https://logs.chromium.org/logs/fuchsia/buildbucket/cr-buildbucket/8716773939392795281/+/u/clang/build/stdout

Could you please revert this change while investigating the issue since there are multiple breakage reports?

@gulfemsavrun
Copy link
Contributor

I reverted the change via #137077. Before relanding, please make sure that it fixes the reported issues. I can test it on our builders when you have the fix if you need my help.

@SchrodingerZhu
Copy link
Contributor Author

Sorry but I am a bit confused. f07511a should have fixed

CMake Error at /b/s/w/ir/x/w/llvm-llvm-project/libc/cmake/modules/LLVMLibCObjectRules.cmake:35 (add_library):
  add_library cannot create ALIAS target "libc.src.setjmp.sigsetjmp_epilogue"
  because target "libc.src.setjmp.baremetal.sigsetjmp_epilogue" does not
  already exist.

Does this still reproduce under f07511a?

@gulfemsavrun
Copy link
Contributor

Sorry but I am a bit confused. f07511a should have fixed

CMake Error at /b/s/w/ir/x/w/llvm-llvm-project/libc/cmake/modules/LLVMLibCObjectRules.cmake:35 (add_library):
  add_library cannot create ALIAS target "libc.src.setjmp.sigsetjmp_epilogue"
  because target "libc.src.setjmp.baremetal.sigsetjmp_epilogue" does not
  already exist.

Does this still reproduce under f07511a?

Yes, it still reproduces with f07511a. So, that's why I had to revert both changes.

SchrodingerZhu added a commit that referenced this pull request Apr 29, 2025
- **[libc][aarch64] implement sigsetjmp**

On top of #136072
See also #137055 for remarks
on naked attributes.

```c++
//===-- Implementation of setjmp ------------------------------------------===//
//
// 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
```
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
- **[libc][aarch64] implement sigsetjmp**

On top of llvm#136072
See also llvm#137055 for remarks
on naked attributes.

```c++
//===-- Implementation of setjmp ------------------------------------------===//
//
// 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
```
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
- **[libc][aarch64] implement sigsetjmp**

On top of llvm#136072
See also llvm#137055 for remarks
on naked attributes.

```c++
//===-- Implementation of setjmp ------------------------------------------===//
//
// 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
```
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
- **[libc][aarch64] implement sigsetjmp**

On top of llvm#136072
See also llvm#137055 for remarks
on naked attributes.

```c++
//===-- Implementation of setjmp ------------------------------------------===//
//
// 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
```
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request May 6, 2025
- **[libc][aarch64] implement sigsetjmp**

On top of llvm/llvm-project#136072
See also llvm/llvm-project#137055 for remarks
on naked attributes.

```c++
//===-- Implementation of setjmp ------------------------------------------===//
//
// 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
```
GeorgeARM pushed a commit to GeorgeARM/llvm-project that referenced this pull request May 7, 2025
- **[libc][aarch64] implement sigsetjmp**

On top of llvm#136072
See also llvm#137055 for remarks
on naked attributes.

```c++
//===-- Implementation of setjmp ------------------------------------------===//
//
// 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
```
Ankur-0429 pushed a commit to Ankur-0429/llvm-project that referenced this pull request May 9, 2025
Ankur-0429 pushed a commit to Ankur-0429/llvm-project that referenced this pull request May 9, 2025
- **[libc][aarch64] implement sigsetjmp**

On top of llvm#136072
See also llvm#137055 for remarks
on naked attributes.

```c++
//===-- Implementation of setjmp ------------------------------------------===//
//
// 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
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants