aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/X86/X86AsmPrinter.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 10:51:19 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 10:51:19 +0000
commiteb11fae6d08f479c0799db45860a98af528fa6e7 (patch)
tree44d492a50c8c1a7eb8e2d17ea3360ec4d066f042 /lib/Target/X86/X86AsmPrinter.cpp
parentb8a2042aa938069e862750553db0e4d82d25822c (diff)
Notes
Diffstat (limited to 'lib/Target/X86/X86AsmPrinter.cpp')
-rw-r--r--lib/Target/X86/X86AsmPrinter.cpp159
1 files changed, 89 insertions, 70 deletions
diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp
index 71526dd77f11..7d8f7b9dfe46 100644
--- a/lib/Target/X86/X86AsmPrinter.cpp
+++ b/lib/Target/X86/X86AsmPrinter.cpp
@@ -19,9 +19,9 @@
#include "X86InstrInfo.h"
#include "X86MachineFunctionInfo.h"
#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
-#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Mangler.h"
@@ -31,11 +31,13 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSectionCOFF.h"
+#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MachineValueType.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
@@ -370,6 +372,14 @@ static void printIntelMemReference(X86AsmPrinter &P, const MachineInstr *MI,
static bool printAsmMRegister(X86AsmPrinter &P, const MachineOperand &MO,
char Mode, raw_ostream &O) {
unsigned Reg = MO.getReg();
+ bool EmitPercent = true;
+
+ if (!X86::GR8RegClass.contains(Reg) &&
+ !X86::GR16RegClass.contains(Reg) &&
+ !X86::GR32RegClass.contains(Reg) &&
+ !X86::GR64RegClass.contains(Reg))
+ return true;
+
switch (Mode) {
default: return true; // Unknown mode.
case 'b': // Print QImode register
@@ -384,6 +394,9 @@ static bool printAsmMRegister(X86AsmPrinter &P, const MachineOperand &MO,
case 'k': // Print SImode register
Reg = getX86SubSuperRegister(Reg, 32);
break;
+ case 'V':
+ EmitPercent = false;
+ LLVM_FALLTHROUGH;
case 'q':
// Print 64-bit register names if 64-bit integer registers are available.
// Otherwise, print 32-bit register names.
@@ -391,7 +404,10 @@ static bool printAsmMRegister(X86AsmPrinter &P, const MachineOperand &MO,
break;
}
- O << '%' << X86ATTInstPrinter::getRegisterName(Reg);
+ if (EmitPercent)
+ O << '%';
+
+ O << X86ATTInstPrinter::getRegisterName(Reg);
return false;
}
@@ -464,6 +480,7 @@ bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
case 'w': // Print HImode register
case 'k': // Print SImode register
case 'q': // Print DImode register
+ case 'V': // Print native register without '%'
if (MO.isReg())
return printAsmMRegister(*this, MO, ExtraCode[0], O);
printOperand(*this, MI, OpNo, O);
@@ -473,7 +490,7 @@ bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
printPCRelImm(*this, MI, OpNo, O);
return false;
- case 'n': // Negate the immediate or print a '-' before the operand.
+ case 'n': // Negate the immediate or print a '-' before the operand.
// Note: this is a temporary solution. It should be handled target
// independently as part of the 'MC' work.
if (MO.isImm()) {
@@ -524,6 +541,42 @@ bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
void X86AsmPrinter::EmitStartOfAsmFile(Module &M) {
const Triple &TT = TM.getTargetTriple();
+ if (TT.isOSBinFormatELF()) {
+ // Assemble feature flags that may require creation of a note section.
+ unsigned FeatureFlagsAnd = 0;
+ if (M.getModuleFlag("cf-protection-branch"))
+ FeatureFlagsAnd |= ELF::GNU_PROPERTY_X86_FEATURE_1_IBT;
+ if (M.getModuleFlag("cf-protection-return"))
+ FeatureFlagsAnd |= ELF::GNU_PROPERTY_X86_FEATURE_1_SHSTK;
+
+ if (FeatureFlagsAnd) {
+ // Emit a .note.gnu.property section with the flags.
+ if (!TT.isArch32Bit() && !TT.isArch64Bit())
+ llvm_unreachable("CFProtection used on invalid architecture!");
+ MCSection *Cur = OutStreamer->getCurrentSectionOnly();
+ MCSection *Nt = MMI->getContext().getELFSection(
+ ".note.gnu.property", ELF::SHT_NOTE, ELF::SHF_ALLOC);
+ OutStreamer->SwitchSection(Nt);
+
+ // Emitting note header.
+ int WordSize = TT.isArch64Bit() ? 8 : 4;
+ EmitAlignment(WordSize == 4 ? 2 : 3);
+ OutStreamer->EmitIntValue(4, 4 /*size*/); // data size for "GNU\0"
+ OutStreamer->EmitIntValue(8 + WordSize, 4 /*size*/); // Elf_Prop size
+ OutStreamer->EmitIntValue(ELF::NT_GNU_PROPERTY_TYPE_0, 4 /*size*/);
+ OutStreamer->EmitBytes(StringRef("GNU", 4)); // note name
+
+ // Emitting an Elf_Prop for the CET properties.
+ OutStreamer->EmitIntValue(ELF::GNU_PROPERTY_X86_FEATURE_1_AND, 4);
+ OutStreamer->EmitIntValue(WordSize, 4); // data size
+ OutStreamer->EmitIntValue(FeatureFlagsAnd, WordSize); // data
+ EmitAlignment(WordSize == 4 ? 2 : 3); // padding
+
+ OutStreamer->endSection(Nt);
+ OutStreamer->SwitchSection(Cur);
+ }
+ }
+
if (TT.isOSBinFormatMachO())
OutStreamer->SwitchSection(getObjFileLowering().getTextSection());
@@ -578,64 +631,48 @@ emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel,
4 /*size*/);
}
-MCSymbol *X86AsmPrinter::GetCPISymbol(unsigned CPID) const {
- if (Subtarget->isTargetKnownWindowsMSVC()) {
- const MachineConstantPoolEntry &CPE =
- MF->getConstantPool()->getConstants()[CPID];
- if (!CPE.isMachineConstantPoolEntry()) {
- const DataLayout &DL = MF->getDataLayout();
- SectionKind Kind = CPE.getSectionKind(&DL);
- const Constant *C = CPE.Val.ConstVal;
- unsigned Align = CPE.Alignment;
- if (const MCSectionCOFF *S = dyn_cast<MCSectionCOFF>(
- getObjFileLowering().getSectionForConstant(DL, Kind, C, Align))) {
- if (MCSymbol *Sym = S->getCOMDATSymbol()) {
- if (Sym->isUndefined())
- OutStreamer->EmitSymbolAttribute(Sym, MCSA_Global);
- return Sym;
- }
- }
- }
- }
+static void emitNonLazyStubs(MachineModuleInfo *MMI, MCStreamer &OutStreamer) {
- return AsmPrinter::GetCPISymbol(CPID);
-}
+ MachineModuleInfoMachO &MMIMacho =
+ MMI->getObjFileInfo<MachineModuleInfoMachO>();
-void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
- const Triple &TT = TM.getTargetTriple();
+ // Output stubs for dynamically-linked functions.
+ MachineModuleInfoMachO::SymbolListTy Stubs;
- if (TT.isOSBinFormatMachO()) {
- // All darwin targets use mach-o.
- MachineModuleInfoMachO &MMIMacho =
- MMI->getObjFileInfo<MachineModuleInfoMachO>();
+ // Output stubs for external and common global variables.
+ Stubs = MMIMacho.GetGVStubList();
+ if (!Stubs.empty()) {
+ OutStreamer.SwitchSection(MMI->getContext().getMachOSection(
+ "__IMPORT", "__pointers", MachO::S_NON_LAZY_SYMBOL_POINTERS,
+ SectionKind::getMetadata()));
- // Output stubs for dynamically-linked functions.
- MachineModuleInfoMachO::SymbolListTy Stubs;
+ for (auto &Stub : Stubs)
+ emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second);
- // Output stubs for external and common global variables.
- Stubs = MMIMacho.GetGVStubList();
- if (!Stubs.empty()) {
- MCSection *TheSection = OutContext.getMachOSection(
- "__IMPORT", "__pointers", MachO::S_NON_LAZY_SYMBOL_POINTERS,
- SectionKind::getMetadata());
- OutStreamer->SwitchSection(TheSection);
+ Stubs.clear();
+ OutStreamer.AddBlankLine();
+ }
+}
- for (auto &Stub : Stubs)
- emitNonLazySymbolPointer(*OutStreamer, Stub.first, Stub.second);
+void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
+ const Triple &TT = TM.getTargetTriple();
- Stubs.clear();
- OutStreamer->AddBlankLine();
- }
+ if (TT.isOSBinFormatMachO()) {
+ // Mach-O uses non-lazy symbol stubs to encode per-TU information into
+ // global table for symbol lookup.
+ emitNonLazyStubs(MMI, *OutStreamer);
+ // Emit stack and fault map information.
SM.serializeToStackMapSection();
FM.serializeToFaultMapSection();
- // Funny Darwin hack: This flag tells the linker that no global symbols
- // contain code that falls through to other global symbols (e.g. the obvious
- // implementation of multiple entry points). If this doesn't occur, the
- // linker can safely perform dead code stripping. Since LLVM never
- // generates code that does this, it is always safe to set.
+ // This flag tells the linker that no global symbols contain code that fall
+ // through to other global symbols (e.g. an implementation of multiple entry
+ // points). If this doesn't occur, the linker can safely perform dead code
+ // stripping. Since LLVM never generates code that does this, it is always
+ // safe to set.
OutStreamer->EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
+ return;
}
if (TT.isKnownWindowsMSVCEnvironment() && MMI->usesVAFloatArgument()) {
@@ -643,36 +680,18 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
(TT.getArch() == Triple::x86_64) ? "_fltused" : "__fltused";
MCSymbol *S = MMI->getContext().getOrCreateSymbol(SymbolName);
OutStreamer->EmitSymbolAttribute(S, MCSA_Global);
+ return;
}
if (TT.isOSBinFormatCOFF()) {
- const TargetLoweringObjectFileCOFF &TLOFCOFF =
- static_cast<const TargetLoweringObjectFileCOFF&>(getObjFileLowering());
-
- std::string Flags;
- raw_string_ostream FlagsOS(Flags);
-
- for (const auto &Function : M)
- TLOFCOFF.emitLinkerFlagsForGlobal(FlagsOS, &Function);
- for (const auto &Global : M.globals())
- TLOFCOFF.emitLinkerFlagsForGlobal(FlagsOS, &Global);
- for (const auto &Alias : M.aliases())
- TLOFCOFF.emitLinkerFlagsForGlobal(FlagsOS, &Alias);
-
- FlagsOS.flush();
-
- // Output collected flags.
- if (!Flags.empty()) {
- OutStreamer->SwitchSection(TLOFCOFF.getDrectveSection());
- OutStreamer->EmitBytes(Flags);
- }
-
SM.serializeToStackMapSection();
+ return;
}
if (TT.isOSBinFormatELF()) {
SM.serializeToStackMapSection();
FM.serializeToFaultMapSection();
+ return;
}
}