Skip to content

[libc] implement sigsetjmp for thumb/thumb2/armv7-a #138147

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

SchrodingerZhu
Copy link
Contributor

@SchrodingerZhu SchrodingerZhu commented May 1, 2025

#if defined(__thumb__) && __ARM_ARCH_ISA_THUMB == 1
  // Thumb1 does not support the high registers > r7 in stmia, so move them
  // into lower GPRs first.
  asm(R"(
      tst r1, r1
      bne .Ldosave
      b %c[setjmp]
.Ldosave:
      str r4, [r0, #%c[extra]]
      mov r4, lr
      str r4, [r0, #%c[retaddr]]
      mov r4, r0
      bl %c[setjmp]
      mov r1, r0
      mov r0, r4
      ldr r4, [r0, #%c[retaddr]]
      mov lr, r4
      ldr r4, [r0, #%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)
      : "r0", "r1", "r4");
#else
  // Some thumb2 linkers do not support conditional branch to PLT.
  // We branch to local labels instead.
  asm(R"(
      tst r1, r1
      bne .Ldosave
      b %c[setjmp]
.Ldosave:
      str r4, [r0, #%c[extra]]
      str lr, [r0, #%c[retaddr]]
      mov r4, r0
      bl %c[setjmp]
      mov r1, r0
      mov r0, r4
      ldr r4, [r0, #%c[retaddr]]
      ldr lr, [r0, #%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)
      : "r0", "r1", "r4");
#endif

@llvmbot llvmbot added the libc label May 1, 2025
@llvmbot
Copy link
Member

llvmbot commented May 1, 2025

@llvm/pr-subscribers-libc

Author: Schrodinger ZHU Yifan (SchrodingerZhu)

Changes
#if defined(__thumb__) && __ARM_ARCH_ISA_THUMB == 1
  // Thumb1 does not support the high registers > r7 in stmia, so move them
  // into lower GPRs first.
  asm(R"(
      tst r1, r1
      bne .Ldosave
      b %c[setjmp]
.Ldosave:
      str r4, [r0, #%c[extra]]
      mov r4, lr
      str r4, [r0, #%c[retaddr]]
      mov r4, r0
      bl %c[setjmp]
      mov r1, r0
      mov r0, r4
      ldr r4, [r0, #%c[retaddr]]
      mov lr, r4
      ldr r4, [r0, #%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)
      : "r0", "r1", "r4");
#else
  // Some thumb2 linkers do not support conditional branch to PLT.
  // We branch to local labels instead.
  asm(R"(
      tst r1, r1
      bne .Ldosave
      b %c[setjmp]
.Ldosave:
      str r4, [r0, #%c[extra]]
      str lr, [r0, #%c[retaddr]]
      mov r4, r0
      bl %c[setjmp]
      mov r1, r0
      mov r0, r4
      ldr r4, [r0, #%c[retaddr]]
      ldr lr, [r0, #%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)
      : "r0", "r1", "r4");
#endif

Full diff: https://github.com/llvm/llvm-project/pull/138147.diff

3 Files Affected:

  • (modified) libc/config/linux/arm/entrypoints.txt (+2)
  • (modified) libc/src/setjmp/arm/CMakeLists.txt (+16)
  • (added) libc/src/setjmp/arm/sigsetjmp.cpp (+65)
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index b5e2f59d25a54..607bb359a2321 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -198,6 +198,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
   )
 endif()
 
diff --git a/libc/src/setjmp/arm/CMakeLists.txt b/libc/src/setjmp/arm/CMakeLists.txt
index 55c80b0bede0d..77f8471c06bb8 100644
--- a/libc/src/setjmp/arm/CMakeLists.txt
+++ b/libc/src/setjmp/arm/CMakeLists.txt
@@ -8,6 +8,22 @@ add_entrypoint_object(
     libc.hdr.types.jmp_buf
 )
 
+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
   SRCS
diff --git a/libc/src/setjmp/arm/sigsetjmp.cpp b/libc/src/setjmp/arm/sigsetjmp.cpp
new file mode 100644
index 0000000000000..3f68e8562bd08
--- /dev/null
+++ b/libc/src/setjmp/arm/sigsetjmp.cpp
@@ -0,0 +1,65 @@
+//===-- 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 buf)) {
+#if defined(__thumb__) && __ARM_ARCH_ISA_THUMB == 1
+  // Thumb1 does not support the high registers > r7 in stmia, so move them
+  // into lower GPRs first.
+  asm(R"(
+      tst r1, r1
+      bne .Ldosave
+      b %c[setjmp]
+.Ldosave:
+      str r4, [r0, #%c[extra]]
+      mov r4, lr
+      str r4, [r0, #%c[retaddr]]
+      mov r4, r0
+      bl %c[setjmp]
+      mov r1, r0
+      mov r0, r4
+      ldr r4, [r0, #%c[retaddr]]
+      mov lr, r4
+      ldr r4, [r0, #%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)
+      : "r0", "r1", "r4");
+#else
+  // Some thumb2 linkers do not support conditional branch to PLT.
+  // We branch to local labels instead.
+  asm(R"(
+      tst r1, r1
+      bne .Ldosave
+      b %c[setjmp]
+.Ldosave:
+      str r4, [r0, #%c[extra]]
+      str lr, [r0, #%c[retaddr]]
+      mov r4, r0
+      bl %c[setjmp]
+      mov r1, r0
+      mov r0, r4
+      ldr r4, [r0, #%c[retaddr]]
+      ldr lr, [r0, #%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)
+      : "r0", "r1", "r4");
+#endif
+}
+} // namespace LIBC_NAMESPACE_DECL

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds a new implementation of sigsetjmp for ARM targets (thumb, thumb2, armv7-a) in the libc project. It introduces a new source file implementing the inline assembly for sigsetjmp and updates the Linux ARM entrypoints configuration to register the new sigsetjmp and siglongjmp functions.

Reviewed Changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated no comments.

File Description
libc/src/setjmp/arm/sigsetjmp.cpp Added inline assembly implementations for sigsetjmp supporting both Thumb1 and Thumb2 variants
libc/config/linux/arm/entrypoints.txt Updated the ARM entrypoints to include sigsetjmp and siglongjmp
Files not reviewed (1)
  • libc/src/setjmp/arm/CMakeLists.txt: Language not supported

@lntue lntue requested a review from petrhosek May 1, 2025 15:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants