Author: Schrodinger ZHU Yifan Date: 2025-04-24T13:02:09-04:00 New Revision: 3ef0ab8c752dcd3275e6f408d65a573bd92e9a01
URL: https://github.com/llvm/llvm-project/commit/3ef0ab8c752dcd3275e6f408d65a573bd92e9a01 DIFF: https://github.com/llvm/llvm-project/commit/3ef0ab8c752dcd3275e6f408d65a573bd92e9a01.diff LOG: Revert "Revert "[libc] build fix for sigsetjmp (#137047)" (#137077)" This reverts commit 0d00b6bc3b459122de47d16c5153887063f4ea4b. Added: libc/hdr/offsetof_macros.h libc/src/setjmp/linux/CMakeLists.txt libc/src/setjmp/linux/sigsetjmp_epilogue.cpp libc/src/setjmp/siglongjmp.cpp libc/src/setjmp/siglongjmp.h libc/src/setjmp/sigsetjmp.h libc/src/setjmp/sigsetjmp_epilogue.h libc/src/setjmp/x86_64/sigsetjmp.cpp libc/test/src/setjmp/sigsetjmp_test.cpp Modified: libc/config/linux/x86_64/entrypoints.txt libc/hdr/CMakeLists.txt libc/include/llvm-libc-types/CMakeLists.txt libc/include/llvm-libc-types/jmp_buf.h libc/include/setjmp.yaml libc/src/setjmp/CMakeLists.txt libc/src/setjmp/setjmp_impl.h libc/src/setjmp/x86_64/CMakeLists.txt libc/src/setjmp/x86_64/setjmp.cpp libc/test/src/setjmp/CMakeLists.txt Removed: ################################################################################ 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/hdr/CMakeLists.txt b/libc/hdr/CMakeLists.txt index db2dac9ff2822..209fcb965242f 100644 --- a/libc/hdr/CMakeLists.txt +++ b/libc/hdr/CMakeLists.txt @@ -223,5 +223,14 @@ add_proxy_header_library( libc.include.wchar ) +# offsetof is a macro inside compiler resource header stddef.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 new file mode 100644 index 0000000000000..42e853ffa92e5 --- /dev/null +++ b/libc/hdr/offsetof_macros.h @@ -0,0 +1,23 @@ +//===-- 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 + +#ifdef LIBC_FULL_BUILD + +#include "include/llvm-libc-macros/offsetof-macro.h" + +#else // Overlay mode + +#define __need_offsetof +#include <stddef.h> + +#endif // LLVM_LIBC_FULL_BUILD + +#endif // LLVM_LIBC_HDR_OFFSETOF_MACROS_H 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..1e7791610857d 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 "sigset_t.h" + typedef struct { #ifdef __x86_64__ __UINT64_TYPE__ rbx; @@ -49,9 +51,22 @@ typedef struct { #endif #else #error "__jmp_buf not available for your target architecture." +#endif + // 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; + // 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]; +#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 5fbb9eb2a47e5..00049e58c86c8 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: + - POSIX + return_type: int + attributes: + - _Returns_twice + arguments: + - type: sigjmp_buf + - type: int + - name: siglongjmp + standards: + - POSIX + 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..2591319f15240 100644 --- a/libc/src/setjmp/CMakeLists.txt +++ b/libc/src/setjmp/CMakeLists.txt @@ -1,3 +1,13 @@ +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) + add_object_library( + sigsetjmp_epilogue + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.sigsetjmp_epilogue + ) +endif() + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE}) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE}) endif() @@ -15,3 +25,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..b844c8c5ee55a --- /dev/null +++ b/libc/src/setjmp/linux/CMakeLists.txt @@ -0,0 +1,12 @@ +add_object_library( + sigsetjmp_epilogue + HDRS + ../sigsetjmp_epilogue.h + SRCS + sigsetjmp_epilogue.cpp + DEPENDS + libc.src.__support.common + libc.src.__support.OSUtil.osutil + libc.hdr.types.jmp_buf + libc.hdr.types.sigset_t +) 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/setjmp_impl.h b/libc/src/setjmp/setjmp_impl.h index 669f720bda5d3..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 -__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/siglongjmp.cpp b/libc/src/setjmp/siglongjmp.cpp new file mode 100644 index 0000000000000..e372a6fa37503 --- /dev/null +++ b/libc/src/setjmp/siglongjmp.cpp @@ -0,0 +1,23 @@ +//===-- 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. +// 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. +// 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 LIBC_NAMESPACE::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..ef060c8b344a6 --- /dev/null +++ b/libc/src/setjmp/sigsetjmp.h @@ -0,0 +1,26 @@ +//===-- 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 +[[gnu::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..0090e81655662 100644 --- a/libc/src/setjmp/x86_64/CMakeLists.txt +++ b/libc/src/setjmp/x86_64/CMakeLists.txt @@ -5,9 +5,22 @@ add_entrypoint_object( HDRS ../setjmp_impl.h DEPENDS + libc.hdr.offsetof_macros libc.hdr.types.jmp_buf - COMPILE_OPTIONS - ${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.hdr.offsetof_macros + libc.src.setjmp.sigsetjmp_epilogue + libc.src.setjmp.setjmp ) add_entrypoint_object( @@ -18,7 +31,4 @@ add_entrypoint_object( ../longjmp.h DEPENDS libc.hdr.types.jmp_buf - COMPILE_OPTIONS - ${libc_opt_high_flag} - -fomit-frame-pointer ) 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 new file mode 100644 index 0000000000000..4c97a01822679 --- /dev/null +++ b/libc/src/setjmp/x86_64/sigsetjmp.cpp @@ -0,0 +1,68 @@ +//===-- Implementation of sigsetjmp ---------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/setjmp/sigsetjmp.h" +#include "hdr/offsetof_macros.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" +#include "src/setjmp/setjmp_impl.h" +#include "src/setjmp/sigsetjmp_epilogue.h" + +#if !defined(LIBC_TARGET_ARCH_IS_X86) +#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] "X"(setjmp), + [epilogue] "X"(sigsetjmp_epilogue) + : "eax", "ebx", "ecx"); +} +#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] "X"(setjmp), + [epilogue] "X"(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..e95476e00e54b 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.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 new file mode 100644 index 0000000000000..cf8d2f2fab347 --- /dev/null +++ b/libc/test/src/setjmp/sigsetjmp_test.cpp @@ -0,0 +1,88 @@ +//===-- 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/memcmp.h" +#include "src/string/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 +} + +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); +} + +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; + 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; + int val = LIBC_NAMESPACE::sigsetjmp(buf, 0); + if (val == 0) { + jump_back(buf, val); + } + ASSERT_EQ(longjmp_called, 1); + ASSERT_EQ(val, 1); +} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits