Reland `sigsetjmp` patches with build fixes. We wrap every target replying on the epilogue library into conditional checks. --------- Co-authored-by: Petr Hosek <phosek@google.com>
This commit is contained in:
parent
cc0cf72539
commit
6695976d16
@ -1060,6 +1060,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
|
||||
|
@ -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)
|
||||
|
23
libc/hdr/offsetof_macros.h
Normal file
23
libc/hdr/offsetof_macros.h
Normal file
@ -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
|
@ -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(
|
||||
|
@ -9,6 +9,18 @@
|
||||
#ifndef LLVM_LIBC_TYPES_JMP_BUF_H
|
||||
#define LLVM_LIBC_TYPES_JMP_BUF_H
|
||||
|
||||
// TODO: implement sigjmp_buf related functions for other architectures
|
||||
// Issue: https://github.com/llvm/llvm-project/issues/136358
|
||||
#if defined(__linux__)
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#define __LIBC_HAS_SIGJMP_BUF
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__LIBC_HAS_SIGJMP_BUF)
|
||||
#include "sigset_t.h"
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
#ifdef __x86_64__
|
||||
__UINT64_TYPE__ rbx;
|
||||
@ -50,8 +62,22 @@ typedef struct {
|
||||
#else
|
||||
#error "__jmp_buf not available for your target architecture."
|
||||
#endif
|
||||
#if defined(__LIBC_HAS_SIGJMP_BUF)
|
||||
// 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(__LIBC_HAS_SIGJMP_BUF)
|
||||
typedef __jmp_buf sigjmp_buf[1];
|
||||
#endif
|
||||
|
||||
#undef __LIBC_HAS_SIGJMP_BUF
|
||||
|
||||
#endif // LLVM_LIBC_TYPES_JMP_BUF_H
|
||||
|
@ -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
|
||||
|
@ -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,22 @@ add_entrypoint_object(
|
||||
DEPENDS
|
||||
.${LIBC_TARGET_ARCHITECTURE}.longjmp
|
||||
)
|
||||
|
||||
if (TARGET libc.src.setjmp.sigsetjmp_epilogue)
|
||||
add_entrypoint_object(
|
||||
siglongjmp
|
||||
SRCS
|
||||
siglongjmp.cpp
|
||||
HDRS
|
||||
siglongjmp.h
|
||||
DEPENDS
|
||||
.longjmp
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
sigsetjmp
|
||||
ALIAS
|
||||
DEPENDS
|
||||
.${LIBC_TARGET_ARCHITECTURE}.sigsetjmp
|
||||
)
|
||||
endif()
|
||||
|
12
libc/src/setjmp/linux/CMakeLists.txt
Normal file
12
libc/src/setjmp/linux/CMakeLists.txt
Normal file
@ -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
|
||||
)
|
25
libc/src/setjmp/linux/sigsetjmp_epilogue.cpp
Normal file
25
libc/src/setjmp/linux/sigsetjmp_epilogue.cpp
Normal file
@ -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
|
@ -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
|
||||
|
||||
|
23
libc/src/setjmp/siglongjmp.cpp
Normal file
23
libc/src/setjmp/siglongjmp.cpp
Normal file
@ -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
|
25
libc/src/setjmp/siglongjmp.h
Normal file
25
libc/src/setjmp/siglongjmp.h
Normal file
@ -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
|
26
libc/src/setjmp/sigsetjmp.h
Normal file
26
libc/src/setjmp/sigsetjmp.h
Normal file
@ -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
|
19
libc/src/setjmp/sigsetjmp_epilogue.h
Normal file
19
libc/src/setjmp/sigsetjmp_epilogue.h
Normal file
@ -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
|
@ -5,10 +5,24 @@ add_entrypoint_object(
|
||||
HDRS
|
||||
../setjmp_impl.h
|
||||
DEPENDS
|
||||
libc.hdr.offsetof_macros
|
||||
libc.hdr.types.jmp_buf
|
||||
COMPILE_OPTIONS
|
||||
${libc_opt_high_flag}
|
||||
)
|
||||
if (TARGET libc.src.setjmp.sigsetjmp_epilogue)
|
||||
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
|
||||
)
|
||||
endif()
|
||||
|
||||
add_entrypoint_object(
|
||||
longjmp
|
||||
@ -18,7 +32,4 @@ add_entrypoint_object(
|
||||
../longjmp.h
|
||||
DEPENDS
|
||||
libc.hdr.types.jmp_buf
|
||||
COMPILE_OPTIONS
|
||||
${libc_opt_high_flag}
|
||||
-fomit-frame-pointer
|
||||
)
|
||||
|
@ -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"
|
||||
|
68
libc/src/setjmp/x86_64/sigsetjmp.cpp
Normal file
68
libc/src/setjmp/x86_64/sigsetjmp.cpp
Normal file
@ -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
|
@ -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
|
||||
)
|
||||
|
88
libc/test/src/setjmp/sigsetjmp_test.cpp
Normal file
88
libc/test/src/setjmp/sigsetjmp_test.cpp
Normal file
@ -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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user