Skip to content

Commit d54638b

Browse files
author
git apple-llvm automerger
committed
Merge commit 'edf21314c98a' from llvm.org/main into next
2 parents 5ee9740 + edf2131 commit d54638b

File tree

3 files changed

+56
-18
lines changed

3 files changed

+56
-18
lines changed

llvm/lib/Target/AArch64/AArch64BranchTargets.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,15 +86,14 @@ bool AArch64BranchTargets::runOnMachineFunction(MachineFunction &MF) {
8686
// non-guarded pages (which might be non-BTI-aware code) are allowed to
8787
// branch to a "BTI c" using any register.
8888
//
89-
// For SysV targets, this is enough, because SYSVABI64 says that if the
90-
// static linker later wants to use an indirect branch instruction in a
89+
// For ELF targets, this is enough, because AAELF64 says that if the static
90+
// linker later wants to use an indirect branch instruction in a
9191
// long-branch thunk, it's also responsible for adding a 'landing pad' with
92-
// a BTI, and pointing the indirect branch at that. However, at present
93-
// this guarantee only holds for targets complying with SYSVABI64, so for
94-
// other targets we must assume that `CouldCall` is _always_ true due to
95-
// the risk of long-branch thunks at link time.
92+
// a BTI, and pointing the indirect branch at that. For non-ELF targets we
93+
// can't rely on that, so we assume that `CouldCall` is _always_ true due
94+
// to the risk of long-branch thunks at link time.
9695
if (&MBB == &*MF.begin() &&
97-
(!MF.getSubtarget<AArch64Subtarget>().isTargetLinux() ||
96+
(!MF.getSubtarget<AArch64Subtarget>().isTargetELF() ||
9897
(F.hasAddressTaken() || !F.hasLocalLinkage())))
9998
CouldCall = true;
10099

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
; RUN: llc -mtriple=aarch64-linux-gnu %s -o - | FileCheck %s --check-prefixes=CHECK,NOBTI
2+
; RUN: llc -mtriple=aarch64-none-elf %s -o - | FileCheck %s --check-prefixes=CHECK,NOBTI
3+
; RUN: llc -mtriple=aarch64-none-macho %s -o - | FileCheck %s --check-prefixes=CHECK,BTI
4+
; RUN: llc -mtriple=aarch64-windows-msvc %s -o - | FileCheck %s --check-prefixes=CHECK,BTI
5+
6+
;; This function has internal linkage, and nothing in this translation unit
7+
;; calls it indirectly. So it doesn't need a BTI at the start ... except that
8+
;; it might, if at link time if the linker inserts a long-branch thunk using a
9+
;; BLR instruction.
10+
;;
11+
;; For ELF targets, both Linux and bare-metal, we expect no BTI instruction at
12+
;; the start of the function, because AAELF64 specifies that it's not needed:
13+
;; if the linker wants to do that then it's responsible for making a 'landing
14+
;; pad' near the target function which _does_ have a BTI, and pointing the
15+
;; indirect call at that.
16+
;;
17+
;; But this is specified in AAELF64, so non-ELF targets can't rely on that
18+
;; guarantee, and we expect LLVM to insert the BTI anyway.
19+
define internal void @internal_linkage() "branch-target-enforcement" {
20+
; CHECK-LABEL: internal_linkage:
21+
; BTI: hint #34
22+
; NOBTI-NOT: hint #34
23+
; CHECK: ret
24+
entry:
25+
ret void
26+
}
27+
28+
;; This function has internal linkage but _is_ potentially called indirectly
29+
;; (its address escapes from the module via external_linkage() below), so it
30+
;; needs a BTI irrespective of target triple.
31+
define internal void @indirectly_called() "branch-target-enforcement" {
32+
; CHECK-LABEL: indirectly_called:
33+
; CHECK: hint #34
34+
; CHECK: ret
35+
entry:
36+
ret void
37+
}
38+
39+
;; This function has external linkage, so it needs a BTI in all circumstances.
40+
define ptr @external_linkage() "branch-target-enforcement" {
41+
; CHECK-LABEL: external_linkage:
42+
; CHECK: hint #34
43+
; CHECK: ret
44+
entry:
45+
call void @internal_linkage()
46+
ret ptr @indirectly_called
47+
}

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

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
; RUN: llc -mtriple=aarch64-linux-gnu -aarch64-min-jump-table-entries=4 %s -o - | FileCheck %s --check-prefixes=CHECK,SYSV
2-
; RUN: llc -mtriple=aarch64-none-elf -aarch64-min-jump-table-entries=4 %s -o - | FileCheck %s --check-prefixes=CHECK,NONSYSV
1+
; RUN: llc -mtriple=aarch64 -aarch64-min-jump-table-entries=4 %s -o - | FileCheck %s
32

43
define void @f0() "patchable-function-entry"="0" "branch-target-enforcement" {
54
; CHECK-LABEL: f0:
@@ -49,25 +48,18 @@ define void @f2_1() "patchable-function-entry"="1" "patchable-function-prefix"="
4948
}
5049

5150
;; -fpatchable-function-entry=1 -mbranch-protection=bti
52-
;; For SysV compliant targets, we don't add BTI (or create the .Lpatch0 symbol)
53-
;; because the function has internal linkage and isn't address-taken. For
54-
;; non-SysV targets, we do add the BTI, because outside SYSVABI64 there's no
55-
;; spec preventing the static linker from using an indirect call instruction in
56-
;; a long-branch thunk inserted at link time.
51+
;; We don't add BTI c, because the function has internal linkage
5752
define internal void @f1i(i64 %v) "patchable-function-entry"="1" "branch-target-enforcement" {
5853
; CHECK-LABEL: f1i:
5954
; CHECK-NEXT: .Lfunc_begin3:
6055
; CHECK: // %bb.0:
61-
; NONSYSV-NEXT: hint #34
62-
; NONSYSV-NEXT: .Lpatch1:
6356
; CHECK-NEXT: nop
6457
;; Other basic blocks have BTI, but they don't affect our decision to not create .Lpatch0
6558
; CHECK: .LBB{{.+}} // %sw.bb1
6659
; CHECK-NEXT: hint #36
6760
; CHECK: .section __patchable_function_entries,"awo",@progbits,f1i{{$}}
6861
; CHECK-NEXT: .p2align 3
69-
; NONSYSV-NEXT: .xword .Lpatch1
70-
; SYSV-NEXT: .xword .Lfunc_begin3
62+
; CHECK-NEXT: .xword .Lfunc_begin3
7163
entry:
7264
switch i64 %v, label %sw.bb0 [
7365
i64 1, label %sw.bb1

0 commit comments

Comments
 (0)