[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.
This commit is contained in:
parent
8cc6c2e80f
commit
4f2ee07454
@ -547,6 +547,18 @@ public:
|
|||||||
return false;
|
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 {
|
bool mayLoad(const MCInst &Inst) const override {
|
||||||
return isLDRB(Inst) || isLDRH(Inst) || isLDRW(Inst) || isLDRX(Inst) ||
|
return isLDRB(Inst) || isLDRH(Inst) || isLDRW(Inst) || isLDRX(Inst) ||
|
||||||
isLDRQ(Inst) || isLDRD(Inst) || isLDRS(Inst);
|
isLDRQ(Inst) || isLDRD(Inst) || isLDRS(Inst);
|
||||||
@ -941,6 +953,11 @@ public:
|
|||||||
DenseMap<const MCInst *, SmallVector<MCInst *, 4>> &UDChain,
|
DenseMap<const MCInst *, SmallVector<MCInst *, 4>> &UDChain,
|
||||||
const MCExpr *&JumpTable, int64_t &Offset, int64_t &ScaleValue,
|
const MCExpr *&JumpTable, int64_t &Offset, int64_t &ScaleValue,
|
||||||
MCInst *&PCRelBase) const {
|
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
|
// Expect AArch64 BR
|
||||||
assert(Inst.getOpcode() == AArch64::BR && "Unexpected opcode");
|
assert(Inst.getOpcode() == AArch64::BR && "Unexpected opcode");
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
// REQUIRES: system-linux, asserts
|
// 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: %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: llvm-bolt %t.exe -o %t.bolt --print-cfg --strict --debug-only=mcplus \
|
||||||
// RUN: -v=1 2>&1 | FileCheck %s
|
// RUN: -v=1 2>&1 | FileCheck %s
|
||||||
@ -73,6 +73,27 @@ test2_0:
|
|||||||
test2_1:
|
test2_1:
|
||||||
ret
|
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
|
.section .rodata,"a",@progbits
|
||||||
datatable:
|
datatable:
|
||||||
.word test1_0-datatable
|
.word test1_0-datatable
|
||||||
|
Loading…
x
Reference in New Issue
Block a user