Flags of the module derived exclusively from the compiler flag `-mbranch-protection`.
The note is generated based on the module flags accordingly.
After this change in case of compile unit without function won't have
the .note.gnu.property if the compiler flag is not present [1].
[1] https://bugs.llvm.org/show_bug.cgi?id=46480
Reviewed By: chill
Differential Revision: https://reviews.llvm.org/D80791
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;
-
- if (any_of(M, [](const Function &F) {
- return !F.isDeclaration() &&
- !F.hasFnAttribute("branch-target-enforcement");
- })) {
- 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");
- })) {
- errs() << "warning: some functions compiled with BTI and some compiled "
- "without BTI\n"
- << "warning: not setting BTI in feature flags\n";
- }
-
- if (any_of(M, [](const Function &F) {
- if (F.isDeclaration())
- return false;
- Attribute A = F.getFnAttribute("sign-return-address");
- return !A.isStringAttribute() || A.getValueAsString() == "none";
- })) {
- Flags &= ~ELF::GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
- }
+ unsigned Flags = 0;
+ if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
+ M.getModuleFlag("branch-target-enforcement")))
+ if (BTE->getZExtValue())
+ Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
+
+ if (const auto *Sign = mdconst::extract_or_null<ConstantInt>(
+ M.getModuleFlag("sign-return-address")))
+ if (Sign->getZExtValue())
+ Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
if (Flags == 0)
return;
attributes #0 = { "branch-target-enforcement"="true" }
+!llvm.module.flags = !{!0, !1, !2, !3}
+
+!0 = !{i32 1, !"branch-target-enforcement", i32 1}
+!1 = !{i32 1, !"sign-return-address", i32 1}
+!2 = !{i32 1, !"sign-return-address-all", i32 0}
+!3 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
+
; Both attributes present in a file with no functions.
; ASM: .word 3221225472
; ASM-NEXT: .word 4
; RUN: llc -mtriple=aarch64-linux %s -filetype=obj -o - | \
; RUN: llvm-readelf --notes - | FileCheck %s --check-prefix=OBJ
-define dso_local i32 @f() #0 {
+define dso_local i32 @f() {
entry:
ret i32 0
}
-attributes #0 = { "branch-target-enforcement"="true" }
+!llvm.module.flags = !{!0, !1, !2, !3}
+
+!0 = !{i32 1, !"branch-target-enforcement", i32 1}
+!1 = !{i32 1, !"sign-return-address", i32 0}
+!2 = !{i32 1, !"sign-return-address-all", i32 0}
+!3 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
; BTI attribute present
; ASM: .word 3221225472
; RUN: llc -mtriple=aarch64-linux %s -filetype=obj -o - | \
; RUN: llvm-readelf --notes - | FileCheck %s --check-prefix=OBJ
-define dso_local i32 @f() #0 {
+define dso_local i32 @f() {
entry:
ret i32 0
}
-attributes #0 = { "sign-return-address"="all" }
+!llvm.module.flags = !{!0, !1, !2, !3}
+
+!0 = !{i32 1, !"branch-target-enforcement", i32 0}
+!1 = !{i32 1, !"sign-return-address", i32 1}
+!2 = !{i32 1, !"sign-return-address-all", i32 0}
+!3 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
; PAC attribute present
; ASM: .word 3221225472
; RUN: llc -mtriple=aarch64-linux %s -filetype=obj -o - | \
; RUN: llvm-readelf --notes - | FileCheck %s --check-prefix=OBJ
-define dso_local i32 @f() #0 {
+define dso_local i32 @f() {
entry:
ret i32 0
}
-attributes #0 = { "branch-target-enforcement"="true" "sign-return-address"="non-leaf" }
+!llvm.module.flags = !{!0, !1, !2, !3}
+
+!0 = !{i32 1, !"branch-target-enforcement", i32 1}
+!1 = !{i32 1, !"sign-return-address", i32 1}
+!2 = !{i32 1, !"sign-return-address-all", i32 0}
+!3 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
; Both attribute present
; ASM: .word 3221225472
; 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:
attributes #1 = { "branch-target-enforcement"="true" }
-; Only the common atttribute (BTI)
-; ASM: .word 3221225472
-; ASM-NEXT: .word 4
-; ASM-NEXT: .word 1
+!llvm.module.flags = !{!0, !1, !2, !3}
-; OBJ: Properties: aarch64 feature: BTI
+!0 = !{i32 1, !"branch-target-enforcement", i32 0}
+!1 = !{i32 1, !"sign-return-address", i32 0}
+!2 = !{i32 1, !"sign-return-address-all", i32 0}
+!3 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
+
+; Note is not emited if module has no properties
+; ASM-NOT: .note.gnu.property
\ No newline at end of file
+++ /dev/null
-; RUN: llc -mtriple=aarch64-linux %s -o - 2>&1 | \
-; 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() #1 {
-entry:
- ret i32 0
-}
-
-attributes #0 = { "branch-target-enforcement"="true" "sign-return-address"="non-leaf" }
-
-attributes #1 = { "sign-return-address"="all" }
-
-; Only the common atttribute (PAC)
-; ASM: warning: not setting BTI in feature flags
-; ASM: .word 3221225472
-; ASM-NEXT: .word 4
-; ASM-NEXT: .word 2
-
-; OBJ: Properties: aarch64 feature: PAC
+++ /dev/null
-; 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 -S - | FileCheck %s --check-prefix=OBJ
-
-define dso_local i32 @f() #0 {
-entry:
- ret i32 0
-}
-
-define dso_local i32 @g() #1 {
-entry:
- ret i32 0
-}
-
-attributes #0 = { "sign-return-address"="non-leaf" }
-
-attributes #1 = { "sign-return-address"="none" }
-
-; No common attribute, no note section
-; ASM-NOT: .note.gnu.property
-; OBJ-NOT: .note.gnu.property
+++ /dev/null
-; RUN: llc -mtriple=aarch64-linux %s -o - 2>&1 | \
-; RUN: FileCheck %s --check-prefix=ASM
-; RUN: llc -mtriple=aarch64-linux %s -filetype=obj -o - | \
-; RUN: llvm-readelf -S - | FileCheck %s --check-prefix=OBJ
-
-define dso_local i32 @f() #0 {
-entry:
- ret i32 0
-}
-
-define dso_local i32 @g() #1 {
-entry:
- ret i32 0
-}
-
-attributes #0 = { "sign-return-address"="non-leaf" }
-
-attributes #1 = { "branch-target-enforcement"="true" }
-
-; No common attribute, no note section
-; ASM: warning: not setting BTI in feature flags
-; ASM-NOT: .note.gnu.property
-; OBJ-NOT: .note.gnu.property
+++ /dev/null
-; 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:
- %r = tail call i32 @g()
- ret i32 %r
-}
-
-declare dso_local i32 @g()
-
-attributes #0 = { "branch-target-enforcement"="true" }
-
-; Declarations don't prevent setting BTI
-; ASM: .word 3221225472
-; ASM-NEXT: .word 4
-; ASM-NEXT: .word 1
-
-; OBJ: Properties: aarch64 feature: BTI