[llvm] d53e618 - [AArch64] Emit PAC/BTI .note.gnu.property flags

Momchil Velikov via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 13 09:39:00 PST 2019


Author: Momchil Velikov
Date: 2019-12-13T17:38:20Z
New Revision: d53e61863d48a07ce285d5b0a36abc67583023bd

URL: https://github.com/llvm/llvm-project/commit/d53e61863d48a07ce285d5b0a36abc67583023bd
DIFF: https://github.com/llvm/llvm-project/commit/d53e61863d48a07ce285d5b0a36abc67583023bd.diff

LOG: [AArch64] Emit PAC/BTI .note.gnu.property flags

This patch make LLVM emit the processor specific program property types
defined in AArch64 ELF spec
https://developer.arm.com/docs/ihi0056/f/elf-for-the-arm-64-bit-architecture-aarch64-abi-2019q2-documentation

A file containing no functions gets both property flags.  Otherwise, a property
is set iff all the functions in the file have the corresponding attribute.

Patch by Daniel Kiss and Momchil Velikov.

Differential Revision: https://reviews.llvm.org/D71019

Added: 
    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

Modified: 
    llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index 7ea7915c2ca6..11f3273760d3 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -84,6 +84,7 @@ class AArch64AsmPrinter : public AsmPrinter {
     return MCInstLowering.lowerOperand(MO, MCOp);
   }
 
+  void EmitStartOfAsmFile(Module &M) override;
   void EmitJumpTableInfo() override;
   void emitJumpTableEntry(const MachineJumpTableInfo *MJTI,
                           const MachineBasicBlock *MBB, unsigned JTI);
@@ -181,6 +182,65 @@ class AArch64AsmPrinter : public AsmPrinter {
 
 } // end anonymous namespace
 
+void AArch64AsmPrinter::EmitStartOfAsmFile(Module &M) {
+  if (!TM.getTargetTriple().isOSBinFormatELF())
+    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;
+  }
+
+  if (Flags == 0)
+    return;
+
+  // Emit a .note.gnu.property section with the flags.
+  MCSection *Cur = OutStreamer->getCurrentSectionOnly();
+  MCSection *Nt = MMI->getContext().getELFSection(
+      ".note.gnu.property", ELF::SHT_NOTE, ELF::SHF_ALLOC);
+  OutStreamer->SwitchSection(Nt);
+
+  // Emit the note header.
+  EmitAlignment(Align(8));
+  OutStreamer->EmitIntValue(4, 4);     // data size for "GNU\0"
+  OutStreamer->EmitIntValue(4 * 4, 4); // Elf_Prop size
+  OutStreamer->EmitIntValue(ELF::NT_GNU_PROPERTY_TYPE_0, 4);
+  OutStreamer->EmitBytes(StringRef("GNU", 4)); // note name
+
+  // Emit the PAC/BTI properties.
+  OutStreamer->EmitIntValue(ELF::GNU_PROPERTY_AARCH64_FEATURE_1_AND, 4);
+  OutStreamer->EmitIntValue(4, 4);     // data size
+  OutStreamer->EmitIntValue(Flags, 4); // data
+  OutStreamer->EmitIntValue(0, 4);     // pad
+
+  OutStreamer->endSection(Nt);
+  OutStreamer->SwitchSection(Cur);
+}
+
 void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI)
 {
   EmitSled(MI, SledKind::FUNCTION_ENTER);

diff  --git a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-0.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-0.ll
new file mode 100644
index 000000000000..cd5b99765d1b
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-0.ll
@@ -0,0 +1,14 @@
+; 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
+ at x = common dso_local global i32 0, align 4
+
+attributes #0 = { "branch-target-enforcement" }
+
+; Both attributes present in a file with no functions.
+; ASM:	    .word	3221225472
+; ASM-NEXT:	.word	4
+; ASM-NEXT	.word	3
+
+; OBJ: Properties: aarch64 feature: BTI, PAC

diff  --git a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-1.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-1.ll
new file mode 100644
index 000000000000..3be749761726
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-1.ll
@@ -0,0 +1,18 @@
+; 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
+}
+
+attributes #0 = { "branch-target-enforcement" }
+
+; BTI attribute present
+; ASM:	    .word	3221225472
+; ASM-NEXT:	.word	4
+; ASM-NEXT	.word	1
+
+; OBJ: Properties: aarch64 feature: BTI

diff  --git a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll
new file mode 100644
index 000000000000..bb63a8629765
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll
@@ -0,0 +1,18 @@
+; 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
+}
+
+attributes #0 = { "sign-return-address"="all" }
+
+; PAC attribute present
+; ASM:	    .word	3221225472
+; ASM-NEXT:	.word	4
+; ASM-NEXT	.word	2
+
+; OBJ: Properties: aarch64 feature: PAC

diff  --git a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll
new file mode 100644
index 000000000000..98a8e5e758d3
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll
@@ -0,0 +1,18 @@
+; 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
+}
+
+attributes #0 = { "branch-target-enforcement" "sign-return-address"="non-leaf" }
+
+; Both attribute present
+; ASM:	    .word	3221225472
+; ASM-NEXT:	.word	4
+; ASM-NEXT	.word	3
+
+; OBJ: Properties: aarch64 feature: BTI, PAC

diff  --git a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll
new file mode 100644
index 000000000000..b9179fd26ae4
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll
@@ -0,0 +1,25 @@
+; 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() #1 {
+entry:
+  ret i32 0
+}
+
+attributes #0 = { "branch-target-enforcement" "sign-return-address"="non-leaf" }
+
+attributes #1 = { "branch-target-enforcement" }
+
+; Only the common atttribute (BTI)
+; ASM:	    .word	3221225472
+; ASM-NEXT:	.word	4
+; ASM-NEXT	.word	1
+
+; OBJ: Properties: aarch64 feature: BTI

diff  --git a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-5.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-5.ll
new file mode 100644
index 000000000000..8959c16a13a1
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-5.ll
@@ -0,0 +1,26 @@
+; 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" "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

diff  --git a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-6.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-6.ll
new file mode 100644
index 000000000000..b57a23b97b2c
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-6.ll
@@ -0,0 +1,22 @@
+; 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

diff  --git a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-7.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-7.ll
new file mode 100644
index 000000000000..b663dafe44c3
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-7.ll
@@ -0,0 +1,23 @@
+; 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" }
+
+; No common attribute, no note section
+; ASM: warning: not setting BTI in feature flags
+; ASM-NOT: .note.gnu.property
+; OBJ-NOT: .note.gnu.property

diff  --git a/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-8.ll b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-8.ll
new file mode 100644
index 000000000000..1e9497bd8566
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-8.ll
@@ -0,0 +1,21 @@
+; 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" }
+
+; Declarations don't prevent setting BTI
+; ASM:	    .word	3221225472
+; ASM-NEXT:	.word	4
+; ASM-NEXT	.word	1
+
+; OBJ: Properties: aarch64 feature: BTI


        


More information about the llvm-commits mailing list