[llvm] [BOLT][AArch64] Do not crash on authenticated branch instructions (PR #129898)

via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 5 08:33:00 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-bolt

Author: Anatoly Trosinenko (atrosinenko)

<details>
<summary>Changes</summary>

When an indirect branch instruction is decoded, analyzeIndirectBranch method is asked if this is a well-known code pattern. On AArch64, the only special pattern which is detected is Jump Table, emitted as a branch to the sum of a constant base address and a variable offset. Therefore, `Inst.getOpcode()` being one of `AArch64::BRA*` means Inst cannot belong to such Jump Table pattern, thus returning early.

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


2 Files Affected:

- (modified) bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp (+12) 
- (modified) bolt/test/AArch64/test-indirect-branch.s (+22-1) 


``````````diff
diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index 685b2279e5afb..e073b197e70d2 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -547,6 +547,13 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
     return false;
   }
 
+  bool isBRA(const MCInst &Inst) const {
+    return (Inst.getOpcode() == AArch64::BRAA ||
+            Inst.getOpcode() == AArch64::BRAB ||
+            Inst.getOpcode() == AArch64::BRAAZ ||
+            Inst.getOpcode() == AArch64::BRABZ);
+  }
+
   bool mayLoad(const MCInst &Inst) const override {
     return isLDRB(Inst) || isLDRH(Inst) || isLDRW(Inst) || isLDRX(Inst) ||
            isLDRQ(Inst) || isLDRD(Inst) || isLDRS(Inst);
@@ -941,6 +948,11 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
       DenseMap<const MCInst *, SmallVector<MCInst *, 4>> &UDChain,
       const MCExpr *&JumpTable, int64_t &Offset, int64_t &ScaleValue,
       MCInst *&PCRelBase) const {
+    // The only kind of indirect branches we match is jump table, thus ignore
+    // authenticating branch instructions early.
+    if (isBRA(Inst))
+      return false;
+
     // Expect AArch64 BR
     assert(Inst.getOpcode() == AArch64::BR && "Unexpected opcode");
 
diff --git a/bolt/test/AArch64/test-indirect-branch.s b/bolt/test/AArch64/test-indirect-branch.s
index 1e16e76b11530..b99737ee97acc 100644
--- a/bolt/test/AArch64/test-indirect-branch.s
+++ b/bolt/test/AArch64/test-indirect-branch.s
@@ -5,7 +5,7 @@
 
 // REQUIRES: system-linux, asserts
 
-// RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown -mattr=+pauth %s -o %t.o
 // RUN: %clang %cflags --target=aarch64-unknown-linux %t.o -o %t.exe -Wl,-q
 // RUN: llvm-bolt %t.exe -o %t.bolt --print-cfg --strict --debug-only=mcplus \
 // RUN:  -v=1 2>&1 | FileCheck %s
@@ -73,6 +73,27 @@ test2_0:
 test2_1:
   ret
 
+// Make sure BOLT does not crash trying to disassemble BRA* instructions.
+  .globl test_braa
+  .type  test_braa, %function
+test_braa:
+  braa x0, x1
+
+  .globl test_brab
+  .type  test_brab, %function
+test_brab:
+  brab x0, x1
+
+  .globl test_braaz
+  .type  test_braaz, %function
+test_braaz:
+  braaz x0
+
+  .globl test_brabz
+  .type  test_brabz, %function
+test_brabz:
+  brabz x0
+
   .section .rodata,"a", at progbits
 datatable:
   .word test1_0-datatable

``````````

</details>


https://github.com/llvm/llvm-project/pull/129898


More information about the llvm-commits mailing list