From 4f2ee07454b0d0b156a728ca540f584310ef4a62 Mon Sep 17 00:00:00 2001 From: Anatoly Trosinenko Date: Mon, 17 Mar 2025 12:00:05 +0300 Subject: [PATCH] [BOLT][AArch64] Do not crash on authenticated branch instructions (#129898) 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. --- .../Target/AArch64/AArch64MCPlusBuilder.cpp | 17 ++++++++++++++ bolt/test/AArch64/test-indirect-branch.s | 23 ++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp index c03b4aedbec6..613b24c4553e 100644 --- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp +++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp @@ -547,6 +547,18 @@ public: return false; } + bool isBRA(const MCInst &Inst) const { + switch (Inst.getOpcode()) { + case AArch64::BRAA: + case AArch64::BRAB: + case AArch64::BRAAZ: + case AArch64::BRABZ: + return true; + default: + return false; + } + } + bool mayLoad(const MCInst &Inst) const override { return isLDRB(Inst) || isLDRH(Inst) || isLDRW(Inst) || isLDRX(Inst) || isLDRQ(Inst) || isLDRD(Inst) || isLDRS(Inst); @@ -941,6 +953,11 @@ public: DenseMap> &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 1e16e76b1153..b99737ee97ac 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",@progbits datatable: .word test1_0-datatable