[llvm-branch-commits] [libunwind] 72d2932 - [libunwind] Fix problems caused by combining BTI and GCS (#102322)
Tobias Hieta via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Aug 20 00:31:00 PDT 2024
Author: John Brawn
Date: 2024-08-20T09:29:19+02:00
New Revision: 72d2932da5a7c70885a1fdfaa809ff1ede0984ff
URL: https://github.com/llvm/llvm-project/commit/72d2932da5a7c70885a1fdfaa809ff1ede0984ff
DIFF: https://github.com/llvm/llvm-project/commit/72d2932da5a7c70885a1fdfaa809ff1ede0984ff.diff
LOG: [libunwind] Fix problems caused by combining BTI and GCS (#102322)
The libunwind assembly files need adjustment in order to work correctly
when both BTI and GCS are both enabled (which will be the case when
using -mbranch-protection=standard):
* __libunwind_Registers_arm64_jumpto can't use br to jump to the return
location, instead we need to use gcspush then ret.
* Because we indirectly call __libunwind_Registers_arm64_jumpto it needs
to start with bti jc.
* We need to set the GCS GNU property bit when it's enabled.
---------
Co-authored-by: Daniel Kiss <daniel.kristof.kiss at gmail.com>
(cherry picked from commit 39529107b46032ef0875ac5b809ab5b60cd15a40)
Added:
Modified:
libunwind/src/UnwindRegistersRestore.S
libunwind/src/assembly.h
Removed:
################################################################################
diff --git a/libunwind/src/UnwindRegistersRestore.S b/libunwind/src/UnwindRegistersRestore.S
index e1d6e17549880b..9d34c7909ed371 100644
--- a/libunwind/src/UnwindRegistersRestore.S
+++ b/libunwind/src/UnwindRegistersRestore.S
@@ -629,6 +629,10 @@ Lnovec:
#elif defined(__aarch64__)
+#if defined(__ARM_FEATURE_GCS_DEFAULT)
+.arch_extension gcs
+#endif
+
//
// extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);
//
@@ -680,7 +684,17 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
ldr x16, [x0, #0x0F8]
ldp x0, x1, [x0, #0x000] // restore x0,x1
mov sp,x16 // restore sp
- br x30 // jump to pc
+#if defined(__ARM_FEATURE_GCS_DEFAULT)
+ // If GCS is enabled we need to push the address we're returning to onto the
+ // GCS stack. We can't just return using br, as there won't be a BTI landing
+ // pad instruction at the destination.
+ mov x16, #1
+ chkfeat x16
+ cbnz x16, Lnogcs
+ gcspushm x30
+Lnogcs:
+#endif
+ ret x30 // jump to pc
#elif defined(__arm__) && !defined(__APPLE__)
diff --git a/libunwind/src/assembly.h b/libunwind/src/assembly.h
index fb07d04071af3d..f8e83e138eff50 100644
--- a/libunwind/src/assembly.h
+++ b/libunwind/src/assembly.h
@@ -82,7 +82,22 @@
#define PPC64_OPD2
#endif
-#if defined(__aarch64__) && defined(__ARM_FEATURE_BTI_DEFAULT)
+#if defined(__aarch64__)
+#if defined(__ARM_FEATURE_GCS_DEFAULT) && defined(__ARM_FEATURE_BTI_DEFAULT)
+// Set BTI, PAC, and GCS gnu property bits
+#define GNU_PROPERTY 7
+// We indirectly branch to __libunwind_Registers_arm64_jumpto from
+// __unw_phase2_resume, so we need to use bti jc.
+#define AARCH64_BTI bti jc
+#elif defined(__ARM_FEATURE_GCS_DEFAULT)
+// Set GCS gnu property bit
+#define GNU_PROPERTY 4
+#elif defined(__ARM_FEATURE_BTI_DEFAULT)
+// Set BTI and PAC gnu property bits
+#define GNU_PROPERTY 3
+#define AARCH64_BTI bti c
+#endif
+#ifdef GNU_PROPERTY
.pushsection ".note.gnu.property", "a" SEPARATOR \
.balign 8 SEPARATOR \
.long 4 SEPARATOR \
@@ -91,12 +106,12 @@
.asciz "GNU" SEPARATOR \
.long 0xc0000000 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ \
.long 4 SEPARATOR \
- .long 3 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_BTI AND */ \
- /* GNU_PROPERTY_AARCH64_FEATURE_1_PAC */ \
+ .long GNU_PROPERTY SEPARATOR \
.long 0 SEPARATOR \
.popsection SEPARATOR
-#define AARCH64_BTI bti c
-#else
+#endif
+#endif
+#if !defined(AARCH64_BTI)
#define AARCH64_BTI
#endif
More information about the llvm-branch-commits
mailing list