diff options
| author | Momchil Velikov <momchil.velikov@arm.com> | 2019-12-13 17:37:22 +0000 | 
|---|---|---|
| committer | Momchil Velikov <momchil.velikov@arm.com> | 2019-12-13 17:38:20 +0000 | 
| commit | d53e61863d48a07ce285d5b0a36abc67583023bd (patch) | |
| tree | 8bde0f4b031e8478cd9e27c208a368398db5171f | |
| parent | f99eedeb72644671cd584f48e4c136d47f6b0020 (diff) | |
| download | bcm5719-llvm-d53e61863d48a07ce285d5b0a36abc67583023bd.tar.gz bcm5719-llvm-d53e61863d48a07ce285d5b0a36abc67583023bd.zip  | |
[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
10 files changed, 245 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 7ea7915c2ca..11f3273760d 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -84,6 +84,7 @@ public:      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 @@ private:  } // 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 00000000000..cd5b99765d1 --- /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 +@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 00000000000..3be74976172 --- /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 00000000000..bb63a862976 --- /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 00000000000..98a8e5e758d --- /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 00000000000..b9179fd26ae --- /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 00000000000..8959c16a13a --- /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 00000000000..b57a23b97b2 --- /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 00000000000..b663dafe44c --- /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 00000000000..1e9497bd856 --- /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  | 

