danielkiss updated this revision to Diff 248201. danielkiss added a comment.
Thanks for the comments, patch is improved isStringAttribute() check removed, the attribute is always a string in this case or "null" so the check is not needed. Function level the attribute is now only change when needed, so as the function level attribute is expected to be rare I hope the performance won't be impacted by the patch. I kept the "tri-state" logic because of the emitted functions. Introducing a "branch-target-enforcement-disabled" attribute seems even more confusing for me. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75181/new/ https://reviews.llvm.org/D75181 Files: clang/lib/CodeGen/CGCall.cpp clang/lib/CodeGen/CGDeclCXX.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/CodeGen/TargetInfo.cpp clang/test/CodeGen/aarch64-branch-protection-attr.c clang/test/CodeGen/aarch64-sign-return-address.c clang/test/CodeGenCXX/aarch64-branch-target_clang_call_terminate.cpp clang/test/CodeGenCXX/aarch64-sign-return-address-static-ctor.cpp llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp llvm/lib/Target/AArch64/AArch64BranchTargets.cpp llvm/lib/Target/AArch64/AArch64CallLowering.cpp llvm/lib/Target/AArch64/AArch64InstrInfo.cpp llvm/lib/Target/AArch64/AArch64InstrInfo.td llvm/test/CodeGen/AArch64/branch-target-enforcement-indirect-calls.ll llvm/test/CodeGen/AArch64/branch-target-enforcement.mir llvm/test/CodeGen/AArch64/bti-branch-relaxation.ll llvm/test/CodeGen/AArch64/machine-outliner-bti.mir llvm/test/CodeGen/AArch64/machine-outliner-outline-bti.ll llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-0.ll llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-1.ll llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-5.ll llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-6.ll llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-7.ll llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-8.ll llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-9.ll llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll
Index: llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll =================================================================== --- llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll +++ llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll @@ -1,6 +1,6 @@ ; RUN: llc -mtriple=aarch64 %s -o - | FileCheck %s -define void @f0() "patchable-function-entry"="0" "branch-target-enforcement" { +define void @f0() "patchable-function-entry"="0" "branch-target-enforcement"="true" { ; CHECK-LABEL: f0: ; CHECK-NEXT: .Lfunc_begin0: ; CHECK: // %bb.0: @@ -12,7 +12,7 @@ ;; -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" { +define void @f1() "patchable-function-entry"="1" "branch-target-enforcement"="true" { ; CHECK-LABEL: f1: ; CHECK-NEXT: .Lfunc_begin1: ; CHECK-NEXT: .cfi_startproc @@ -28,7 +28,7 @@ } ;; -fpatchable-function-entry=2,1 -mbranch-protection=bti -define void @f2_1() "patchable-function-entry"="1" "patchable-function-prefix"="1" "branch-target-enforcement" { +define void @f2_1() "patchable-function-entry"="1" "patchable-function-prefix"="1" "branch-target-enforcement"="true" { ; CHECK-LABEL: .type f2_1,@function ; CHECK-NEXT: .Ltmp0: ; CHECK-NEXT: nop @@ -50,7 +50,7 @@ ;; -fpatchable-function-entry=1 -mbranch-protection=bti ;; For M=0, don't create .Lpatch0 if the initial instruction is not BTI, ;; even if other basic blocks may have BTI. -define internal void @f1i(i64 %v) "patchable-function-entry"="1" "branch-target-enforcement" { +define internal void @f1i(i64 %v) "patchable-function-entry"="1" "branch-target-enforcement"="true" { ; CHECK-LABEL: f1i: ; CHECK-NEXT: .Lfunc_begin3: ; CHECK: // %bb.0: Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-9.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-9.ll @@ -0,0 +1,27 @@ +; RUN: llc -mtriple=aarch64-linux %s -o - | \ +; RUN: FileCheck %s --check-prefix=ASM +; RUN: llc -mtriple=aarch64-linux %s -filetype=obj -o - | \ +; RUN: llvm-readelf --notes | FileCheck %s --check-prefix=OBJ + +define dso_local i32 @f() #0 { +entry: + ret i32 0 +} + +define dso_local i32 @g() { +entry: + ret i32 0 +} + +attributes #0 = { "branch-target-enforcement"="true" } + +!llvm.module.flags = !{!0} + +!0 = !{i32 4, !"branch-target-enforcement", i32 1} + +; Only the common atttribute (BTI) +; ASM: .word 3221225472 +; ASM-NEXT: .word 4 +; ASM-NEXT .word 1 + +; OBJ: Properties: aarch64 feature: BTI Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-8.ll =================================================================== --- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-8.ll +++ llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-8.ll @@ -11,7 +11,11 @@ declare dso_local i32 @g() -attributes #0 = { "branch-target-enforcement" } +attributes #0 = { "branch-target-enforcement"="true" } + +!llvm.module.flags = !{!0} + +!0 = !{i32 4, !"branch-target-enforcement", i32 1} ; Declarations don't prevent setting BTI ; ASM: .word 3221225472 Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-7.ll =================================================================== --- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-7.ll +++ llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-7.ll @@ -13,9 +13,13 @@ ret i32 0 } -attributes #0 = { "sign-return-address"="non-leaf" } +attributes #0 = { "branch-target-enforcement"="false" "sign-return-address"="non-leaf" } -attributes #1 = { "branch-target-enforcement" } +attributes #1 = { "branch-target-enforcement"="true" } + +!llvm.module.flags = !{!0} + +!0 = !{i32 4, !"branch-target-enforcement", i32 1} ; No common attribute, no note section ; ASM: warning: not setting BTI in feature flags Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-6.ll =================================================================== --- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-6.ll +++ llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-6.ll @@ -17,6 +17,11 @@ attributes #1 = { "sign-return-address"="none" } +!llvm.module.flags = !{!0} + +!0 = !{i32 4, !"sign-return-address", !"non-leaf"} + + ; No common attribute, no note section ; ASM-NOT: .note.gnu.property ; OBJ-NOT: .note.gnu.property Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-5.ll =================================================================== --- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-5.ll +++ llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-5.ll @@ -13,9 +13,15 @@ ret i32 0 } -attributes #0 = { "branch-target-enforcement" "sign-return-address"="non-leaf" } +attributes #0 = { "branch-target-enforcement"="true" "sign-return-address"="non-leaf" } + +attributes #1 = { "branch-target-enforcement"="false" "sign-return-address"="all" } + +!llvm.module.flags = !{!0, !1} + +!0 = !{i32 4, !"branch-target-enforcement", i32 1} +!1 = !{i32 4, !"sign-return-address", !"all"} -attributes #1 = { "sign-return-address"="all" } ; Only the common atttribute (PAC) ; ASM: warning: not setting BTI in feature flags Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll =================================================================== --- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll +++ llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll @@ -13,9 +13,13 @@ ret i32 0 } -attributes #0 = { "branch-target-enforcement" "sign-return-address"="non-leaf" } +attributes #0 = { "branch-target-enforcement"="true" "sign-return-address"="non-leaf" } -attributes #1 = { "branch-target-enforcement" } +attributes #1 = { "branch-target-enforcement"="true" } + +!llvm.module.flags = !{!0} + +!0 = !{i32 4, !"branch-target-enforcement", i32 1} ; Only the common atttribute (BTI) ; ASM: .word 3221225472 Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll =================================================================== --- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll +++ llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll @@ -8,7 +8,12 @@ ret i32 0 } -attributes #0 = { "branch-target-enforcement" "sign-return-address"="non-leaf" } +attributes #0 = { "branch-target-enforcement"="true" "sign-return-address"="non-leaf" } + +!llvm.module.flags = !{!0, !1} + +!0 = !{i32 4, !"branch-target-enforcement", i32 1} +!1 = !{i32 4, !"sign-return-address", !"non-leaf"} ; Both attribute present ; ASM: .word 3221225472 Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll =================================================================== --- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll +++ llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll @@ -10,6 +10,10 @@ attributes #0 = { "sign-return-address"="all" } +!llvm.module.flags = !{!0} + +!0 = !{i32 4, !"sign-return-address", !"all"} + ; PAC attribute present ; ASM: .word 3221225472 ; ASM-NEXT: .word 4 Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-1.ll =================================================================== --- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-1.ll +++ llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-1.ll @@ -8,7 +8,11 @@ ret i32 0 } -attributes #0 = { "branch-target-enforcement" } +attributes #0 = { "branch-target-enforcement"="true" } + +!llvm.module.flags = !{!0} + +!0 = !{i32 4, !"branch-target-enforcement", i32 1} ; BTI attribute present ; ASM: .word 3221225472 Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-0.ll =================================================================== --- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-0.ll +++ llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-0.ll @@ -4,7 +4,12 @@ ; RUN: llvm-readelf --notes | FileCheck %s --check-prefix=OBJ @x = common dso_local global i32 0, align 4 -attributes #0 = { "branch-target-enforcement" } +attributes #0 = { "branch-target-enforcement"="true" } + +!llvm.module.flags = !{!0, !1} + +!0 = !{i32 4, !"branch-target-enforcement", i32 1} +!1 = !{i32 4, !"sign-return-address", !"all"} ; Both attributes present in a file with no functions. ; ASM: .word 3221225472 Index: llvm/test/CodeGen/AArch64/machine-outliner-outline-bti.ll =================================================================== --- llvm/test/CodeGen/AArch64/machine-outliner-outline-bti.ll +++ llvm/test/CodeGen/AArch64/machine-outliner-outline-bti.ll @@ -5,7 +5,7 @@ @g = hidden global i32 0, align 4 -define hidden void @foo() minsize "branch-target-enforcement" { +define hidden void @foo() minsize "branch-target-enforcement"="true" { entry: ; CHECK: hint #34 ; CHECK: b OUTLINED_FUNCTION_0 @@ -13,10 +13,10 @@ ret void } -define hidden void @bar() minsize "branch-target-enforcement" { +define hidden void @bar() minsize "branch-target-enforcement"="true" { entry: ; CHECK: hint #34 ; CHECK: b OUTLINED_FUNCTION_0 store volatile i32 1, i32* @g, align 4 ret void -} +} \ No newline at end of file Index: llvm/test/CodeGen/AArch64/machine-outliner-bti.mir =================================================================== --- llvm/test/CodeGen/AArch64/machine-outliner-bti.mir +++ llvm/test/CodeGen/AArch64/machine-outliner-bti.mir @@ -15,7 +15,7 @@ --- | @g = hidden local_unnamed_addr global i32 0, align 4 - define hidden void @bar(void ()* nocapture %f) "branch-target-enforcement" { + define hidden void @bar(void ()* nocapture %f) "branch-target-enforcement"="true" { entry: ret void } Index: llvm/test/CodeGen/AArch64/bti-branch-relaxation.ll =================================================================== --- llvm/test/CodeGen/AArch64/bti-branch-relaxation.ll +++ llvm/test/CodeGen/AArch64/bti-branch-relaxation.ll @@ -61,4 +61,4 @@ declare dso_local i64 @llvm.aarch64.space(i32, i64) local_unnamed_addr #0 -attributes #0 = { nounwind "branch-target-enforcement" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+neon,+v8.5a" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #0 = { nounwind "branch-target-enforcement"="true" "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+neon,+v8.5a" "unsafe-fp-math"="false" "use-soft-float"="false" } Index: llvm/test/CodeGen/AArch64/branch-target-enforcement.mir =================================================================== --- llvm/test/CodeGen/AArch64/branch-target-enforcement.mir +++ llvm/test/CodeGen/AArch64/branch-target-enforcement.mir @@ -3,29 +3,29 @@ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" target triple = "aarch64-arm-none-eabi" - define hidden i32 @simple_external() "branch-target-enforcement" { + define hidden i32 @simple_external() "branch-target-enforcement"="true" { entry: ret i32 0 } - define internal i32 @simple_internal() "branch-target-enforcement" { + define internal i32 @simple_internal() "branch-target-enforcement"="true" { entry: ret i32 0 } - define hidden i32 @ptr_auth() "branch-target-enforcement" { + define hidden i32 @ptr_auth() "branch-target-enforcement"="true" { entry: tail call void asm sideeffect "", "~{lr}"() ret i32 0 } - define hidden i32 @ptr_auth_b() "branch-target-enforcement" { + define hidden i32 @ptr_auth_b() "branch-target-enforcement"="true" { entry: tail call void asm sideeffect "", "~{lr}"() ret i32 0 } - define hidden i32 @jump_table(i32 %a) "branch-target-enforcement" { + define hidden i32 @jump_table(i32 %a) "branch-target-enforcement"="true" { entry: switch i32 %a, label %sw.epilog [ i32 1, label %sw.bb @@ -61,7 +61,7 @@ @label_address.addr = internal unnamed_addr global i8* blockaddress(@label_address, %return), align 8 - define hidden i32 @label_address() "branch-target-enforcement" { + define hidden i32 @label_address() "branch-target-enforcement"="true" { entry: %0 = load i8*, i8** @label_address.addr, align 8 indirectbr i8* %0, [label %return, label %lab2] @@ -79,7 +79,7 @@ ret i32 %merge2 } - define hidden i32 @label_address_entry() "branch-target-enforcement" { + define hidden i32 @label_address_entry() "branch-target-enforcement"="true" { entry: %0 = load i8*, i8** @label_address.addr, align 8 indirectbr i8* %0, [label %return, label %lab2] @@ -97,7 +97,7 @@ ret i32 %merge2 } - define hidden i32 @debug_ptr_auth() "branch-target-enforcement" { + define hidden i32 @debug_ptr_auth() "branch-target-enforcement"="true" { entry: tail call void asm sideeffect "", "~{lr}"() ret i32 0 Index: llvm/test/CodeGen/AArch64/branch-target-enforcement-indirect-calls.ll =================================================================== --- llvm/test/CodeGen/AArch64/branch-target-enforcement-indirect-calls.ll +++ llvm/test/CodeGen/AArch64/branch-target-enforcement-indirect-calls.ll @@ -20,7 +20,7 @@ ret void } -define void @bti_enabled(void ()* %p) "branch-target-enforcement" { +define void @bti_enabled(void ()* %p) "branch-target-enforcement"="true" { entry: tail call void %p() ; CHECK: br {{x16|x17}} Index: llvm/lib/Target/AArch64/AArch64InstrInfo.td =================================================================== --- llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -570,8 +570,8 @@ // Avoid generating STRQro if it is slow, unless we're optimizing for code size. def UseSTRQro : Predicate<"!Subtarget->isSTRQroSlow() || shouldOptForSize(MF)">; - def UseBTI : Predicate<[{ MF->getFunction().hasFnAttribute("branch-target-enforcement") }]>; - def NotUseBTI : Predicate<[{ !MF->getFunction().hasFnAttribute("branch-target-enforcement") }]>; + def UseBTI : Predicate<[{ MF->getFunction().getFnAttribute("branch-target-enforcement").getValueAsString() == "true" }]>; + def NotUseBTI : Predicate<[{ !(MF->getFunction().getFnAttribute("branch-target-enforcement").getValueAsString() == "true") }]>; // Toggles patterns which aren't beneficial in GlobalISel when we aren't // optimizing. This allows us to selectively use patterns without impacting Index: llvm/lib/Target/AArch64/AArch64InstrInfo.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -5859,7 +5859,10 @@ NumBytesToCreateFrame += 4; bool HasBTI = any_of(RepeatedSequenceLocs, [](outliner::Candidate &C) { - return C.getMF()->getFunction().hasFnAttribute("branch-target-enforcement"); + return C.getMF() + ->getFunction() + .getFnAttribute("branch-target-enforcement") + .getValueAsString() == "true"; }); // Returns true if an instructions is safe to fix up, false otherwise. Index: llvm/lib/Target/AArch64/AArch64CallLowering.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64CallLowering.cpp +++ llvm/lib/Target/AArch64/AArch64CallLowering.cpp @@ -762,7 +762,8 @@ // When BTI is enabled, we need to use TCRETURNriBTI to make sure that we use // x16 or x17. - if (CallerF.hasFnAttribute("branch-target-enforcement")) + if (CallerF.getFnAttribute("branch-target-enforcement").getValueAsString() == + "true") return AArch64::TCRETURNriBTI; return AArch64::TCRETURNri; @@ -782,7 +783,8 @@ // TODO: Right now, regbankselect doesn't know how to handle the rtcGPR64 // register class. Until we can do that, we should fall back here. - if (F.hasFnAttribute("branch-target-enforcement")) { + if (F.getFnAttribute("branch-target-enforcement").getValueAsString() == + "true") { LLVM_DEBUG( dbgs() << "Cannot lower indirect tail calls with BTI enabled yet.\n"); return false; Index: llvm/lib/Target/AArch64/AArch64BranchTargets.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64BranchTargets.cpp +++ llvm/lib/Target/AArch64/AArch64BranchTargets.cpp @@ -58,8 +58,18 @@ bool AArch64BranchTargets::runOnMachineFunction(MachineFunction &MF) { const Function &F = MF.getFunction(); - if (!F.hasFnAttribute("branch-target-enforcement")) - return false; + + // LLVM emmited function won't have the attribute. + if (!F.hasFnAttribute("branch-target-enforcement")) { + // Fall back to the module flag, add BTI if the module is compiled with it. + if (!MF.getMMI().getModule()->getModuleFlag("branch-target-enforcement")) + return false; + } else { + // Explicitly requested to not generate BTI. + if (F.getFnAttribute("branch-target-enforcement").getValueAsString() == + "false") + return false; + } LLVM_DEBUG( dbgs() << "********** AArch64 Branch Targets **********\n" Index: llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -187,19 +187,29 @@ return; // Assemble feature flags that may require creation of a note section. - unsigned Flags = ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI | - ELF::GNU_PROPERTY_AARCH64_FEATURE_1_PAC; + unsigned Flags = 0; + if (M.getModuleFlag("branch-target-enforcement")) + Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI; + if (M.getModuleFlag("sign-return-address")) + Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_PAC; if (any_of(M, [](const Function &F) { - return !F.isDeclaration() && - !F.hasFnAttribute("branch-target-enforcement"); + if (F.isDeclaration()) + return false; + return F.getFnAttribute("branch-target-enforcement") + .getValueAsString() == "false"; })) { Flags &= ~ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI; } if ((Flags & ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI) == 0 && any_of(M, [](const Function &F) { - return F.hasFnAttribute("branch-target-enforcement"); + if (F.isDeclaration()) + return false; + if (!F.hasFnAttribute("branch-target-enforcement")) + return false; + return F.getFnAttribute("branch-target-enforcement") + .getValueAsString() == "true"; })) { errs() << "warning: some functions compiled with BTI and some compiled " "without BTI\n" Index: clang/test/CodeGenCXX/aarch64-sign-return-address-static-ctor.cpp =================================================================== --- clang/test/CodeGenCXX/aarch64-sign-return-address-static-ctor.cpp +++ clang/test/CodeGenCXX/aarch64-sign-return-address-static-ctor.cpp @@ -38,4 +38,4 @@ // CHECK-ALL: "sign-return-address"="all" // CHECK-A-KEY: "sign-return-address-key"="a_key" // CHECK-B-KEY: "sign-return-address-key"="b_key" -// CHECK-BTE: "branch-target-enforcement" +// CHECK-BTE: "branch-target-enforcement"="true" Index: clang/test/CodeGenCXX/aarch64-branch-target_clang_call_terminate.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/aarch64-branch-target_clang_call_terminate.cpp @@ -0,0 +1,34 @@ +// RUN: %clang -target aarch64-linux-android -mbranch-protection=none -c %s -o - | \ +// RUN: llvm-objdump -d -mattr=+bti - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NONE +// RUN: %clang -target aarch64-linux-android -mbranch-protection=pac-ret -c %s -o - | \ +// RUN: llvm-objdump -d -mattr=+bti - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NONE +// RUN: %clang -target aarch64-linux-android -mbranch-protection=pac-ret+leaf -c %s -o - | \ +// RUN: llvm-objdump -d -mattr=+bti - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NONE +// RUN: %clang -target aarch64-linux-android -mbranch-protection=pac-ret+b-key -c %s -o - | \ +// RUN: llvm-objdump -d -mattr=+bti - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NONE +// RUN: %clang -target aarch64-linux-android -mbranch-protection=pac-ret+b-key+leaf -c %s -o - | \ +// RUN: llvm-objdump -d -mattr=+bti - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NONE +// RUN: %clang -target aarch64-linux-android -mbranch-protection=standard -c %s -o - | \ +// RUN: llvm-objdump -d -mattr=+bti - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BTI +// RUN: %clang -target aarch64-linux-android -mbranch-protection=bti -c %s -o - | \ +// RUN: llvm-objdump -d -mattr=+bti - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BTI +// RUN: %clang -target aarch64-linux-android -mbranch-protection=pac-ret+b-key+leaf+bti -c %s -o - | \ +// RUN: llvm-objdump -d -mattr=+bti - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-BTI + +void a(); +void d(); + +void c() { + try { + d(); + } catch (...) { + a(); + } +} + +// CHECK-BTI: 0000000000000000 __clang_call_terminate: +// CHECK-BTI-NEXT: bti c +// CHECK-BTI-NEXT: str x30, [sp, #-16]! + +// CHECK-NONE: 0000000000000000 __clang_call_terminate: +// CHECK-NONE-NEXT: str x30, [sp, #-16]! Index: clang/test/CodeGen/aarch64-sign-return-address.c =================================================================== --- clang/test/CodeGen/aarch64-sign-return-address.c +++ clang/test/CodeGen/aarch64-sign-return-address.c @@ -18,7 +18,7 @@ // ALL: "sign-return-address"="all" -// BTE: "branch-target-enforcement" +// BTE: "branch-target-enforcement"="true" // A-KEY: "sign-return-address-key"="a_key" Index: clang/test/CodeGen/aarch64-branch-protection-attr.c =================================================================== --- clang/test/CodeGen/aarch64-branch-protection-attr.c +++ clang/test/CodeGen/aarch64-branch-protection-attr.c @@ -64,18 +64,18 @@ // NO-OVERRIDE: define void @btileaf() #[[#BTIPACLEAF:]] // OVERRIDE: define void @btileaf() #[[#BTIPACLEAF:]] -// CHECK-DAG: attributes #[[#NONE]] +// CHECK-DAG: attributes #[[#NONE]] = { {{.*}} "branch-target-enforcement"="false" -// CHECK-DAG: attributes #[[#STD]] = { {{.*}} "branch-target-enforcement" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" +// CHECK-DAG: attributes #[[#STD]] = { {{.*}} "branch-target-enforcement"="true" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" -// CHECK-DAG: attributes #[[#BTI]] = { {{.*}}"branch-target-enforcement" +// CHECK-DAG: attributes #[[#BTI]] = { {{.*}} "branch-target-enforcement"="true" -// CHECK-DAG: attributes #[[#PAC]] = { {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" +// CHECK-DAG: attributes #[[#PAC]] = { {{.*}} "branch-target-enforcement"="false" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="a_key" -// CHECK-DAG: attributes #[[#PACLEAF]] = { {{.*}} "sign-return-address"="all" "sign-return-address-key"="a_key" +// CHECK-DAG: attributes #[[#PACLEAF]] = { {{.*}} "branch-target-enforcement"="false" {{.*}} "sign-return-address"="all" "sign-return-address-key"="a_key" -// CHECK-DAG: attributes #[[#PACBKEY]] = { {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="b_key" +// CHECK-DAG: attributes #[[#PACBKEY]] = { {{.*}} "branch-target-enforcement"="false" {{.*}} "sign-return-address"="non-leaf" "sign-return-address-key"="b_key" -// CHECK-DAG: attributes #[[#PACBKEYLEAF]] = { {{.*}} "sign-return-address"="all" "sign-return-address-key"="b_key" +// CHECK-DAG: attributes #[[#PACBKEYLEAF]] = { {{.*}} "branch-target-enforcement"="false" {{.*}} "sign-return-address"="all" "sign-return-address-key"="b_key" -// CHECK-DAG: attributes #[[#BTIPACLEAF]] = { {{.*}}"branch-target-enforcement" {{.*}} "sign-return-address"="all" "sign-return-address-key"="a_key" +// CHECK-DAG: attributes #[[#BTIPACLEAF]] = { {{.*}}"branch-target-enforcement"="true" {{.*}} "sign-return-address"="all" "sign-return-address-key"="a_key" Index: clang/lib/CodeGen/TargetInfo.cpp =================================================================== --- clang/lib/CodeGen/TargetInfo.cpp +++ clang/lib/CodeGen/TargetInfo.cpp @@ -5106,38 +5106,53 @@ if (!FD) return; - CodeGenOptions::SignReturnAddressScope Scope = CGM.getCodeGenOpts().getSignReturnAddress(); - CodeGenOptions::SignReturnAddressKeyValue Key = CGM.getCodeGenOpts().getSignReturnAddressKey(); - bool BranchTargetEnforcement = CGM.getCodeGenOpts().BranchTargetEnforcement; if (const auto *TA = FD->getAttr<TargetAttr>()) { ParsedTargetAttr Attr = TA->parse(); if (!Attr.BranchProtection.empty()) { TargetInfo::BranchProtectionInfo BPI; StringRef Error; + + CodeGenOptions::SignReturnAddressScope Scope = + CGM.getCodeGenOpts().getSignReturnAddress(); + CodeGenOptions::SignReturnAddressKeyValue Key = + CGM.getCodeGenOpts().getSignReturnAddressKey(); + bool BranchTargetEnforcement = + CGM.getCodeGenOpts().BranchTargetEnforcement; + (void)CGM.getTarget().validateBranchProtection(Attr.BranchProtection, BPI, Error); assert(Error.empty()); - Scope = BPI.SignReturnAddr; - Key = BPI.SignKey; - BranchTargetEnforcement = BPI.BranchTargetEnforcement; + auto *Fn = cast<llvm::Function>(GV); + + // Update flags only when differ from the codegen flags. + if (Scope != BPI.SignReturnAddr || Key != BPI.SignKey) { + Scope = BPI.SignReturnAddr; + Key = BPI.SignKey; + if (Scope != CodeGenOptions::SignReturnAddressScope::None) { + Fn->addFnAttr("sign-return-address", + Scope == CodeGenOptions::SignReturnAddressScope::All + ? "all" + : "non-leaf"); + + Fn->addFnAttr("sign-return-address-key", + Key == CodeGenOptions::SignReturnAddressKeyValue::AKey + ? "a_key" + : "b_key"); + } else { + Fn->removeAttribute(llvm::AttributeList::FunctionIndex, + "sign-return-address"); + Fn->removeAttribute(llvm::AttributeList::FunctionIndex, + "sign-return-address-key"); + } + } + if (BranchTargetEnforcement != BPI.BranchTargetEnforcement) { + if (BPI.BranchTargetEnforcement) + Fn->addFnAttr("branch-target-enforcement", "true"); + else + Fn->addFnAttr("branch-target-enforcement", "false"); + } } } - - auto *Fn = cast<llvm::Function>(GV); - if (Scope != CodeGenOptions::SignReturnAddressScope::None) { - Fn->addFnAttr("sign-return-address", - Scope == CodeGenOptions::SignReturnAddressScope::All - ? "all" - : "non-leaf"); - - Fn->addFnAttr("sign-return-address-key", - Key == CodeGenOptions::SignReturnAddressKeyValue::AKey - ? "a_key" - : "b_key"); - } - - if (BranchTargetEnforcement) - Fn->addFnAttr("branch-target-enforcement"); } llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const override { Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -583,6 +583,27 @@ 1); } + if (CodeGenOpts.BranchTargetEnforcement) { + getModule().addModuleFlag(llvm::Module::Override, + "branch-target-enforcement", 1); + } + + CodeGenOptions::SignReturnAddressScope Scope = + CodeGenOpts.getSignReturnAddress(); + if (Scope != CodeGenOptions::SignReturnAddressScope::None) { + getModule().addModuleFlag( + llvm::Module::Override, "sign-return-address", + Scope == CodeGenOptions::SignReturnAddressScope::All + ? llvm::MDString::get(VMContext, "all") + : llvm::MDString::get(VMContext, "non-leaf")); + getModule().addModuleFlag( + llvm::Module::Override, "sign-return-address-key", + CodeGenOpts.getSignReturnAddressKey() == + CodeGenOptions::SignReturnAddressKeyValue::AKey + ? llvm::MDString::get(VMContext, "a_key") + : llvm::MDString::get(VMContext, "b_key")); + } + if (LangOpts.CUDAIsDevice && getTriple().isNVPTX()) { // Indicate whether __nvvm_reflect should be configured to flush denormal // floating point values to 0. (This corresponds to its "__CUDA_FTZ" Index: clang/lib/CodeGen/CGDeclCXX.cpp =================================================================== --- clang/lib/CodeGen/CGDeclCXX.cpp +++ clang/lib/CodeGen/CGDeclCXX.cpp @@ -406,7 +406,7 @@ } if (getCodeGenOpts().BranchTargetEnforcement) - Fn->addFnAttr("branch-target-enforcement"); + Fn->addFnAttr("branch-target-enforcement", "true"); return Fn; } Index: clang/lib/CodeGen/CGCall.cpp =================================================================== --- clang/lib/CodeGen/CGCall.cpp +++ clang/lib/CodeGen/CGCall.cpp @@ -1823,6 +1823,23 @@ std::tie(Var, Value) = Attr.split('='); FuncAttrs.addAttribute(Var, Value); } + + if (CodeGenOpts.BranchTargetEnforcement) { + FuncAttrs.addAttribute("branch-target-enforcement", "true"); + } + + auto RASignKind = CodeGenOpts.getSignReturnAddress(); + if (RASignKind != CodeGenOptions::SignReturnAddressScope::None) { + FuncAttrs.addAttribute( + "sign-return-address", + RASignKind == CodeGenOptions::SignReturnAddressScope::All ? "all" + : "non-leaf"); + auto RASignKey = CodeGenOpts.getSignReturnAddressKey(); + FuncAttrs.addAttribute( + "sign-return-address-key", + RASignKey == CodeGenOptions::SignReturnAddressKeyValue::AKey ? "a_key" + : "b_key"); + } } void CodeGenModule::AddDefaultFnAttrs(llvm::Function &F) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits