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 /llvm/lib/Target | |
| 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
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 60 |
1 files changed, 60 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); |

