From a325f7fece19773695b79e783e76c39d68f58feb Mon Sep 17 00:00:00 2001 From: Schrodinger ZHU Yifan Date: Tue, 22 Apr 2025 10:46:43 -0400 Subject: [PATCH] [libc][aarch64] implement sigsetjmp --- libc/config/linux/aarch64/entrypoints.txt | 2 ++ libc/include/llvm-libc-types/jmp_buf.h | 4 +-- libc/src/setjmp/aarch64/CMakeLists.txt | 14 +++++++++ libc/src/setjmp/aarch64/sigsetjmp.cpp | 36 +++++++++++++++++++++++ 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 libc/src/setjmp/aarch64/sigsetjmp.cpp diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index be5f5a66016b5..57058633ae50a 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -932,6 +932,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/jmp_buf.h b/libc/include/llvm-libc-types/jmp_buf.h index 1e7791610857d..0376332f2a0dc 100644 --- a/libc/include/llvm-libc-types/jmp_buf.h +++ b/libc/include/llvm-libc-types/jmp_buf.h @@ -54,7 +54,7 @@ typedef struct { #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__) +#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) // return address void *sig_retaddr; // extra register buffer to avoid indefinite stack growth in sigsetjmp @@ -66,7 +66,7 @@ typedef struct { typedef __jmp_buf jmp_buf[1]; -#if defined(__i386__) || defined(__x86_64__) +#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) typedef __jmp_buf sigjmp_buf[1]; #endif #endif // LLVM_LIBC_TYPES_JMP_BUF_H diff --git a/libc/src/setjmp/aarch64/CMakeLists.txt b/libc/src/setjmp/aarch64/CMakeLists.txt index e0e7702c7c4b6..1078af8ce04f3 100644 --- a/libc/src/setjmp/aarch64/CMakeLists.txt +++ b/libc/src/setjmp/aarch64/CMakeLists.txt @@ -26,3 +26,17 @@ add_entrypoint_object( libc.hdr.types.jmp_buf ${setjmp_config_options} ) + +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 +) diff --git a/libc/src/setjmp/aarch64/sigsetjmp.cpp b/libc/src/setjmp/aarch64/sigsetjmp.cpp new file mode 100644 index 0000000000000..734591b2aca4c --- /dev/null +++ b/libc/src/setjmp/aarch64/sigsetjmp.cpp @@ -0,0 +1,36 @@ +//===-- 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" + +namespace LIBC_NAMESPACE_DECL { +[[gnu::naked]] +LLVM_LIBC_FUNCTION(int, sigsetjmp, (sigjmp_buf, int)) { + asm(R"( + cbz w1, %c[setjmp] + + str x30, [x0, %c[retaddr]] + str x19, [x0, %c[extra]] + mov x19, x0 + bl %c[setjmp] + + mov w1, w0 + mov x0, x19 + ldr x30, [x0, %c[retaddr]] + ldr x19, [x0, %c[extra]] + b %c[epilogue])" ::[retaddr] "i"(offsetof(__jmp_buf, sig_retaddr)), + [extra] "i"(offsetof(__jmp_buf, sig_extra)), [setjmp] "i"(setjmp), + [epilogue] "i"(sigsetjmp_epilogue) + : "x0", "x1", "x19", "x30"); +} +} // namespace LIBC_NAMESPACE_DECL