Skip to content

Reland "[libc] build fix for sigsetjmp (#137047)" #137214

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions libc/hdr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 23 additions & 0 deletions libc/hdr/offsetof_macros.h
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion libc/include/llvm-libc-types/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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(
Expand Down
26 changes: 26 additions & 0 deletions libc/include/llvm-libc-types/jmp_buf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
16 changes: 16 additions & 0 deletions libc/include/setjmp.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
29 changes: 29 additions & 0 deletions libc/src/setjmp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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()
Expand All @@ -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 changes: 12 additions & 0 deletions libc/src/setjmp/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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 changes: 25 additions & 0 deletions libc/src/setjmp/linux/sigsetjmp_epilogue.cpp
Original file line number Diff line number Diff line change
@@ -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
3 changes: 2 additions & 1 deletion libc/src/setjmp/setjmp_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
23 changes: 23 additions & 0 deletions libc/src/setjmp/siglongjmp.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 25 additions & 0 deletions libc/src/setjmp/siglongjmp.h
Original file line number Diff line number Diff line change
@@ -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 changes: 26 additions & 0 deletions libc/src/setjmp/sigsetjmp.h
Original file line number Diff line number Diff line change
@@ -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 changes: 19 additions & 0 deletions libc/src/setjmp/sigsetjmp_epilogue.h
Original file line number Diff line number Diff line change
@@ -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
21 changes: 16 additions & 5 deletions libc/src/setjmp/x86_64/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -18,7 +32,4 @@ add_entrypoint_object(
../longjmp.h
DEPENDS
libc.hdr.types.jmp_buf
COMPILE_OPTIONS
${libc_opt_high_flag}
-fomit-frame-pointer
)
2 changes: 1 addition & 1 deletion libc/src/setjmp/x86_64/setjmp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Loading
Loading