Skip to content

Commit cca40aa

Browse files
committed
[AArch64][v8.5A] Add BTI to all function starts
The existing BTI placement pass avoids inserting "BTI c" when the function has local linkage and is only directly called. However, even in this case, there is a (small) chance that the linker later adds a hunk with an indirect call to the function, e.g. if the function is placed in a separate section and moved far away from its callers. Make sure to add BTI for these functions too. Differential Revision: https://reviews.llvm.org/D99417
1 parent 7c4de2e commit cca40aa

File tree

3 files changed

+15
-9
lines changed

3 files changed

+15
-9
lines changed

llvm/lib/Target/AArch64/AArch64BranchTargets.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ bool AArch64BranchTargets::runOnMachineFunction(MachineFunction &MF) {
6464
LLVM_DEBUG(
6565
dbgs() << "********** AArch64 Branch Targets **********\n"
6666
<< "********** Function: " << MF.getName() << '\n');
67-
const Function &F = MF.getFunction();
6867

6968
// LLVM does not consider basic blocks which are the targets of jump tables
7069
// to be address-taken (the address can't escape anywhere else), but they are
@@ -78,13 +77,16 @@ bool AArch64BranchTargets::runOnMachineFunction(MachineFunction &MF) {
7877
bool MadeChange = false;
7978
for (MachineBasicBlock &MBB : MF) {
8079
bool CouldCall = false, CouldJump = false;
81-
// If the function is address-taken or externally-visible, it could be
82-
// indirectly called. PLT entries and tail-calls use BR, but when they are
80+
// Even in cases where a function has internal linkage and is only called
81+
// directly in its translation unit, it can still be called indirectly if
82+
// the linker decides to add a thunk to it for whatever reason (say, for
83+
// example, if it is finally placed far from its call site and a BL is not
84+
// long-range enough). PLT entries and tail-calls use BR, but when they are
8385
// are in guarded pages should all use x16 or x17 to hold the called
8486
// address, so we don't need to set CouldJump here. BR instructions in
8587
// non-guarded pages (which might be non-BTI-aware code) are allowed to
8688
// branch to a "BTI c" using any register.
87-
if (&MBB == &*MF.begin() && (F.hasAddressTaken() || !F.hasLocalLinkage()))
89+
if (&MBB == &*MF.begin())
8890
CouldCall = true;
8991

9092
// If the block itself is address-taken, it could be indirectly branched

llvm/test/CodeGen/AArch64/branch-target-enforcement.mir

+5-2
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,15 @@ body: |
116116
RET undef $lr, implicit killed $w0
117117
118118
---
119-
# Internal function, not address-taken in this module, so no BTI needed.
119+
# Internal function, not address-taken in this module, however the compiler
120+
# cannot 100% ensure that later parts of the toolchain won't add indirect
121+
# jumps. E.g. a linker adding a thunk to extend the range of a direct jump.
122+
# Therefore, even this case needs a BTI.
120123
name: simple_internal
121124
body: |
122125
bb.0.entry:
123126
; CHECK-LABEL: name: simple_internal
124-
; CHECK-NOT: HINT
127+
; CHECK: HINT 34
125128
; CHECK: RET
126129
$w0 = ORRWrs $wzr, $wzr, 0
127130
RET undef $lr, implicit killed $w0

llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll

+4-3
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,20 @@ define void @f2_1() "patchable-function-entry"="1" "patchable-function-prefix"="
4848
}
4949

5050
;; -fpatchable-function-entry=1 -mbranch-protection=bti
51-
;; For M=0, don't create .Lpatch0 if the initial instruction is not BTI,
52-
;; even if other basic blocks may have BTI.
51+
;; We add BTI c even when the function has internal linkage
5352
define internal void @f1i(i64 %v) "patchable-function-entry"="1" "branch-target-enforcement"="true" {
5453
; CHECK-LABEL: f1i:
5554
; CHECK-NEXT: .Lfunc_begin3:
5655
; CHECK: // %bb.0:
56+
; CHECK-NEXT: hint #34
57+
; CHECK-NEXT: .Lpatch1:
5758
; CHECK-NEXT: nop
5859
;; Other basic blocks have BTI, but they don't affect our decision to not create .Lpatch0
5960
; CHECK: .LBB{{.+}} // %sw.bb1
6061
; CHECK-NEXT: hint #36
6162
; CHECK: .section __patchable_function_entries,"awo",@progbits,f1i{{$}}
6263
; CHECK-NEXT: .p2align 3
63-
; CHECK-NEXT: .xword .Lfunc_begin3
64+
; CHECK-NEXT: .xword .Lpatch1
6465
entry:
6566
switch i64 %v, label %sw.bb0 [
6667
i64 1, label %sw.bb1

0 commit comments

Comments
 (0)