llvm-project/llvm/test/CodeGen/Thumb2/jump-table-bti.ll
Daniel Kiss 1782810b84 [Clang][ARM][AArch64] Alway emit protection attributes for functions. (#82819)
So far branch protection, sign return address, guarded control stack
attributes are
only emitted as module flags to indicate the functions need to be
generated with
those features.
The problem is in case of an LTO build the module flags are merged with
the `min`
rule which means if one of the module is not build with sign return
address then the features
will be turned off for all functions. Due to the functions take the
branch-protection and
sign-return-address features from the module flags. The
sign-return-address is
function level option therefore it is expected functions from files that
is
compiled with -mbranch-protection=pac-ret to be protected.
The inliner might inline functions with different set of flags as it
doesn't consider
the module flags.

This patch adds the attributes to all functions and drops the checking
of the module flags
for the code generation.
Module flag is still used for generating the ELF markers.
Also drops the "true"/"false" values from the
branch-protection-enforcement,
branch-protection-pauth-lr, guarded-control-stack attributes as presence
of the
attribute means it is on absence means off and no other option.

Releand with test fixes.
2024-07-10 11:32:41 +02:00

130 lines
5.8 KiB
LLVM

;; When BTI is enabled, keep the range check for a jump table for hardening,
;; even with an unreachable default.
;;
;; We check with and without the branch-target-enforcement module attribute,
;; and in each case, try overriding it with the opposite function attribute.
;; Expect to see a range check whenever there is BTI, and not where there
;; isn't.
; RUN: sed s/SPACE/4/ %s | sed '/test_jumptable/s/{/#1 {/' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-TBB
; RUN: sed s/SPACE/4/ %s | sed '/test_jumptable/s/{/#0 {/' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=NOBTI-TBB
; RUN: sed s/SPACE/4/ %s | sed '/^..for-non-bti-build-sed-will-delete-everything-after-this-line/q' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=NOBTI-TBB
; RUN: sed s/SPACE/4/ %s | sed '/test_jumptable/s/{/#1 {/' | sed '/^..for-non-bti-build-sed-will-delete-everything-after-this-line/q' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-TBB
; RUN: sed s/SPACE/400/ %s | sed '/test_jumptable/s/{/#1 {/' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-TBH
; RUN: sed s/SPACE/400/ %s | sed '/test_jumptable/s/{/#0 {/' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=NOBTI-TBH
; RUN: sed s/SPACE/400/ %s | sed '/^..for-non-bti-build-sed-will-delete-everything-after-this-line/q' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=NOBTI-TBH
; RUN: sed s/SPACE/400/ %s | sed '/test_jumptable/s/{/#1 {/' | sed '/^..for-non-bti-build-sed-will-delete-everything-after-this-line/q' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-TBH
; RUN: sed s/SPACE/400000/ %s | sed '/test_jumptable/s/{/#1 {/' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-MOV
; RUN: sed s/SPACE/400000/ %s | sed '/test_jumptable/s/{/#0 {/' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=NOBTI-MOV
; RUN: sed s/SPACE/400000/ %s | sed '/^..for-non-bti-build-sed-will-delete-everything-after-this-line/q' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=NOBTI-MOV
; RUN: sed s/SPACE/400000/ %s | sed '/test_jumptable/s/{/#1 {/' | sed '/^..for-non-bti-build-sed-will-delete-everything-after-this-line/q' | llc -mtriple=thumbv8.1m.main-linux-gnu -mattr=+pacbti -o - | FileCheck %s --check-prefix=BTI-MOV
declare i32 @llvm.arm.space(i32, i32)
attributes #0 = { norecurse }
attributes #1 = { norecurse "branch-target-enforcement" }
define ptr @test_jumptable(ptr %src, ptr %dst) {
entry:
%sw = load i32, ptr %src, align 4
%src.postinc = getelementptr inbounds i32, ptr %src, i32 1
switch i32 %sw, label %default [
i32 0, label %sw.0
i32 1, label %sw.1
i32 2, label %sw.2
i32 3, label %sw.3
]
sw.0:
%store.0 = call i32 @llvm.arm.space(i32 SPACE, i32 14142)
store i32 %store.0, ptr %dst, align 4
br label %exit
sw.1:
%store.1 = call i32 @llvm.arm.space(i32 SPACE, i32 31415)
%dst.1 = getelementptr inbounds i32, ptr %dst, i32 1
store i32 %store.1, ptr %dst.1, align 4
br label %exit
sw.2:
%store.2 = call i32 @llvm.arm.space(i32 SPACE, i32 27182)
%dst.2 = getelementptr inbounds i32, ptr %dst, i32 2
store i32 %store.2, ptr %dst.2, align 4
br label %exit
sw.3:
%store.3 = call i32 @llvm.arm.space(i32 SPACE, i32 16180)
%dst.3 = getelementptr inbounds i32, ptr %dst, i32 3
store i32 %store.3, ptr %dst.3, align 4
br label %exit
default:
unreachable
exit:
ret ptr %src.postinc
}
; NOBTI-TBB: test_jumptable:
; NOBTI-TBB-NEXT: .fnstart
; NOBTI-TBB-NEXT: @ %bb
; NOBTI-TBB-NEXT: ldr [[INDEX:r[0-9]+]], [r0], #4
; NOBTI-TBB-NEXT: .LCPI
; NOBTI-TBB-NEXT: tbb [pc, [[INDEX]]]
; BTI-TBB: test_jumptable:
; BTI-TBB-NEXT: .fnstart
; BTI-TBB-NEXT: @ %bb
; BTI-TBB-NEXT: bti
; BTI-TBB-NEXT: ldr [[INDEX:r[0-9]+]], [r0], #4
; BTI-TBB-NEXT: cmp [[INDEX]], #3
; BTI-TBB-NEXT: bhi .LBB
; BTI-TBB-NEXT: @ %bb
; BTI-TBB-NEXT: .LCPI
; BTI-TBB-NEXT: tbb [pc, [[INDEX]]]
; NOBTI-TBH: test_jumptable:
; NOBTI-TBH-NEXT: .fnstart
; NOBTI-TBH-NEXT: @ %bb
; NOBTI-TBH-NEXT: ldr [[INDEX:r[0-9]+]], [r0], #4
; NOBTI-TBH-NEXT: .LCPI
; NOBTI-TBH-NEXT: tbh [pc, [[INDEX]], lsl #1]
; BTI-TBH: test_jumptable:
; BTI-TBH-NEXT: .fnstart
; BTI-TBH-NEXT: @ %bb
; BTI-TBH-NEXT: bti
; BTI-TBH-NEXT: ldr [[INDEX:r[0-9]+]], [r0], #4
; BTI-TBH-NEXT: cmp [[INDEX]], #3
; BTI-TBH-NEXT: bhi.w .LBB
; BTI-TBH-NEXT: @ %bb
; BTI-TBH-NEXT: .LCPI
; BTI-TBH-NEXT: tbh [pc, [[INDEX]], lsl #1]
; NOBTI-MOV: test_jumptable:
; NOBTI-MOV-NEXT: .fnstart
; NOBTI-MOV-NEXT: @ %bb
; NOBTI-MOV-NEXT: ldr [[INDEX:r[0-9]+]], [r0], #4
; NOBTI-MOV-NEXT: adr.w [[ADDR:r[0-9]+]], .LJTI
; NOBTI-MOV-NEXT: add.w [[ADDR]], [[ADDR]], [[INDEX]], lsl #2
; NOBTI-MOV-NEXT: mov pc, [[ADDR]]
; BTI-MOV: test_jumptable:
; BTI-MOV-NEXT: .fnstart
; BTI-MOV-NEXT: @ %bb
; BTI-MOV-NEXT: bti
; BTI-MOV-NEXT: ldr [[INDEX:r[0-9]+]], [r0], #4
; BTI-MOV-NEXT: cmp [[INDEX]], #3
; BTI-MOV-NEXT: bls .LBB
; BTI-MOV-NEXT: b.w .LBB
; BTI-MOV-NEXT: .LBB
; BTI-MOV-NEXT: adr.w [[ADDR:r[0-9]+]], .LJTI
; BTI-MOV-NEXT: add.w [[ADDR]], [[ADDR]], [[INDEX]], lsl #2
; BTI-MOV-NEXT: mov pc, [[ADDR]]
; for-non-bti-build-sed-will-delete-everything-after-this-line
!llvm.module.flags = !{!0}
!0 = !{i32 8, !"branch-target-enforcement", i32 1}