summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorMomchil Velikov <momchil.velikov@arm.com>2019-12-13 17:37:22 +0000
committerMomchil Velikov <momchil.velikov@arm.com>2019-12-13 17:38:20 +0000
commitd53e61863d48a07ce285d5b0a36abc67583023bd (patch)
tree8bde0f4b031e8478cd9e27c208a368398db5171f /llvm/lib/Target
parentf99eedeb72644671cd584f48e4c136d47f6b0020 (diff)
downloadbcm5719-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.cpp60
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);
OpenPOWER on IntegriCloud