llvm-project/llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll
Simon Tatham edf21314c9
[AArch64][v8.5A] Omit BTI for non-addr-taken static fns in ELF (#135043)
This follows up commit 7af2b51e761f499, which removed the BTI at the
start of functions with internal linkage (provided they weren't
indirectly called inside the translation unit) for Linux targets.

Now we leave out the BTI for any ELF target, including bare-metal,
because the AAELF64 document in the Arm ABI has been updated to make the
same guarantee as SYSVABI64: if the linker wants to insert an indirect
branch at link time (e.g. as part of a long branch thunk) it's
responsible for making a BTI-equipped landing pad.

That was too difficult to test in the existing codegen test
`patchable-function-entry-bti.ll`, because so much of LLVM's detailed
asm output changes for non-ELF targets. So I've simplified that back to
how it was before 7af2b51e761f499 (except that now it expects no BTI in
the disputed function), and made a new test checking specifically the
difference in BTI between the formats.
2025-04-10 17:08:45 +01:00

105 lines
3.1 KiB
LLVM

; RUN: llc -mtriple=aarch64 -aarch64-min-jump-table-entries=4 %s -o - | FileCheck %s
define void @f0() "patchable-function-entry"="0" "branch-target-enforcement" {
; CHECK-LABEL: f0:
; CHECK-NEXT: .Lfunc_begin0:
; CHECK: // %bb.0:
; CHECK-NEXT: hint #34
; CHECK-NEXT: ret
; CHECK-NOT: .section __patchable_function_entries
ret void
}
;; -fpatchable-function-entry=1 -mbranch-protection=bti
;; For M=0, place the label .Lpatch0 after the initial BTI.
define void @f1() "patchable-function-entry"="1" "branch-target-enforcement" {
; CHECK-LABEL: f1:
; CHECK-NEXT: .Lfunc_begin1:
; CHECK-NEXT: .cfi_startproc
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: hint #34
; CHECK-NEXT: .Lpatch0:
; CHECK-NEXT: nop
; CHECK-NEXT: ret
; CHECK: .section __patchable_function_entries,"awo",@progbits,f1{{$}}
; CHECK-NEXT: .p2align 3
; CHECK-NEXT: .xword .Lpatch0
ret void
}
;; -fpatchable-function-entry=2,1 -mbranch-protection=bti
define void @f2_1() "patchable-function-entry"="1" "patchable-function-prefix"="1" "branch-target-enforcement" {
; CHECK-LABEL: .type f2_1,@function
; CHECK-NEXT: .Ltmp0:
; CHECK-NEXT: nop
; CHECK-NEXT: f2_1:
; CHECK-NEXT: .Lfunc_begin2:
; CHECK-NEXT: .cfi_startproc
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: hint #34
; CHECK-NEXT: nop
; CHECK-NEXT: ret
; CHECK: .Lfunc_end2:
; CHECK-NEXT: .size f2_1, .Lfunc_end2-f2_1
; CHECK: .section __patchable_function_entries,"awo",@progbits,f2_1{{$}}
; CHECK-NEXT: .p2align 3
; CHECK-NEXT: .xword .Ltmp0
ret void
}
;; -fpatchable-function-entry=1 -mbranch-protection=bti
;; We don't add BTI c, because the function has internal linkage
define internal void @f1i(i64 %v) "patchable-function-entry"="1" "branch-target-enforcement" {
; CHECK-LABEL: f1i:
; CHECK-NEXT: .Lfunc_begin3:
; CHECK: // %bb.0:
; CHECK-NEXT: nop
;; Other basic blocks have BTI, but they don't affect our decision to not create .Lpatch0
; CHECK: .LBB{{.+}} // %sw.bb1
; CHECK-NEXT: hint #36
; CHECK: .section __patchable_function_entries,"awo",@progbits,f1i{{$}}
; CHECK-NEXT: .p2align 3
; CHECK-NEXT: .xword .Lfunc_begin3
entry:
switch i64 %v, label %sw.bb0 [
i64 1, label %sw.bb1
i64 2, label %sw.bb2
i64 3, label %sw.bb3
i64 4, label %sw.bb4
]
sw.bb0:
call void asm sideeffect "nop", ""()
ret void
sw.bb1:
call void asm sideeffect "", ""()
ret void
sw.bb2:
call void asm sideeffect "", ""()
ret void
sw.bb3:
call void asm sideeffect "", ""()
ret void
sw.bb4:
call void asm sideeffect "", ""()
ret void
}
;; Test the interaction with -fsanitize=function.
; CHECK: .type sanitize_function,@function
; CHECK-NEXT: .Ltmp{{.*}}:
; CHECK-NEXT: nop
; CHECK-NEXT: .word 3238382334 // 0xc105cafe
; CHECK-NEXT: .word 42
; CHECK-NEXT: sanitize_function:
; CHECK-NEXT: .Lfunc_begin{{.*}}:
; CHECK-NEXT: .cfi_startproc
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: hint #34
; CHECK-NEXT: nop
; CHECK-NEXT: ret
define void @sanitize_function(ptr noundef %x) "patchable-function-prefix"="1" "patchable-function-entry"="1" "branch-target-enforcement" !func_sanitize !0 {
ret void
}
!0 = !{i32 3238382334, i32 42}