[llvm] 95e43f8 - [AArch64] Add -mmark-bti-property flag.
Daniel Kiss via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 16 15:24:23 PDT 2020
Author: Daniel Kiss
Date: 2020-09-17T00:24:14+02:00
New Revision: 95e43f84b7b9c61011aece7583c0367297dd67d8
URL: https://github.com/llvm/llvm-project/commit/95e43f84b7b9c61011aece7583c0367297dd67d8
DIFF: https://github.com/llvm/llvm-project/commit/95e43f84b7b9c61011aece7583c0367297dd67d8.diff
LOG: [AArch64] Add -mmark-bti-property flag.
Writing the .note.gnu.property manually is error prone and hard to
maintain in the assembly files.
The -mmark-bti-property is for the assembler to emit the section with the
GNU_PROPERTY_AARCH64_FEATURE_1_BTI. To be used when C/C++ is compiled
with -mbranch-protection=bti.
This patch refactors the .note.gnu.property handling.
Reviewed By: chill, nickdesaulniers
Differential Revision: https://reviews.llvm.org/D81930
Added:
clang/test/Driver/arm64-markbti.S
Modified:
clang/include/clang/Driver/Options.td
clang/lib/Driver/ToolChains/Clang.cpp
llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
Removed:
################################################################################
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 5b39ea513b24..d7c2496b8a5d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2385,6 +2385,9 @@ def mfix_cortex_a53_835769 : Flag<["-"], "mfix-cortex-a53-835769">,
def mno_fix_cortex_a53_835769 : Flag<["-"], "mno-fix-cortex-a53-835769">,
Group<m_aarch64_Features_Group>,
HelpText<"Don't workaround Cortex-A53 erratum 835769 (AArch64 only)">;
+def mmark_bti_property : Flag<["-"], "mmark-bti-property">,
+ Group<m_aarch64_Features_Group>,
+ HelpText<"Add .note.gnu.property with BTI to assembly files (AArch64 only)">;
foreach i = {1-31} in
def ffixed_x#i : Flag<["-"], "ffixed-x"#i>, Group<m_Group>,
HelpText<"Reserve the x"#i#" register (AArch64/RISC-V only)">;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 51056960761d..e13ffe67af89 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7018,6 +7018,15 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
}
break;
+ case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
+ case llvm::Triple::aarch64_be:
+ if (Args.hasArg(options::OPT_mmark_bti_property)) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-aarch64-mark-bti-property");
+ }
+ break;
+
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
AddRISCVTargetArgs(Args, CmdArgs);
diff --git a/clang/test/Driver/arm64-markbti.S b/clang/test/Driver/arm64-markbti.S
new file mode 100644
index 000000000000..68c81d31afa3
--- /dev/null
+++ b/clang/test/Driver/arm64-markbti.S
@@ -0,0 +1,24 @@
+// When -mmark-bti-property is passed the generated file object gets BTI marking.
+// RUN: %clang -target arm64-linux-none -mmark-bti-property -c -o - %s | llvm-readobj -n - | FileCheck -check-prefix=CHECK -check-prefix=CHECK_GEN %s
+// RUN: %clang -target arm64-linux-none -DNOTE_PRESENT -c %s -o - | llvm-readobj -n - | FileCheck -check-prefix=CHECK -check-prefix=CHECK_PRESET %s
+// RUN: %clang -target arm64-linux-none -mmark-bti-property -DNOTE_PRESENT -c %s -o - | llvm-readobj -n - | FileCheck -check-prefix=CHECK -check-prefix=CHECK_PRESET %s
+// RUN: %clang -target arm64-linux-none -mmark-bti-property -DNOTE_PRESENT -c %s -o - 2>&1 | FileCheck -check-prefix=CHECK_WARNING %s
+//
+// CHECK_WARNING: The .note.gnu.property is not emitted because it is already present.
+// CHECK: Name: .note.gnu.property
+// CHECK: Type: NT_GNU_PROPERTY_TYPE_0
+// CHECK_GEN: aarch64 feature: BTI
+// CHECK_PRESET: aarch64 feature: BTI, PAC
+
+#ifdef NOTE_PRESENT
+ .section .note.gnu.property, "a";
+ .balign 8;
+ .long 4;
+ .long 0x10;
+ .long 0x5
+ .asciz "GNU"
+ .long 0xc0000000
+ .long 4
+ .long 3
+ .long 0
+#endif
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index 8cbd60d74970..30ac7f4c0d2e 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -223,26 +223,9 @@ void AArch64AsmPrinter::emitStartOfAsmFile(Module &M) {
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->emitInt32(4); // data size for "GNU\0"
- OutStreamer->emitInt32(4 * 4); // Elf_Prop size
- OutStreamer->emitInt32(ELF::NT_GNU_PROPERTY_TYPE_0);
- OutStreamer->emitBytes(StringRef("GNU", 4)); // note name
-
- // Emit the PAC/BTI properties.
- OutStreamer->emitInt32(ELF::GNU_PROPERTY_AARCH64_FEATURE_1_AND);
- OutStreamer->emitInt32(4); // data size
- OutStreamer->emitInt32(Flags); // data
- OutStreamer->emitInt32(0); // pad
-
- OutStreamer->endSection(Nt);
- OutStreamer->SwitchSection(Cur);
+ if (auto *TS = static_cast<AArch64TargetStreamer *>(
+ OutStreamer->getTargetStreamer()))
+ TS->emitNoteSection(Flags);
}
void AArch64AsmPrinter::emitFunctionHeaderComment() {
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
index 48ed68f49263..f32a8f15b8a5 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp
@@ -11,12 +11,23 @@
//===----------------------------------------------------------------------===//
#include "AArch64TargetStreamer.h"
+#include "AArch64MCAsmInfo.h"
+#include "AArch64Subtarget.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/ConstantPools.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/CommandLine.h"
using namespace llvm;
+static cl::opt<bool> MarkBTIProperty(
+ "aarch64-mark-bti-property", cl::Hidden,
+ cl::desc("Add .note.gnu.property with BTI to assembly files"),
+ cl::init(false));
+
//
// AArch64TargetStreamer Implemenation
//
@@ -37,8 +48,50 @@ void AArch64TargetStreamer::emitCurrentConstantPool() {
ConstantPools->emitForCurrentSection(Streamer);
}
-// finish() - write out any non-empty assembler constant pools.
-void AArch64TargetStreamer::finish() { ConstantPools->emitAll(Streamer); }
+// finish() - write out any non-empty assembler constant pools and
+// write out note.gnu.properties if need.
+void AArch64TargetStreamer::finish() {
+ ConstantPools->emitAll(Streamer);
+
+ if (MarkBTIProperty)
+ emitNoteSection(ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI);
+}
+
+void AArch64TargetStreamer::emitNoteSection(unsigned Flags) {
+ if (Flags == 0)
+ return;
+
+ MCStreamer &OutStreamer = getStreamer();
+ MCContext &Context = OutStreamer.getContext();
+ // Emit a .note.gnu.property section with the flags.
+ MCSectionELF *Nt = Context.getELFSection(".note.gnu.property", ELF::SHT_NOTE,
+ ELF::SHF_ALLOC);
+ if (Nt->isRegistered()) {
+ SMLoc Loc;
+ Context.reportWarning(
+ Loc,
+ "The .note.gnu.property is not emitted because it is already present.");
+ return;
+ }
+ MCSection *Cur = OutStreamer.getCurrentSectionOnly();
+ OutStreamer.SwitchSection(Nt);
+
+ // Emit the note header.
+ OutStreamer.emitValueToAlignment(Align(8).value());
+ 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 AArch64TargetStreamer::emitInst(uint32_t Inst) {
char Buffer[4];
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
index c0dee085cace..09953315bbd0 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
@@ -33,6 +33,9 @@ class AArch64TargetStreamer : public MCTargetStreamer {
/// Emit contents of constant pool for the current section.
void emitCurrentConstantPool();
+ /// Callback used to implement the .note.gnu.property section.
+ void emitNoteSection(unsigned Flags);
+
/// Callback used to implement the .inst directive.
virtual void emitInst(uint32_t Inst);
More information about the llvm-commits
mailing list