summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/X86/X86AsmPrinter.cpp25
-rw-r--r--llvm/lib/Target/X86/X86AsmPrinter.h2
-rw-r--r--llvm/lib/Target/X86/X86FrameLowering.cpp8
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp11
-rw-r--r--llvm/lib/Target/X86/X86TargetTransformInfo.cpp15
-rw-r--r--llvm/lib/Target/X86/X86TargetTransformInfo.h7
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);
OpenPOWER on IntegriCloud