diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 |
| commit | eb11fae6d08f479c0799db45860a98af528fa6e7 (patch) | |
| tree | 44d492a50c8c1a7eb8e2d17ea3360ec4d066f042 /lib/Target/X86/X86AsmPrinter.cpp | |
| parent | b8a2042aa938069e862750553db0e4d82d25822c (diff) | |
Notes
Diffstat (limited to 'lib/Target/X86/X86AsmPrinter.cpp')
| -rw-r--r-- | lib/Target/X86/X86AsmPrinter.cpp | 159 |
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; } } |
