danielkiss updated this revision to Diff 247201.
danielkiss retitled this revision from "[Clang][AArch64] Add default arguments 
to runtime functions." to "[AArch64] Handle BTI/PAC in case of generated 
functions.".
danielkiss edited the summary of this revision.
danielkiss added a project: LLVM.
danielkiss added a comment.
Herald added subscribers: llvm-commits, hiraditya.

Previous version of the patch handled only the functions that are created in 
clang. Sanitizers can't see the codegen options therefore they also disables 
BTI.
This version of the patch is less invasive in my opinion, effects only aarch64.
branch-target-enforcement(BTI) and sign-return-address(PAC) are added to all 
function that comes from clang frontend.
If the backend encounters with the function without BTI attribute but the 
module is compiled with BTI then it assumes it should be made BTI compatible.


Repository:
  rG LLVM Github Monorepo

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").isStringAttribute() && (MF->getFunction().getFnAttribute("branch-target-enforcement").getValueAsString() == "true") }]>;
+  def NotUseBTI : Predicate<[{ !(MF->getFunction().getFnAttribute("branch-target-enforcement").isStringAttribute() && (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,9 @@
   NumBytesToCreateFrame += 4;
 
   bool HasBTI = any_of(RepeatedSequenceLocs, [](outliner::Candidate &C) {
-    return C.getMF()->getFunction().hasFnAttribute("branch-target-enforcement");
+    Attribute A =
+        C.getMF()->getFunction().getFnAttribute("branch-target-enforcement");
+    return A.isStringAttribute() && A.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"))
+  Attribute A = CallerF.getFnAttribute("branch-target-enforcement");
+  if (A.isStringAttribute() && A.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")) {
+  Attribute A = F.getFnAttribute("branch-target-enforcement");
+  if (A.isStringAttribute() && A.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,7 +58,13 @@
 
 bool AArch64BranchTargets::runOnMachineFunction(MachineFunction &MF) {
   const Function &F = MF.getFunction();
-  if (!F.hasFnAttribute("branch-target-enforcement"))
+
+  Attribute A = F.getFnAttribute("branch-target-enforcement");
+  if (A.isStringAttribute() && A.getValueAsString() == "false")
+    return false;
+
+  if (!F.hasFnAttribute("branch-target-enforcement") &&
+      !MF.getMMI().getModule()->getModuleFlag("branch-target-enforcement"))
     return false;
 
   LLVM_DEBUG(
Index: llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -187,19 +187,31 @@
     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;
+        if (!F.hasFnAttribute("branch-target-enforcement"))
+          return false;
+        Attribute A = F.getFnAttribute("branch-target-enforcement");
+        return !A.isStringAttribute() || A.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;
+        Attribute A = F.getFnAttribute("branch-target-enforcement");
+        return A.isStringAttribute() && A.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
@@ -5134,10 +5134,17 @@
                     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)
-      Fn->addFnAttr("branch-target-enforcement");
+      Fn->addFnAttr("branch-target-enforcement", "true");
+    else
+      Fn->addFnAttr("branch-target-enforcement", "false");
   }
   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

Reply via email to