Skip to content

Commit 6695976

Browse files
Reland "[libc] build fix for sigsetjmp (#137047)" (#137214)
Reland `sigsetjmp` patches with build fixes. We wrap every target replying on the epilogue library into conditional checks. --------- Co-authored-by: Petr Hosek <[email protected]>
1 parent cc0cf72 commit 6695976

19 files changed

+428
-8
lines changed

libc/config/linux/x86_64/entrypoints.txt

+2
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,8 @@ if(LLVM_LIBC_FULL_BUILD)
10601060
# setjmp.h entrypoints
10611061
libc.src.setjmp.longjmp
10621062
libc.src.setjmp.setjmp
1063+
libc.src.setjmp.siglongjmp
1064+
libc.src.setjmp.sigsetjmp
10631065

10641066
# stdio.h entrypoints
10651067
libc.src.stdio.clearerr

libc/hdr/CMakeLists.txt

+9
Original file line numberDiff line numberDiff line change
@@ -223,5 +223,14 @@ add_proxy_header_library(
223223
libc.include.wchar
224224
)
225225

226+
# offsetof is a macro inside compiler resource header stddef.h
227+
add_proxy_header_library(
228+
offsetof_macros
229+
HDRS
230+
offsetof_macros.h
231+
FULL_BUILD_DEPENDS
232+
libc.include.llvm-libc-macros.offsetof_macro
233+
)
234+
226235
add_subdirectory(types)
227236
add_subdirectory(func)

libc/hdr/offsetof_macros.h

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===-- Definition of macros for offsetof ---------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_HDR_OFFSETOF_MACROS_H
10+
#define LLVM_LIBC_HDR_OFFSETOF_MACROS_H
11+
12+
#ifdef LIBC_FULL_BUILD
13+
14+
#include "include/llvm-libc-macros/offsetof-macro.h"
15+
16+
#else // Overlay mode
17+
18+
#define __need_offsetof
19+
#include <stddef.h>
20+
21+
#endif // LLVM_LIBC_FULL_BUILD
22+
23+
#endif // LLVM_LIBC_HDR_OFFSETOF_MACROS_H

libc/include/llvm-libc-types/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ add_header(gid_t HDR gid_t.h)
3939
add_header(uid_t HDR uid_t.h)
4040
add_header(imaxdiv_t HDR imaxdiv_t.h)
4141
add_header(ino_t HDR ino_t.h)
42-
add_header(jmp_buf HDR jmp_buf.h)
4342
add_header(mbstate_t HDR mbstate_t.h)
4443
add_header(mode_t HDR mode_t.h)
4544
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)
8382
add_header(siginfo_t HDR siginfo_t.h DEPENDS .union_sigval .pid_t .uid_t .clock_t)
8483
add_header(sig_atomic_t HDR sig_atomic_t.h)
8584
add_header(sigset_t HDR sigset_t.h DEPENDS libc.include.llvm-libc-macros.signal_macros)
85+
add_header(jmp_buf HDR jmp_buf.h DEPENDS .sigset_t)
8686
add_header(struct_sigaction HDR struct_sigaction.h DEPENDS .sigset_t .siginfo_t)
8787
add_header(struct_timespec HDR struct_timespec.h DEPENDS .time_t)
8888
add_header(

libc/include/llvm-libc-types/jmp_buf.h

+26
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,18 @@
99
#ifndef LLVM_LIBC_TYPES_JMP_BUF_H
1010
#define LLVM_LIBC_TYPES_JMP_BUF_H
1111

12+
// TODO: implement sigjmp_buf related functions for other architectures
13+
// Issue: https://github.com/llvm/llvm-project/issues/136358
14+
#if defined(__linux__)
15+
#if defined(__i386__) || defined(__x86_64__)
16+
#define __LIBC_HAS_SIGJMP_BUF
17+
#endif
18+
#endif
19+
20+
#if defined(__LIBC_HAS_SIGJMP_BUF)
21+
#include "sigset_t.h"
22+
#endif
23+
1224
typedef struct {
1325
#ifdef __x86_64__
1426
__UINT64_TYPE__ rbx;
@@ -50,8 +62,22 @@ typedef struct {
5062
#else
5163
#error "__jmp_buf not available for your target architecture."
5264
#endif
65+
#if defined(__LIBC_HAS_SIGJMP_BUF)
66+
// return address
67+
void *sig_retaddr;
68+
// extra register buffer to avoid indefinite stack growth in sigsetjmp
69+
void *sig_extra;
70+
// signal masks
71+
sigset_t sigmask;
72+
#endif
5373
} __jmp_buf;
5474

5575
typedef __jmp_buf jmp_buf[1];
5676

77+
#if defined(__LIBC_HAS_SIGJMP_BUF)
78+
typedef __jmp_buf sigjmp_buf[1];
79+
#endif
80+
81+
#undef __LIBC_HAS_SIGJMP_BUF
82+
5783
#endif // LLVM_LIBC_TYPES_JMP_BUF_H

libc/include/setjmp.yaml

+16
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,19 @@ functions:
2121
- _Returns_twice
2222
arguments:
2323
- type: jmp_buf
24+
- name: sigsetjmp
25+
standards:
26+
- POSIX
27+
return_type: int
28+
attributes:
29+
- _Returns_twice
30+
arguments:
31+
- type: sigjmp_buf
32+
- type: int
33+
- name: siglongjmp
34+
standards:
35+
- POSIX
36+
return_type: _Noreturn void
37+
arguments:
38+
- type: sigjmp_buf
39+
- type: int

libc/src/setjmp/CMakeLists.txt

+29
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
2+
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
3+
add_object_library(
4+
sigsetjmp_epilogue
5+
ALIAS
6+
DEPENDS
7+
.${LIBC_TARGET_OS}.sigsetjmp_epilogue
8+
)
9+
endif()
10+
111
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE})
212
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE})
313
endif()
@@ -15,3 +25,22 @@ add_entrypoint_object(
1525
DEPENDS
1626
.${LIBC_TARGET_ARCHITECTURE}.longjmp
1727
)
28+
29+
if (TARGET libc.src.setjmp.sigsetjmp_epilogue)
30+
add_entrypoint_object(
31+
siglongjmp
32+
SRCS
33+
siglongjmp.cpp
34+
HDRS
35+
siglongjmp.h
36+
DEPENDS
37+
.longjmp
38+
)
39+
40+
add_entrypoint_object(
41+
sigsetjmp
42+
ALIAS
43+
DEPENDS
44+
.${LIBC_TARGET_ARCHITECTURE}.sigsetjmp
45+
)
46+
endif()

libc/src/setjmp/linux/CMakeLists.txt

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
add_object_library(
2+
sigsetjmp_epilogue
3+
HDRS
4+
../sigsetjmp_epilogue.h
5+
SRCS
6+
sigsetjmp_epilogue.cpp
7+
DEPENDS
8+
libc.src.__support.common
9+
libc.src.__support.OSUtil.osutil
10+
libc.hdr.types.jmp_buf
11+
libc.hdr.types.sigset_t
12+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===-- Implementation of sigsetjmp_epilogue ------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/setjmp/sigsetjmp_epilogue.h"
10+
#include "src/__support/OSUtil/syscall.h"
11+
#include "src/__support/common.h"
12+
#include <sys/syscall.h> // For syscall numbers.
13+
14+
namespace LIBC_NAMESPACE_DECL {
15+
[[gnu::returns_twice]] int sigsetjmp_epilogue(jmp_buf buffer, int retval) {
16+
// If set is NULL, then the signal mask is unchanged (i.e., how is
17+
// ignored), but the current value of the signal mask is nevertheless
18+
// returned in oldset (if it is not NULL).
19+
syscall_impl<long>(SYS_rt_sigprocmask, SIG_SETMASK,
20+
/* set= */ retval ? &buffer->sigmask : nullptr,
21+
/* old_set= */ retval ? nullptr : &buffer->sigmask,
22+
sizeof(sigset_t));
23+
return retval;
24+
}
25+
} // namespace LIBC_NAMESPACE_DECL

libc/src/setjmp/setjmp_impl.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ namespace LIBC_NAMESPACE_DECL {
2929
#ifdef LIBC_COMPILER_IS_GCC
3030
[[gnu::nothrow]]
3131
#endif
32-
__attribute__((returns_twice)) int setjmp(jmp_buf buf);
32+
[[gnu::returns_twice]] int
33+
setjmp(jmp_buf buf);
3334

3435
} // namespace LIBC_NAMESPACE_DECL
3536

libc/src/setjmp/siglongjmp.cpp

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===-- Implementation of siglongjmp --------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/setjmp/siglongjmp.h"
10+
#include "src/__support/common.h"
11+
#include "src/setjmp/longjmp.h"
12+
13+
namespace LIBC_NAMESPACE_DECL {
14+
15+
// siglongjmp is the same as longjmp. The additional recovery work is done in
16+
// the epilogue of the sigsetjmp function.
17+
// TODO: move this inside the TU of longjmp and making it an alias after
18+
// sigsetjmp is implemented for all architectures.
19+
LLVM_LIBC_FUNCTION(void, siglongjmp, (jmp_buf buf, int val)) {
20+
return LIBC_NAMESPACE::longjmp(buf, val);
21+
}
22+
23+
} // namespace LIBC_NAMESPACE_DECL

libc/src/setjmp/siglongjmp.h

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===-- Implementation header for siglongjmp --------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_SETJMP_SIGLONGJMP_H
10+
#define LLVM_LIBC_SRC_SETJMP_SIGLONGJMP_H
11+
12+
#include "hdr/types/jmp_buf.h"
13+
#include "src/__support/macros/config.h"
14+
#include "src/__support/macros/properties/compiler.h"
15+
16+
namespace LIBC_NAMESPACE_DECL {
17+
18+
#ifdef LIBC_COMPILER_IS_GCC
19+
[[gnu::nothrow]]
20+
#endif
21+
void siglongjmp(jmp_buf buf, int val);
22+
23+
} // namespace LIBC_NAMESPACE_DECL
24+
25+
#endif // LLVM_LIBC_SRC_SETJMP_SIGLONGJMP_H

libc/src/setjmp/sigsetjmp.h

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===-- Implementation header for sigsetjmp ---------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_SETJMP_SIGSETJMP_H
10+
#define LLVM_LIBC_SRC_SETJMP_SIGSETJMP_H
11+
12+
#include "hdr/types/jmp_buf.h"
13+
#include "src/__support/macros/config.h"
14+
#include "src/__support/macros/properties/compiler.h"
15+
16+
namespace LIBC_NAMESPACE_DECL {
17+
18+
#ifdef LIBC_COMPILER_IS_GCC
19+
[[gnu::nothrow]]
20+
#endif
21+
[[gnu::returns_twice]] int
22+
sigsetjmp(sigjmp_buf buf, int savesigs);
23+
24+
} // namespace LIBC_NAMESPACE_DECL
25+
26+
#endif // LLVM_LIBC_SRC_SETJMP_SIGSETJMP_H

libc/src/setjmp/sigsetjmp_epilogue.h

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//===-- Implementation header for sigsetjmp epilogue ------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SRC_SETJMP_SIGSETJMP_EPILOGUE_H
10+
#define LLVM_LIBC_SRC_SETJMP_SIGSETJMP_EPILOGUE_H
11+
12+
#include "hdr/types/jmp_buf.h"
13+
#include "src/__support/common.h"
14+
15+
namespace LIBC_NAMESPACE_DECL {
16+
[[gnu::returns_twice]] int sigsetjmp_epilogue(jmp_buf buffer, int retval);
17+
} // namespace LIBC_NAMESPACE_DECL
18+
19+
#endif // LLVM_LIBC_SRC_SETJMP_SIGSETJMP_EPILOGUE_H

libc/src/setjmp/x86_64/CMakeLists.txt

+16-5
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,24 @@ add_entrypoint_object(
55
HDRS
66
../setjmp_impl.h
77
DEPENDS
8+
libc.hdr.offsetof_macros
89
libc.hdr.types.jmp_buf
9-
COMPILE_OPTIONS
10-
${libc_opt_high_flag}
1110
)
11+
if (TARGET libc.src.setjmp.sigsetjmp_epilogue)
12+
add_entrypoint_object(
13+
sigsetjmp
14+
SRCS
15+
sigsetjmp.cpp
16+
HDRS
17+
../sigsetjmp.h
18+
DEPENDS
19+
libc.hdr.types.jmp_buf
20+
libc.hdr.types.sigset_t
21+
libc.hdr.offsetof_macros
22+
libc.src.setjmp.sigsetjmp_epilogue
23+
libc.src.setjmp.setjmp
24+
)
25+
endif()
1226

1327
add_entrypoint_object(
1428
longjmp
@@ -18,7 +32,4 @@ add_entrypoint_object(
1832
../longjmp.h
1933
DEPENDS
2034
libc.hdr.types.jmp_buf
21-
COMPILE_OPTIONS
22-
${libc_opt_high_flag}
23-
-fomit-frame-pointer
2435
)

libc/src/setjmp/x86_64/setjmp.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "include/llvm-libc-macros/offsetof-macro.h"
9+
#include "hdr/offsetof_macros.h"
1010
#include "src/__support/common.h"
1111
#include "src/__support/macros/config.h"
1212
#include "src/setjmp/setjmp_impl.h"

0 commit comments

Comments
 (0)