[libc-commits] [libc] [libc][AArch64] Support LFI in setjmp and longjmp (PR #238092)
Christian Nieves via libc-commits
libc-commits at lists.llvm.org
Tue Nov 3 08:50:13 PST 2026
https://github.com/squk updated https://github.com/llvm/llvm-project/pull/238092
>From 865b37a58a205841ca7a2438c8bb82c0cd91c437 Mon Sep 17 00:00:00 2001
From: Christian Nieves <christian at nieves.io>
Date: Mon, 2 Nov 2026 20:38:14 +0000
Subject: [PATCH] [libc][AArch64] Support LFI in setjmp and longjmp
Skip saving and restoring LFI-reserved registers (x25, x27, and x28) in
AArch64 setjmp and longjmp when building for LFI (__LFI__).
---
.../__support/macros/properties/architectures.h | 4 ++++
libc/src/setjmp/aarch64/longjmp.cpp | 15 ++++++++++++++-
libc/src/setjmp/aarch64/setjmp.cpp | 12 ++++++++++++
3 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/libc/src/__support/macros/properties/architectures.h b/libc/src/__support/macros/properties/architectures.h
index c1c425067ddd9d..18700b66f9a0e6 100644
--- a/libc/src/__support/macros/properties/architectures.h
+++ b/libc/src/__support/macros/properties/architectures.h
@@ -74,4 +74,8 @@
#define LIBC_TARGET_ARCH_IS_HEXAGON
#endif
+#if defined(__LFI__)
+#define LIBC_TARGET_ARCH_IS_LFI
+#endif
+
#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_ARCHITECTURES_H
diff --git a/libc/src/setjmp/aarch64/longjmp.cpp b/libc/src/setjmp/aarch64/longjmp.cpp
index 80c97c721cc4f6..144524f675c7d3 100644
--- a/libc/src/setjmp/aarch64/longjmp.cpp
+++ b/libc/src/setjmp/aarch64/longjmp.cpp
@@ -9,6 +9,7 @@
#include "src/setjmp/longjmp.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/architectures.h"
namespace LIBC_NAMESPACE_DECL {
@@ -32,7 +33,18 @@ namespace LIBC_NAMESPACE_DECL {
// address at the start of longjmp, because we're not going to use it anyway!
asm(
- // Reload the callee-saved GPRs, including fp and lr.
+ // Reload the callee-saved GPRs, including fp and lr.
+#if defined(LIBC_TARGET_ARCH_IS_LFI)
+ // LFI reserves x25 (ctx), x27 (membase), and x28 (retbase); also mask sp
+ // and x30 via the LFI target rewriting rules.
+ R"(
+ ldp x19, x20, [x0, #0*16]
+ ldp x21, x22, [x0, #1*16]
+ ldp x23, x24, [x0, #2*16]
+ ldr x26, [x0, #3*16 + 8]
+ ldp x29, x30, [x0, #5*16]
+ )"
+#else
R"(
ldp x19, x20, [x0, #0*16]
ldp x21, x22, [x0, #1*16]
@@ -41,6 +53,7 @@ namespace LIBC_NAMESPACE_DECL {
ldp x27, x28, [x0, #4*16]
ldp x29, x30, [x0, #5*16]
)"
+#endif
#if LIBC_COPT_SETJMP_AARCH64_RESTORE_PLATFORM_REGISTER
// Reload the stack pointer, and the platform register x18.
diff --git a/libc/src/setjmp/aarch64/setjmp.cpp b/libc/src/setjmp/aarch64/setjmp.cpp
index 8dd1eb342c0973..9378f54f0a8d53 100644
--- a/libc/src/setjmp/aarch64/setjmp.cpp
+++ b/libc/src/setjmp/aarch64/setjmp.cpp
@@ -8,6 +8,7 @@
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/architectures.h"
#include "src/setjmp/setjmp_impl.h"
namespace LIBC_NAMESPACE_DECL {
@@ -33,6 +34,16 @@ namespace LIBC_NAMESPACE_DECL {
// Of course lr isn't normally callee-saved (the call instruction itself
// can't help clobbering it), but we certainly need to save it for this
// purpose.
+#if defined(LIBC_TARGET_ARCH_IS_LFI)
+ // LFI reserves x25 (ctx), x27 (membase), and x28 (retbase).
+ R"(
+ stp x19, x20, [x0, #0*16]
+ stp x21, x22, [x0, #1*16]
+ stp x23, x24, [x0, #2*16]
+ str x26, [x0, #3*16 + 8]
+ stp x29, x30, [x0, #5*16]
+ )"
+#else
R"(
stp x19, x20, [x0, #0*16]
stp x21, x22, [x0, #1*16]
@@ -41,6 +52,7 @@ namespace LIBC_NAMESPACE_DECL {
stp x27, x28, [x0, #4*16]
stp x29, x30, [x0, #5*16]
)"
+#endif
#if LIBC_COPT_SETJMP_AARCH64_RESTORE_PLATFORM_REGISTER
// Store the stack pointer, and the platform register x18.
More information about the libc-commits
mailing list