summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/PatchableFunction.cpp
diff options
context:
space:
mode:
authorCharles Davis <cdavis5x@gmail.com>2016-08-08 21:01:39 +0000
committerCharles Davis <cdavis5x@gmail.com>2016-08-08 21:01:39 +0000
commit0822aa118eafbe860acc393e076567697adda77a (patch)
treed5b7b3fb0545cf4634fe1e559165fdc35df63880 /llvm/lib/CodeGen/PatchableFunction.cpp
parent31f32fa62aab473aa58291af0a6984aa1a36f2ee (diff)
downloadbcm5719-llvm-0822aa118eafbe860acc393e076567697adda77a.tar.gz
bcm5719-llvm-0822aa118eafbe860acc393e076567697adda77a.zip
[X86] Support the "ms-hotpatch" attribute.
Summary: Based on two patches by Michael Mueller. This is a target attribute that causes a function marked with it to be emitted as "hotpatchable". This particular mechanism was originally devised by Microsoft for patching their binaries (which they are constantly updating to stay ahead of crackers, script kiddies, and other ne'er-do-wells on the Internet), but is now commonly abused by Windows programs to hook API functions. This mechanism is target-specific. For x86, a two-byte no-op instruction is emitted at the function's entry point; the entry point must be immediately preceded by 64 (32-bit) or 128 (64-bit) bytes of padding. This padding is where the patch code is written. The two byte no-op is then overwritten with a short jump into this code. The no-op is usually a `movl %edi, %edi` instruction; this is used as a magic value indicating that this is a hotpatchable function. Reviewers: majnemer, sanjoy, rnk Subscribers: dberris, llvm-commits Differential Revision: https://reviews.llvm.org/D19908 llvm-svn: 278048
Diffstat (limited to 'llvm/lib/CodeGen/PatchableFunction.cpp')
-rw-r--r--llvm/lib/CodeGen/PatchableFunction.cpp30
1 files changed, 14 insertions, 16 deletions
diff --git a/llvm/lib/CodeGen/PatchableFunction.cpp b/llvm/lib/CodeGen/PatchableFunction.cpp
index 32468c90b86..c94307df62b 100644
--- a/llvm/lib/CodeGen/PatchableFunction.cpp
+++ b/llvm/lib/CodeGen/PatchableFunction.cpp
@@ -13,12 +13,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/Passes.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Target/TargetFrameLowering.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
using namespace llvm;
@@ -29,8 +28,9 @@ struct PatchableFunction : public MachineFunctionPass {
initializePatchableFunctionPass(*PassRegistry::getPassRegistry());
}
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
bool runOnMachineFunction(MachineFunction &F) override;
- MachineFunctionProperties getRequiredProperties() const override {
+ MachineFunctionProperties getRequiredProperties() const override {
return MachineFunctionProperties().set(
MachineFunctionProperties::Property::AllVRegsAllocated);
}
@@ -53,31 +53,29 @@ static bool doesNotGeneratecode(const MachineInstr &MI) {
}
}
+void PatchableFunction::getAnalysisUsage(AnalysisUsage &AU) const {
+ MachineFunctionPass::getAnalysisUsage(AU);
+ AU.addRequired<TargetTransformInfoWrapperPass>();
+}
+
bool PatchableFunction::runOnMachineFunction(MachineFunction &MF) {
if (!MF.getFunction()->hasFnAttribute("patchable-function"))
return false;
-#ifndef NDEBUG
Attribute PatchAttr = MF.getFunction()->getFnAttribute("patchable-function");
StringRef PatchType = PatchAttr.getValueAsString();
- assert(PatchType == "prologue-short-redirect" && "Only possibility today!");
-#endif
+ assert((PatchType == "prologue-short-redirect" ||
+ PatchType == "ms-hotpatch") && "Only possibilities today!");
auto &FirstMBB = *MF.begin();
MachineBasicBlock::iterator FirstActualI = FirstMBB.begin();
for (; doesNotGeneratecode(*FirstActualI); ++FirstActualI)
assert(FirstActualI != FirstMBB.end());
- auto *TII = MF.getSubtarget().getInstrInfo();
- auto MIB = BuildMI(FirstMBB, FirstActualI, FirstActualI->getDebugLoc(),
- TII->get(TargetOpcode::PATCHABLE_OP))
- .addImm(2)
- .addImm(FirstActualI->getOpcode());
-
- for (auto &MO : FirstActualI->operands())
- MIB.addOperand(MO);
+ const TargetTransformInfo &TTI =
+ getAnalysis<TargetTransformInfoWrapperPass>().getTTI(*MF.getFunction());
+ TTI.emitPatchableOp(PatchType, FirstMBB, FirstActualI);
- FirstActualI->eraseFromParent();
MF.ensureAlignment(4);
return true;
}
OpenPOWER on IntegriCloud