diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/X86/X86AsmPrinter.cpp | 25 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86AsmPrinter.h | 2 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86FrameLowering.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86TargetTransformInfo.cpp | 15 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86TargetTransformInfo.h | 7 |
6 files changed, 63 insertions, 5 deletions
diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp index 67e51f1e919..76241dae069 100644 --- a/llvm/lib/Target/X86/X86AsmPrinter.cpp +++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp @@ -76,6 +76,31 @@ bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) { return false; } +void X86AsmPrinter::EmitConstantPool() { + if (MF) { + // If an MS hotpatch function, we need to ensure 64 (32-bit) or 128 (64-bit) + // bytes of padding precede the label. This is the scratch space used + // by the hotpatching mechanism to insert the patch code. The movl %edi, + // %edi instruction emitted as the very first instruction of a hotpatch + // function is usually overwritten with a short jump instruction when the + // patch is installed, so it will jump directly into this space. (But + // don't add the space when targeting MSVC. There, the /FUNCTIONPADMIN + // option to link.exe is expected to be used.) + const Function *Fn = MF->getFunction(); + if (!Subtarget->isTargetKnownWindowsMSVC() && + Fn->hasFnAttribute("patchable-function") && + Fn->getFnAttribute("patchable-function").getValueAsString() == + "ms-hotpatch") { + // Emit INT3 instructions instead of NOPs. If a patch runs off the end, + // best to let the patcher know with a crash/debug break than to silently + // continue, only to run into the jump back into the patch. + OutStreamer->emitFill(Subtarget->is64Bit() ? 128 : 64, 0xcc); + } + } + + AsmPrinter::EmitConstantPool(); +} + /// printSymbolOperand - Print a raw symbol reference operand. This handles /// jump tables, constant pools, global address and external symbols, all of /// which print to a label with various suffixes for relocation types etc. diff --git a/llvm/lib/Target/X86/X86AsmPrinter.h b/llvm/lib/Target/X86/X86AsmPrinter.h index dcb7b5a3466..7fc15cfd603 100644 --- a/llvm/lib/Target/X86/X86AsmPrinter.h +++ b/llvm/lib/Target/X86/X86AsmPrinter.h @@ -140,6 +140,8 @@ public: SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo()); } + void EmitConstantPool() override; + bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS) override; diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index 850a67a30e0..a3f4d294421 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -928,6 +928,10 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF, bool NeedsWinCFI = IsWin64Prologue && Fn->needsUnwindTableEntry(); bool NeedsDwarfCFI = !IsWin64Prologue && (MMI.hasDebugInfo() || Fn->needsUnwindTableEntry()); + bool IsMSHotpatch = + Fn->hasFnAttribute("patchable-function") && + Fn->getFnAttribute("patchable-function").getValueAsString() == + "ms-hotpatch"; unsigned FramePtr = TRI->getFrameRegister(MF); const unsigned MachineFramePtr = STI.isTarget64BitILP32() @@ -1069,7 +1073,9 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF, if (!IsWin64Prologue && !IsFunclet) { // Update EBP with the new base value. BuildMI(MBB, MBBI, DL, - TII.get(Uses64BitFramePtr ? X86::MOV64rr : X86::MOV32rr), + TII.get(IsMSHotpatch ? + (Uses64BitFramePtr ? X86::MOV64rr_REV : X86::MOV32rr_REV): + (Uses64BitFramePtr ? X86::MOV64rr : X86::MOV32rr)), FramePtr) .addReg(StackPtr) .setMIFlag(MachineInstr::FrameSetup); diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index c09d76d4845..2c6bd64dbb9 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -2576,10 +2576,13 @@ SDValue X86TargetLowering::LowerFormalArguments( X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>(); const TargetFrameLowering &TFI = *Subtarget.getFrameLowering(); - const Function *Fn = MF.getFunction(); - if (Fn->hasExternalLinkage() && - Subtarget.isTargetCygMing() && - Fn->getName() == "main") + const Function* Fn = MF.getFunction(); + if ((Fn->hasExternalLinkage() && + Subtarget.isTargetCygMing() && + Fn->getName() == "main") || + (!Subtarget.is64Bit() && Fn->hasFnAttribute("patchable-function") && + Fn->getFnAttribute("patchable-function").getValueAsString() == + "ms-hotpatch")) FuncInfo->setForceFramePointer(true); MachineFrameInfo &MFI = MF.getFrameInfo(); diff --git a/llvm/lib/Target/X86/X86TargetTransformInfo.cpp b/llvm/lib/Target/X86/X86TargetTransformInfo.cpp index 657a0451719..453afc00e9f 100644 --- a/llvm/lib/Target/X86/X86TargetTransformInfo.cpp +++ b/llvm/lib/Target/X86/X86TargetTransformInfo.cpp @@ -1681,3 +1681,18 @@ bool X86TTIImpl::areInlineCompatible(const Function *Caller, // correct. return (CallerBits & CalleeBits) == CalleeBits; } + +void X86TTIImpl::emitPatchableOp(StringRef PatchType, + MachineBasicBlock &MBB, + MachineBasicBlock::iterator &MBBI) const { + if (PatchType != "ms-hotpatch" || !ST->is32Bit()) { + BaseT::emitPatchableOp(PatchType, MBB, MBBI); + return; + } + + auto &TII = *MBB.getParent()->getSubtarget().getInstrInfo(); + BuildMI(MBB, MBBI, MBBI->getDebugLoc(), + TII.get(X86::MOV32rr_REV), X86::EDI) + .addReg(X86::EDI) + .setMIFlag(MachineInstr::FrameSetup); +} diff --git a/llvm/lib/Target/X86/X86TargetTransformInfo.h b/llvm/lib/Target/X86/X86TargetTransformInfo.h index ab8046bb9fd..e8856c77296 100644 --- a/llvm/lib/Target/X86/X86TargetTransformInfo.h +++ b/llvm/lib/Target/X86/X86TargetTransformInfo.h @@ -50,6 +50,13 @@ public: : BaseT(std::move(static_cast<BaseT &>(Arg))), ST(std::move(Arg.ST)), TLI(std::move(Arg.TLI)) {} + /// \name Generic TTI Implementations + /// @{ + void emitPatchableOp(StringRef PatchType, MachineBasicBlock &MBB, + MachineBasicBlock::iterator &MBBI) const; + + /// @} + /// \name Scalar TTI Implementations /// @{ TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth); |