From 6dd4406c05eed3060f97cc97475c56e5ef334fba Mon Sep 17 00:00:00 2001 From: Schrodinger ZHU Yifan Date: Wed, 16 Apr 2025 21:40:18 -0400 Subject: [PATCH 01/12] [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 // 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(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 Date: Wed, 16 Apr 2025 22:08:08 -0400 Subject: [PATCH 02/12] Update libc/src/setjmp/siglongjmp.cpp Co-authored-by: Copilot <175728472+Copilot@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 Date: Thu, 17 Apr 2025 09:10:02 -0400 Subject: [PATCH 03/12] 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 Date: Thu, 17 Apr 2025 09:21:08 -0400 Subject: [PATCH 04/12] 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 Date: Thu, 17 Apr 2025 12:56:00 -0400 Subject: [PATCH 05/12] 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 // 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 Date: Thu, 17 Apr 2025 12:57:32 -0400 Subject: [PATCH 06/12] 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 Date: Fri, 18 Apr 2025 15:44:05 -0400 Subject: [PATCH 07/12] 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 // 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 // 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 Date: Fri, 18 Apr 2025 15:48:11 -0400 Subject: [PATCH 08/12] 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" From a88ad070e4138001eaef634638a7d42cf72999fa Mon Sep 17 00:00:00 2001 From: Schrodinger ZHU Yifan Date: Tue, 22 Apr 2025 10:26:54 -0400 Subject: [PATCH 09/12] fix --- libc/hdr/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/hdr/CMakeLists.txt b/libc/hdr/CMakeLists.txt index 1c4716241473d..efb5c3f0b2ce7 100644 --- a/libc/hdr/CMakeLists.txt +++ b/libc/hdr/CMakeLists.txt @@ -225,7 +225,7 @@ add_proxy_header_library( # 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_header_library(offsetof_macros HDRS offsetof_macros.h) add_subdirectory(types) add_subdirectory(func) From 80e7dda5d6710b6b21fad404f2e88788177342cf Mon Sep 17 00:00:00 2001 From: Schrodinger ZHU Yifan Date: Tue, 22 Apr 2025 17:28:30 -0400 Subject: [PATCH 10/12] remove extra changes --- libc/hdr/offsetof_macros.h | 9 +-------- libc/src/setjmp/x86_64/sigsetjmp.cpp | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/libc/hdr/offsetof_macros.h b/libc/hdr/offsetof_macros.h index 1db3da9167a26..4a7f7b0708dc9 100644 --- a/libc/hdr/offsetof_macros.h +++ b/libc/hdr/offsetof_macros.h @@ -9,14 +9,7 @@ #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 // compiler resource header -#endif +#include #endif // LLVM_LIBC_HDR_OFFSETOF_MACROS_H diff --git a/libc/src/setjmp/x86_64/sigsetjmp.cpp b/libc/src/setjmp/x86_64/sigsetjmp.cpp index 2f56ae6f76d0c..dc41a71321322 100644 --- a/libc/src/setjmp/x86_64/sigsetjmp.cpp +++ b/libc/src/setjmp/x86_64/sigsetjmp.cpp @@ -1,4 +1,4 @@ -//===-- Implementation of setjmp ------------------------------------------===// +//===-- 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. From 8fd8ba1f22e5692ebc0ab6c8f45273ca348565a5 Mon Sep 17 00:00:00 2001 From: Schrodinger ZHU Yifan Date: Wed, 23 Apr 2025 13:03:07 -0400 Subject: [PATCH 11/12] Update libc/hdr/offsetof_macros.h Co-authored-by: Michael Jones --- libc/hdr/offsetof_macros.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libc/hdr/offsetof_macros.h b/libc/hdr/offsetof_macros.h index 4a7f7b0708dc9..bf8ef546190cd 100644 --- a/libc/hdr/offsetof_macros.h +++ b/libc/hdr/offsetof_macros.h @@ -9,7 +9,15 @@ #ifndef LLVM_LIBC_HDR_OFFSETOF_MACROS_H #define LLVM_LIBC_HDR_OFFSETOF_MACROS_H +#ifdef LIBC_FULL_BUILD + +#include "include/llvm-libc-macros/offsetof-macros.h" + +#else // Overlay mode + #define __need_offsetof #include +#endif // LLVM_LIBC_FULL_BUILD + #endif // LLVM_LIBC_HDR_OFFSETOF_MACROS_H From 0b62f8a6034b03477dfbfe5645bfa8c341cb9a03 Mon Sep 17 00:00:00 2001 From: Schrodinger ZHU Yifan Date: Wed, 23 Apr 2025 13:49:54 -0400 Subject: [PATCH 12/12] fix --- libc/hdr/CMakeLists.txt | 9 +++++++-- libc/hdr/offsetof_macros.h | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/libc/hdr/CMakeLists.txt b/libc/hdr/CMakeLists.txt index efb5c3f0b2ce7..209fcb965242f 100644 --- a/libc/hdr/CMakeLists.txt +++ b/libc/hdr/CMakeLists.txt @@ -224,8 +224,13 @@ add_proxy_header_library( ) # 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_proxy_header_library( + offsetof_macros + HDRS + offsetof_macros.h + FULL_BUILD_DEPENDS + libc.include.llvm-libc-macros.offsetof_macro +) add_subdirectory(types) add_subdirectory(func) diff --git a/libc/hdr/offsetof_macros.h b/libc/hdr/offsetof_macros.h index bf8ef546190cd..42e853ffa92e5 100644 --- a/libc/hdr/offsetof_macros.h +++ b/libc/hdr/offsetof_macros.h @@ -11,7 +11,7 @@ #ifdef LIBC_FULL_BUILD -#include "include/llvm-libc-macros/offsetof-macros.h" +#include "include/llvm-libc-macros/offsetof-macro.h" #else // Overlay mode