aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/X86/X86AsmPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/X86/X86AsmPrinter.cpp')
-rw-r--r--llvm/lib/Target/X86/X86AsmPrinter.cpp96
1 files changed, 76 insertions, 20 deletions
diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp
index d48b8e458219..c205395aa084 100644
--- a/llvm/lib/Target/X86/X86AsmPrinter.cpp
+++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp
@@ -29,6 +29,7 @@
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
@@ -60,8 +61,7 @@ bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
SMShadowTracker.startFunction(MF);
CodeEmitter.reset(TM.getTarget().createMCCodeEmitter(
- *Subtarget->getInstrInfo(), *Subtarget->getRegisterInfo(),
- MF.getContext()));
+ *Subtarget->getInstrInfo(), MF.getContext()));
EmitFPOData =
Subtarget->isTargetWin32() && MF.getMMI().getModule()->getCodeViewFlag();
@@ -70,12 +70,12 @@ bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
if (Subtarget->isTargetCOFF()) {
bool Local = MF.getFunction().hasLocalLinkage();
- OutStreamer->BeginCOFFSymbolDef(CurrentFnSym);
- OutStreamer->EmitCOFFSymbolStorageClass(
+ OutStreamer->beginCOFFSymbolDef(CurrentFnSym);
+ OutStreamer->emitCOFFSymbolStorageClass(
Local ? COFF::IMAGE_SYM_CLASS_STATIC : COFF::IMAGE_SYM_CLASS_EXTERNAL);
- OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
- << COFF::SCT_COMPLEX_TYPE_SHIFT);
- OutStreamer->EndCOFFSymbolDef();
+ OutStreamer->emitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
+ << COFF::SCT_COMPLEX_TYPE_SHIFT);
+ OutStreamer->endCOFFSymbolDef();
}
// Emit the rest of the function body.
@@ -249,7 +249,7 @@ void X86AsmPrinter::PrintOperand(const MachineInstr *MI, unsigned OpNo,
void X86AsmPrinter::PrintModifiedOperand(const MachineInstr *MI, unsigned OpNo,
raw_ostream &O, const char *Modifier) {
const MachineOperand &MO = MI->getOperand(OpNo);
- if (!Modifier || MO.getType() != MachineOperand::MO_Register)
+ if (!Modifier || !MO.isReg())
return PrintOperand(MI, OpNo, O);
if (MI->getInlineAsmDialect() == InlineAsm::AD_ATT)
O << '%';
@@ -336,6 +336,37 @@ void X86AsmPrinter::PrintLeaMemReference(const MachineInstr *MI, unsigned OpNo,
}
}
+static bool isSimpleReturn(const MachineInstr &MI) {
+ // We exclude all tail calls here which set both isReturn and isCall.
+ return MI.getDesc().isReturn() && !MI.getDesc().isCall();
+}
+
+static bool isIndirectBranchOrTailCall(const MachineInstr &MI) {
+ unsigned Opc = MI.getOpcode();
+ return MI.getDesc().isIndirectBranch() /*Make below code in a good shape*/ ||
+ Opc == X86::TAILJMPr || Opc == X86::TAILJMPm ||
+ Opc == X86::TAILJMPr64 || Opc == X86::TAILJMPm64 ||
+ Opc == X86::TCRETURNri || Opc == X86::TCRETURNmi ||
+ Opc == X86::TCRETURNri64 || Opc == X86::TCRETURNmi64 ||
+ Opc == X86::TAILJMPr64_REX || Opc == X86::TAILJMPm64_REX;
+}
+
+void X86AsmPrinter::emitBasicBlockEnd(const MachineBasicBlock &MBB) {
+ if (Subtarget->hardenSlsRet() || Subtarget->hardenSlsIJmp()) {
+ auto I = MBB.getLastNonDebugInstr();
+ if (I != MBB.end()) {
+ if ((Subtarget->hardenSlsRet() && isSimpleReturn(*I)) ||
+ (Subtarget->hardenSlsIJmp() && isIndirectBranchOrTailCall(*I))) {
+ MCInst TmpInst;
+ TmpInst.setOpcode(X86::INT3);
+ EmitToStreamer(*OutStreamer, TmpInst);
+ }
+ }
+ }
+ AsmPrinter::emitBasicBlockEnd(MBB);
+ SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
+}
+
void X86AsmPrinter::PrintMemReference(const MachineInstr *MI, unsigned OpNo,
raw_ostream &O, const char *Modifier) {
assert(isMem(*MI, OpNo) && "Invalid memory reference!");
@@ -363,6 +394,12 @@ void X86AsmPrinter::PrintIntelMemReference(const MachineInstr *MI,
BaseReg.getReg() == X86::RIP)
HasBaseReg = false;
+ // If we really just want to print out displacement.
+ if (Modifier && (DispSpec.isGlobal() || DispSpec.isSymbol()) &&
+ !strcmp(Modifier, "disp-only")) {
+ HasBaseReg = false;
+ }
+
// If this has a segment register, print it.
if (SegReg.getReg()) {
PrintOperand(MI, OpNo + X86::AddrSegmentReg, O);
@@ -606,11 +643,14 @@ bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
PrintMemReference(MI, OpNo, O, "H");
}
return false;
- case 'P': // Don't print @PLT, but do print as memory.
+ // Print memory only with displacement. The Modifer 'P' is used in inline
+ // asm to present a call symbol or a global symbol which can not use base
+ // reg or index reg.
+ case 'P':
if (MI->getInlineAsmDialect() == InlineAsm::AD_Intel) {
- PrintIntelMemReference(MI, OpNo, O, "no-rip");
+ PrintIntelMemReference(MI, OpNo, O, "disp-only");
} else {
- PrintMemReference(MI, OpNo, O, "no-rip");
+ PrintMemReference(MI, OpNo, O, "disp-only");
}
return false;
}
@@ -641,7 +681,7 @@ void X86AsmPrinter::emitStartOfAsmFile(Module &M) {
MCSection *Cur = OutStreamer->getCurrentSectionOnly();
MCSection *Nt = MMI->getContext().getELFSection(
".note.gnu.property", ELF::SHT_NOTE, ELF::SHF_ALLOC);
- OutStreamer->SwitchSection(Nt);
+ OutStreamer->switchSection(Nt);
// Emitting note header.
const int WordSize = TT.isArch64Bit() && !TT.isX32() ? 8 : 4;
@@ -658,21 +698,21 @@ void X86AsmPrinter::emitStartOfAsmFile(Module &M) {
emitAlignment(WordSize == 4 ? Align(4) : Align(8)); // padding
OutStreamer->endSection(Nt);
- OutStreamer->SwitchSection(Cur);
+ OutStreamer->switchSection(Cur);
}
}
if (TT.isOSBinFormatMachO())
- OutStreamer->SwitchSection(getObjFileLowering().getTextSection());
+ OutStreamer->switchSection(getObjFileLowering().getTextSection());
if (TT.isOSBinFormatCOFF()) {
// Emit an absolute @feat.00 symbol. This appears to be some kind of
// compiler features bitfield read by link.exe.
MCSymbol *S = MMI->getContext().getOrCreateSymbol(StringRef("@feat.00"));
- OutStreamer->BeginCOFFSymbolDef(S);
- OutStreamer->EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC);
- OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL);
- OutStreamer->EndCOFFSymbolDef();
+ OutStreamer->beginCOFFSymbolDef(S);
+ OutStreamer->emitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC);
+ OutStreamer->emitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL);
+ OutStreamer->endCOFFSymbolDef();
int64_t Feat00Flags = 0;
if (TT.getArch() == Triple::x86) {
@@ -739,7 +779,7 @@ static void emitNonLazyStubs(MachineModuleInfo *MMI, MCStreamer &OutStreamer) {
// Output stubs for external and common global variables.
Stubs = MMIMacho.GetGVStubList();
if (!Stubs.empty()) {
- OutStreamer.SwitchSection(MMI->getContext().getMachOSection(
+ OutStreamer.switchSection(MMI->getContext().getMachOSection(
"__IMPORT", "__pointers", MachO::S_NON_LAZY_SYMBOL_POINTERS,
SectionKind::getMetadata()));
@@ -747,7 +787,7 @@ static void emitNonLazyStubs(MachineModuleInfo *MMI, MCStreamer &OutStreamer) {
emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second);
Stubs.clear();
- OutStreamer.AddBlankLine();
+ OutStreamer.addBlankLine();
}
}
@@ -795,6 +835,22 @@ void X86AsmPrinter::emitEndOfAsmFile(Module &M) {
emitStackMaps(SM);
FM.serializeToFaultMapSection();
}
+
+ // Emit __morestack address if needed for indirect calls.
+ if (TT.getArch() == Triple::x86_64 && TM.getCodeModel() == CodeModel::Large) {
+ if (MCSymbol *AddrSymbol = OutContext.lookupSymbol("__morestack_addr")) {
+ Align Alignment(1);
+ MCSection *ReadOnlySection = getObjFileLowering().getSectionForConstant(
+ getDataLayout(), SectionKind::getReadOnly(),
+ /*C=*/nullptr, Alignment);
+ OutStreamer->switchSection(ReadOnlySection);
+ OutStreamer->emitLabel(AddrSymbol);
+
+ unsigned PtrSize = MAI->getCodePointerSize();
+ OutStreamer->emitSymbolValue(GetExternalSymbolSymbol("__morestack"),
+ PtrSize);
+ }
+ }
}
//===----------------------------------------------------------------------===//