[libc-commits] [libc] [libc] implement sigsetjmp/siglongjmp for x86-64 (PR #136072)
Schrodinger ZHU Yifan via libc-commits
libc-commits at lists.llvm.org
Fri Apr 18 12:48:30 PDT 2025
https://github.com/SchrodingerZhu updated https://github.com/llvm/llvm-project/pull/136072
>From 6dd4406c05eed3060f97cc97475c56e5ef334fba Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <i at zhuyi.fan>
Date: Wed, 16 Apr 2025 21:40:18 -0400
Subject: [PATCH 1/8] [libc] implement sigsetjmp/siglongjmp for x86-64
---
libc/config/linux/x86_64/entrypoints.txt | 2 +
libc/include/llvm-libc-types/CMakeLists.txt | 2 +-
libc/include/llvm-libc-types/jmp_buf.h | 9 +++
libc/include/setjmp.yaml | 16 +++++
libc/src/setjmp/CMakeLists.txt | 28 ++++++++
libc/src/setjmp/linux/CMakeLists.txt | 15 ++++
libc/src/setjmp/linux/sigsetjmp_epilogue.cpp | 25 +++++++
libc/src/setjmp/siglongjmp.cpp | 21 ++++++
libc/src/setjmp/siglongjmp.h | 25 +++++++
libc/src/setjmp/sigsetjmp.h | 25 +++++++
libc/src/setjmp/sigsetjmp_epilogue.h | 19 +++++
libc/src/setjmp/x86_64/CMakeLists.txt | 15 ++++
libc/src/setjmp/x86_64/sigsetjmp.cpp | 70 ++++++++++++++++++
libc/test/src/setjmp/CMakeLists.txt | 17 +++++
libc/test/src/setjmp/sigsetjmp_test.cpp | 76 ++++++++++++++++++++
15 files changed, 364 insertions(+), 1 deletion(-)
create mode 100644 libc/src/setjmp/linux/CMakeLists.txt
create mode 100644 libc/src/setjmp/linux/sigsetjmp_epilogue.cpp
create mode 100644 libc/src/setjmp/siglongjmp.cpp
create mode 100644 libc/src/setjmp/siglongjmp.h
create mode 100644 libc/src/setjmp/sigsetjmp.h
create mode 100644 libc/src/setjmp/sigsetjmp_epilogue.h
create mode 100644 libc/src/setjmp/x86_64/sigsetjmp.cpp
create mode 100644 libc/test/src/setjmp/sigsetjmp_test.cpp
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)
>From 647b822291b5b7c9b4c3bd3762ef544394a6d2e4 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Wed, 16 Apr 2025 22:08:08 -0400
Subject: [PATCH 2/8] Update libc/src/setjmp/siglongjmp.cpp
Co-authored-by: Copilot <175728472+Copilot at users.noreply.github.com>
---
libc/src/setjmp/siglongjmp.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/setjmp/siglongjmp.cpp b/libc/src/setjmp/siglongjmp.cpp
index 1641fd9ae5522..141b2164674e5 100644
--- a/libc/src/setjmp/siglongjmp.cpp
+++ b/libc/src/setjmp/siglongjmp.cpp
@@ -1,4 +1,4 @@
-//===-- Implementation of lsigongjmp --------------------------------------===//
+//===-- Implementation of siglongjmp --------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
>From a612005fd18691db8b5f14875767681b71cc1274 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Thu, 17 Apr 2025 09:10:02 -0400
Subject: [PATCH 3/8] address CRs
---
libc/include/llvm-libc-types/jmp_buf.h | 2 +-
libc/src/setjmp/linux/CMakeLists.txt | 6 +++---
libc/src/setjmp/setjmp_impl.h | 2 +-
libc/src/setjmp/sigsetjmp.h | 2 +-
libc/src/setjmp/x86_64/CMakeLists.txt | 13 +++++++------
libc/src/setjmp/x86_64/sigsetjmp.cpp | 2 +-
6 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/libc/include/llvm-libc-types/jmp_buf.h b/libc/include/llvm-libc-types/jmp_buf.h
index ccfe249c8ee91..e7877aa591ca6 100644
--- a/libc/include/llvm-libc-types/jmp_buf.h
+++ b/libc/include/llvm-libc-types/jmp_buf.h
@@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_TYPES_JMP_BUF_H
#define LLVM_LIBC_TYPES_JMP_BUF_H
-#include "llvm-libc-types/sigset_t.h"
+#include "sigset_t.h"
typedef struct {
#ifdef __x86_64__
diff --git a/libc/src/setjmp/linux/CMakeLists.txt b/libc/src/setjmp/linux/CMakeLists.txt
index fdf6cf3d4ee62..0acf9b9d7a4bc 100644
--- a/libc/src/setjmp/linux/CMakeLists.txt
+++ b/libc/src/setjmp/linux/CMakeLists.txt
@@ -4,12 +4,12 @@ add_object_library(
../sigsetjmp_epilogue.h
SRCS
sigsetjmp_epilogue.cpp
+ COMPILE_OPTIONS
+ ${libc_opt_high_flag}
+ -fomit-frame-pointer
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/setjmp_impl.h b/libc/src/setjmp/setjmp_impl.h
index 669f720bda5d3..351383390d55f 100644
--- a/libc/src/setjmp/setjmp_impl.h
+++ b/libc/src/setjmp/setjmp_impl.h
@@ -29,7 +29,7 @@ namespace LIBC_NAMESPACE_DECL {
#ifdef LIBC_COMPILER_IS_GCC
[[gnu::nothrow]]
#endif
-__attribute__((returns_twice)) int setjmp(jmp_buf buf);
+[[gnu::returns_twice]] int setjmp(jmp_buf buf);
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/setjmp/sigsetjmp.h b/libc/src/setjmp/sigsetjmp.h
index 5c6d143c3a7a3..6bbfda8a959c7 100644
--- a/libc/src/setjmp/sigsetjmp.h
+++ b/libc/src/setjmp/sigsetjmp.h
@@ -18,7 +18,7 @@ namespace LIBC_NAMESPACE_DECL {
#ifdef LIBC_COMPILER_IS_GCC
[[gnu::nothrow]]
#endif
-__attribute__((returns_twice)) int sigsetjmp(sigjmp_buf buf, int savesigs);
+[[gnu::returns_twice]] int sigsetjmp(sigjmp_buf buf, int savesigs);
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/setjmp/x86_64/CMakeLists.txt b/libc/src/setjmp/x86_64/CMakeLists.txt
index f831cc584838f..af22071d44a69 100644
--- a/libc/src/setjmp/x86_64/CMakeLists.txt
+++ b/libc/src/setjmp/x86_64/CMakeLists.txt
@@ -4,10 +4,11 @@ add_entrypoint_object(
setjmp.cpp
HDRS
../setjmp_impl.h
- DEPENDS
- libc.hdr.types.jmp_buf
COMPILE_OPTIONS
${libc_opt_high_flag}
+ -fomit-frame-pointer
+ DEPENDS
+ libc.hdr.types.jmp_buf
)
add_entrypoint_object(
@@ -16,13 +17,13 @@ add_entrypoint_object(
sigsetjmp.cpp
HDRS
../sigsetjmp.h
+ COMPILE_OPTIONS
+ ${libc_opt_high_flag}
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(
@@ -31,9 +32,9 @@ add_entrypoint_object(
longjmp.cpp
HDRS
../longjmp.h
- DEPENDS
- libc.hdr.types.jmp_buf
COMPILE_OPTIONS
${libc_opt_high_flag}
-fomit-frame-pointer
+ DEPENDS
+ libc.hdr.types.jmp_buf
)
diff --git a/libc/src/setjmp/x86_64/sigsetjmp.cpp b/libc/src/setjmp/x86_64/sigsetjmp.cpp
index 8b2ebb5af227c..c5677f339b8db 100644
--- a/libc/src/setjmp/x86_64/sigsetjmp.cpp
+++ b/libc/src/setjmp/x86_64/sigsetjmp.cpp
@@ -41,7 +41,7 @@ LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf buf)) {
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");
+ : "eax", "ebx", "ecx");
}
#endif
[[gnu::naked]]
>From 1bde1bae260db667638cc01eb623e34eeec7dc63 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Thu, 17 Apr 2025 09:21:08 -0400
Subject: [PATCH 4/8] address CRs
---
libc/src/setjmp/setjmp_impl.h | 3 ++-
libc/src/setjmp/sigsetjmp.h | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/libc/src/setjmp/setjmp_impl.h b/libc/src/setjmp/setjmp_impl.h
index 351383390d55f..c89d6bc07c900 100644
--- a/libc/src/setjmp/setjmp_impl.h
+++ b/libc/src/setjmp/setjmp_impl.h
@@ -29,7 +29,8 @@ namespace LIBC_NAMESPACE_DECL {
#ifdef LIBC_COMPILER_IS_GCC
[[gnu::nothrow]]
#endif
-[[gnu::returns_twice]] int setjmp(jmp_buf buf);
+[[gnu::returns_twice]] int
+setjmp(jmp_buf buf);
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/setjmp/sigsetjmp.h b/libc/src/setjmp/sigsetjmp.h
index 6bbfda8a959c7..ef060c8b344a6 100644
--- a/libc/src/setjmp/sigsetjmp.h
+++ b/libc/src/setjmp/sigsetjmp.h
@@ -18,7 +18,8 @@ namespace LIBC_NAMESPACE_DECL {
#ifdef LIBC_COMPILER_IS_GCC
[[gnu::nothrow]]
#endif
-[[gnu::returns_twice]] int sigsetjmp(sigjmp_buf buf, int savesigs);
+[[gnu::returns_twice]] int
+sigsetjmp(sigjmp_buf buf, int savesigs);
} // namespace LIBC_NAMESPACE_DECL
>From 2d9ca389245eff621a6998841e121ab2977128f0 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Thu, 17 Apr 2025 12:56:00 -0400
Subject: [PATCH 5/8] address CRs
---
libc/include/llvm-libc-types/jmp_buf.h | 7 +-
libc/include/setjmp.yaml | 4 +-
libc/src/setjmp/x86_64/sigsetjmp.cpp | 6 +-
libc/test/src/setjmp/CMakeLists.txt | 4 +-
libc/test/src/setjmp/sigsetjmp_test.cpp | 132 ++++++++++++++----------
5 files changed, 92 insertions(+), 61 deletions(-)
diff --git a/libc/include/llvm-libc-types/jmp_buf.h b/libc/include/llvm-libc-types/jmp_buf.h
index e7877aa591ca6..588e6c54c0dec 100644
--- a/libc/include/llvm-libc-types/jmp_buf.h
+++ b/libc/include/llvm-libc-types/jmp_buf.h
@@ -52,15 +52,20 @@ typedef struct {
#else
#error "__jmp_buf not available for your target architecture."
#endif
+ // TODO: implement sigjmp_buf related functions
+#if defined(__i386__) || defined(__x86_64__)
// return address
void *sig_retaddr;
// extra register buffer to avoid indefinite stack growth in sigsetjmp
void *sig_extra;
// signal masks
sigset_t sigmask;
+#endif
} __jmp_buf;
typedef __jmp_buf jmp_buf[1];
-typedef __jmp_buf sigjmp_buf[1];
+#if defined(__i386__) || defined(__x86_64__)
+typedef __jmp_buf sigjmp_buf[1];
+#endif
#endif // LLVM_LIBC_TYPES_JMP_BUF_H
diff --git a/libc/include/setjmp.yaml b/libc/include/setjmp.yaml
index 65eb51c2b17be..00049e58c86c8 100644
--- a/libc/include/setjmp.yaml
+++ b/libc/include/setjmp.yaml
@@ -23,7 +23,7 @@ functions:
- type: jmp_buf
- name: sigsetjmp
standards:
- - stdc
+ - POSIX
return_type: int
attributes:
- _Returns_twice
@@ -32,7 +32,7 @@ functions:
- type: int
- name: siglongjmp
standards:
- - stdc
+ - POSIX
return_type: _Noreturn void
arguments:
- type: sigjmp_buf
diff --git a/libc/src/setjmp/x86_64/sigsetjmp.cpp b/libc/src/setjmp/x86_64/sigsetjmp.cpp
index c5677f339b8db..0720f5d355df0 100644
--- a/libc/src/setjmp/x86_64/sigsetjmp.cpp
+++ b/libc/src/setjmp/x86_64/sigsetjmp.cpp
@@ -7,18 +7,18 @@
//===----------------------------------------------------------------------===//
#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"
+#define __need_offsetof
+#include <stddef.h> // compiler resource header
+
#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)) {
diff --git a/libc/test/src/setjmp/CMakeLists.txt b/libc/test/src/setjmp/CMakeLists.txt
index 7c81ee366b67f..e95476e00e54b 100644
--- a/libc/test/src/setjmp/CMakeLists.txt
+++ b/libc/test/src/setjmp/CMakeLists.txt
@@ -30,7 +30,7 @@ add_libc_unittest(
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.src.string.memset
+ libc.src.string.memcmp
libc.hdr.types.sigset_t
)
diff --git a/libc/test/src/setjmp/sigsetjmp_test.cpp b/libc/test/src/setjmp/sigsetjmp_test.cpp
index b11070a6f0f48..91004cfe473b5 100644
--- a/libc/test/src/setjmp/sigsetjmp_test.cpp
+++ b/libc/test/src/setjmp/sigsetjmp_test.cpp
@@ -9,8 +9,8 @@
#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 "src/string/memcmp.h"
+#include "src/string/memset.h"
#include "test/UnitTest/Test.h"
constexpr int MAX_LOOP = 123;
@@ -21,56 +21,82 @@ void jump_back(jmp_buf buf, int n) {
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); \
+TEST(LlvmLibcSetJmpTest, SigSetAndJumpBackSaveSigs) {
+ jmp_buf buf;
+ longjmp_called = 0;
+ volatile int n = 0;
+ sigset_t old;
+ sigset_t mask_all;
+ sigset_t recovered;
+ LIBC_NAMESPACE::memset(&mask_all, 0xFF, sizeof(mask_all));
+ LIBC_NAMESPACE::memset(&old, 0, sizeof(old));
+ LIBC_NAMESPACE::memset(&recovered, 0, sizeof(recovered));
+ LIBC_NAMESPACE::sigprocmask(0, nullptr, &old);
+ if (LIBC_NAMESPACE::sigsetjmp(buf, 1) <= MAX_LOOP) {
+ LIBC_NAMESPACE::sigprocmask(0, nullptr, &recovered);
+ ASSERT_EQ(0, LIBC_NAMESPACE::memcmp(&old, &recovered, sizeof(old)));
+ n = n + 1;
+ LIBC_NAMESPACE::sigprocmask(SIG_BLOCK, &mask_all, nullptr);
+ jump_back(buf, n);
}
+ ASSERT_EQ(longjmp_called, n);
+ ASSERT_EQ(n, MAX_LOOP + 1);
+}
-SMOKE_TESTS(SaveSigs, 1)
-SMOKE_TESTS(NoSaveSigs, 0)
+TEST(LlvmLibcSetJmpTest, SigSetAndJumpBackValOneSaveSigs) {
+ jmp_buf buf;
+ longjmp_called = 0;
+ sigset_t old;
+ sigset_t mask_all;
+ sigset_t recovered;
+ LIBC_NAMESPACE::memset(&mask_all, 0xFF, sizeof(mask_all));
+ LIBC_NAMESPACE::memset(&old, 0, sizeof(old));
+ LIBC_NAMESPACE::memset(&recovered, 0, sizeof(recovered));
+ LIBC_NAMESPACE::sigprocmask(0, nullptr, &old);
+ int val = LIBC_NAMESPACE::sigsetjmp(buf, 1);
+ if (val == 0) {
+ LIBC_NAMESPACE::sigprocmask(SIG_BLOCK, &mask_all, nullptr);
+ jump_back(buf, val);
+ }
+ LIBC_NAMESPACE::sigprocmask(0, nullptr, &recovered);
+ ASSERT_EQ(0, LIBC_NAMESPACE::memcmp(&old, &recovered, sizeof(old)));
+ ASSERT_EQ(longjmp_called, 1);
+ ASSERT_EQ(val, 1);
+}
+
+TEST(LlvmLibcSetJmpTest, SigSetAndJumpBackNoSaveSigs) {
+ jmp_buf buf;
+ longjmp_called = 0;
+ volatile int n = 0;
+ sigset_t old;
+ sigset_t mask_all;
+ sigset_t recovered;
+ LIBC_NAMESPACE::memset(&mask_all, 0xFF, sizeof(mask_all));
+ LIBC_NAMESPACE::memset(&old, 0, sizeof(old));
+ LIBC_NAMESPACE::memset(&recovered, 0, sizeof(recovered));
+ LIBC_NAMESPACE::sigprocmask(0, nullptr, &old);
+ if (LIBC_NAMESPACE::sigsetjmp(buf, 0) <= MAX_LOOP) {
+ n = n + 1;
+ jump_back(buf, n);
+ }
+ ASSERT_EQ(longjmp_called, n);
+ ASSERT_EQ(n, MAX_LOOP + 1);
+}
+
+TEST(LlvmLibcSetJmpTest, SigSetAndJumpBackValOneNoSaveSigs) {
+ jmp_buf buf;
+ longjmp_called = 0;
+ sigset_t old;
+ sigset_t mask_all;
+ sigset_t recovered;
+ LIBC_NAMESPACE::memset(&mask_all, 0xFF, sizeof(mask_all));
+ LIBC_NAMESPACE::memset(&old, 0, sizeof(old));
+ LIBC_NAMESPACE::memset(&recovered, 0, sizeof(recovered));
+ LIBC_NAMESPACE::sigprocmask(0, nullptr, &old);
+ int val = LIBC_NAMESPACE::sigsetjmp(buf, 0);
+ if (val == 0) {
+ jump_back(buf, val);
+ }
+ ASSERT_EQ(longjmp_called, 1);
+ ASSERT_EQ(val, 1);
+}
>From 6496e37cc39d3848c065841bbb75d20b01e96eb2 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Thu, 17 Apr 2025 12:57:32 -0400
Subject: [PATCH 6/8] address CRs
---
libc/test/src/setjmp/sigsetjmp_test.cpp | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/libc/test/src/setjmp/sigsetjmp_test.cpp b/libc/test/src/setjmp/sigsetjmp_test.cpp
index 91004cfe473b5..cf8d2f2fab347 100644
--- a/libc/test/src/setjmp/sigsetjmp_test.cpp
+++ b/libc/test/src/setjmp/sigsetjmp_test.cpp
@@ -68,13 +68,6 @@ TEST(LlvmLibcSetJmpTest, SigSetAndJumpBackNoSaveSigs) {
jmp_buf buf;
longjmp_called = 0;
volatile int n = 0;
- sigset_t old;
- sigset_t mask_all;
- sigset_t recovered;
- LIBC_NAMESPACE::memset(&mask_all, 0xFF, sizeof(mask_all));
- LIBC_NAMESPACE::memset(&old, 0, sizeof(old));
- LIBC_NAMESPACE::memset(&recovered, 0, sizeof(recovered));
- LIBC_NAMESPACE::sigprocmask(0, nullptr, &old);
if (LIBC_NAMESPACE::sigsetjmp(buf, 0) <= MAX_LOOP) {
n = n + 1;
jump_back(buf, n);
@@ -86,13 +79,6 @@ TEST(LlvmLibcSetJmpTest, SigSetAndJumpBackNoSaveSigs) {
TEST(LlvmLibcSetJmpTest, SigSetAndJumpBackValOneNoSaveSigs) {
jmp_buf buf;
longjmp_called = 0;
- sigset_t old;
- sigset_t mask_all;
- sigset_t recovered;
- LIBC_NAMESPACE::memset(&mask_all, 0xFF, sizeof(mask_all));
- LIBC_NAMESPACE::memset(&old, 0, sizeof(old));
- LIBC_NAMESPACE::memset(&recovered, 0, sizeof(recovered));
- LIBC_NAMESPACE::sigprocmask(0, nullptr, &old);
int val = LIBC_NAMESPACE::sigsetjmp(buf, 0);
if (val == 0) {
jump_back(buf, val);
>From abaab76c93297f0f2c9159225d6035a861f53c7f Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Fri, 18 Apr 2025 15:44:05 -0400
Subject: [PATCH 7/8] address CRs
---
libc/hdr/CMakeLists.txt | 4 ++++
libc/hdr/offsetof_macros.h | 22 ++++++++++++++++++++++
libc/include/llvm-libc-types/jmp_buf.h | 3 ++-
libc/src/setjmp/linux/CMakeLists.txt | 3 ---
libc/src/setjmp/siglongjmp.cpp | 4 +++-
libc/src/setjmp/x86_64/CMakeLists.txt | 10 ++--------
libc/src/setjmp/x86_64/setjmp.cpp | 2 +-
libc/src/setjmp/x86_64/sigsetjmp.cpp | 4 +---
8 files changed, 35 insertions(+), 17 deletions(-)
create mode 100644 libc/hdr/offsetof_macros.h
diff --git a/libc/hdr/CMakeLists.txt b/libc/hdr/CMakeLists.txt
index db2dac9ff2822..1c4716241473d 100644
--- a/libc/hdr/CMakeLists.txt
+++ b/libc/hdr/CMakeLists.txt
@@ -223,5 +223,9 @@ add_proxy_header_library(
libc.include.wchar
)
+# 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)
+
add_subdirectory(types)
add_subdirectory(func)
diff --git a/libc/hdr/offsetof_macros.h b/libc/hdr/offsetof_macros.h
new file mode 100644
index 0000000000000..1db3da9167a26
--- /dev/null
+++ b/libc/hdr/offsetof_macros.h
@@ -0,0 +1,22 @@
+//===-- Definition of macros for offsetof ---------------------------------===//
+//
+// 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_HDR_OFFSETOF_MACROS_H
+#define LLVM_LIBC_HDR_OFFSETOF_MACROS_H
+
+#undef offsetof
+
+// Simplify the inclusion if builtin function is available.
+#if __has_builtin(__builtin_offsetof)
+#define offsetof(t, d) __builtin_offsetof(t, d)
+#else
+#define __need_offsetof
+#include <stddef.h> // compiler resource header
+#endif
+
+#endif // LLVM_LIBC_HDR_OFFSETOF_MACROS_H
diff --git a/libc/include/llvm-libc-types/jmp_buf.h b/libc/include/llvm-libc-types/jmp_buf.h
index 588e6c54c0dec..1e7791610857d 100644
--- a/libc/include/llvm-libc-types/jmp_buf.h
+++ b/libc/include/llvm-libc-types/jmp_buf.h
@@ -52,7 +52,8 @@ typedef struct {
#else
#error "__jmp_buf not available for your target architecture."
#endif
- // TODO: implement sigjmp_buf related functions
+ // TODO: implement sigjmp_buf related functions for other architectures
+ // Issue: https://github.com/llvm/llvm-project/issues/136358
#if defined(__i386__) || defined(__x86_64__)
// return address
void *sig_retaddr;
diff --git a/libc/src/setjmp/linux/CMakeLists.txt b/libc/src/setjmp/linux/CMakeLists.txt
index 0acf9b9d7a4bc..b844c8c5ee55a 100644
--- a/libc/src/setjmp/linux/CMakeLists.txt
+++ b/libc/src/setjmp/linux/CMakeLists.txt
@@ -4,9 +4,6 @@ add_object_library(
../sigsetjmp_epilogue.h
SRCS
sigsetjmp_epilogue.cpp
- COMPILE_OPTIONS
- ${libc_opt_high_flag}
- -fomit-frame-pointer
DEPENDS
libc.src.__support.common
libc.src.__support.OSUtil.osutil
diff --git a/libc/src/setjmp/siglongjmp.cpp b/libc/src/setjmp/siglongjmp.cpp
index 141b2164674e5..e372a6fa37503 100644
--- a/libc/src/setjmp/siglongjmp.cpp
+++ b/libc/src/setjmp/siglongjmp.cpp
@@ -14,8 +14,10 @@ namespace LIBC_NAMESPACE_DECL {
// siglongjmp is the same as longjmp. The additional recovery work is done in
// the epilogue of the sigsetjmp function.
+// TODO: move this inside the TU of longjmp and making it an alias after
+// sigsetjmp is implemented for all architectures.
LLVM_LIBC_FUNCTION(void, siglongjmp, (jmp_buf buf, int val)) {
- return longjmp(buf, val);
+ return LIBC_NAMESPACE::longjmp(buf, val);
}
} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/setjmp/x86_64/CMakeLists.txt b/libc/src/setjmp/x86_64/CMakeLists.txt
index af22071d44a69..0090e81655662 100644
--- a/libc/src/setjmp/x86_64/CMakeLists.txt
+++ b/libc/src/setjmp/x86_64/CMakeLists.txt
@@ -4,10 +4,8 @@ add_entrypoint_object(
setjmp.cpp
HDRS
../setjmp_impl.h
- COMPILE_OPTIONS
- ${libc_opt_high_flag}
- -fomit-frame-pointer
DEPENDS
+ libc.hdr.offsetof_macros
libc.hdr.types.jmp_buf
)
@@ -17,11 +15,10 @@ add_entrypoint_object(
sigsetjmp.cpp
HDRS
../sigsetjmp.h
- COMPILE_OPTIONS
- ${libc_opt_high_flag}
DEPENDS
libc.hdr.types.jmp_buf
libc.hdr.types.sigset_t
+ libc.hdr.offsetof_macros
libc.src.setjmp.sigsetjmp_epilogue
libc.src.setjmp.setjmp
)
@@ -32,9 +29,6 @@ add_entrypoint_object(
longjmp.cpp
HDRS
../longjmp.h
- COMPILE_OPTIONS
- ${libc_opt_high_flag}
- -fomit-frame-pointer
DEPENDS
libc.hdr.types.jmp_buf
)
diff --git a/libc/src/setjmp/x86_64/setjmp.cpp b/libc/src/setjmp/x86_64/setjmp.cpp
index 5ac10fa87b39a..28e52712c785d 100644
--- a/libc/src/setjmp/x86_64/setjmp.cpp
+++ b/libc/src/setjmp/x86_64/setjmp.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "include/llvm-libc-macros/offsetof-macro.h"
+#include "hdr/offsetof_macros.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/setjmp/setjmp_impl.h"
diff --git a/libc/src/setjmp/x86_64/sigsetjmp.cpp b/libc/src/setjmp/x86_64/sigsetjmp.cpp
index 0720f5d355df0..6eeb182cdd420 100644
--- a/libc/src/setjmp/x86_64/sigsetjmp.cpp
+++ b/libc/src/setjmp/x86_64/sigsetjmp.cpp
@@ -11,9 +11,7 @@
#include "src/__support/macros/config.h"
#include "src/setjmp/setjmp_impl.h"
#include "src/setjmp/sigsetjmp_epilogue.h"
-
-#define __need_offsetof
-#include <stddef.h> // compiler resource header
+#include "hdr/offsetof_macros.h"
#if !defined(LIBC_TARGET_ARCH_IS_X86)
#error "Invalid file include"
>From ca317131fe0895894cb462abd594fb702efba6cb Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Fri, 18 Apr 2025 15:48:11 -0400
Subject: [PATCH 8/8] address CRs
---
libc/src/setjmp/x86_64/sigsetjmp.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libc/src/setjmp/x86_64/sigsetjmp.cpp b/libc/src/setjmp/x86_64/sigsetjmp.cpp
index 6eeb182cdd420..2f56ae6f76d0c 100644
--- a/libc/src/setjmp/x86_64/sigsetjmp.cpp
+++ b/libc/src/setjmp/x86_64/sigsetjmp.cpp
@@ -7,11 +7,11 @@
//===----------------------------------------------------------------------===//
#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"
-#include "hdr/offsetof_macros.h"
#if !defined(LIBC_TARGET_ARCH_IS_X86)
#error "Invalid file include"
More information about the libc-commits
mailing list