30#define DEBUG_TYPE "cfguard"
32STATISTIC(CFGuardCounter,
"Number of Control Flow Guard checks added");
44 CFGuardImpl(Mechanism M) : GuardMechanism(M) {
46 switch (GuardMechanism) {
47 case Mechanism::Check:
48 GuardFnName =
"__guard_check_icall_fptr";
50 case Mechanism::Dispatch:
51 GuardFnName =
"__guard_dispatch_icall_fptr";
99 void insertCFGuardCheck(
CallBase *CB);
140 void insertCFGuardDispatch(
CallBase *CB);
142 bool doInitialization(
Module &M);
147 int cfguard_module_flag = 0;
149 Mechanism GuardMechanism = Mechanism::Check;
172void CFGuardImpl::insertCFGuardCheck(
CallBase *CB) {
175 "Only applicable for Windows targets");
177 "Control Flow Guard checks can only be added to indirect calls");
189 LoadInst *GuardCheckLoad =
B.CreateLoad(GuardFnPtrType, GuardFnGlobal);
194 B.CreateCall(GuardFnType, GuardCheckLoad, {CalledOperand}, Bundles);
201void CFGuardImpl::insertCFGuardDispatch(
CallBase *CB) {
204 "Only applicable for Windows targets");
206 "Control Flow Guard checks can only be added to indirect calls");
210 Type *CalledOperandType = CalledOperand->
getType();
213 LoadInst *GuardDispatchLoad =
B.CreateLoad(CalledOperandType, GuardFnGlobal);
221 assert((isa<CallInst>(CB) || isa<InvokeInst>(CB)) &&
222 "Unknown indirect call type");
235bool CFGuardImpl::doInitialization(
Module &M) {
239 mdconst::extract_or_null<ConstantInt>(
M.getModuleFlag(
"cfguard")))
240 cfguard_module_flag = MD->getZExtValue();
243 if (cfguard_module_flag != 2)
249 {PointerType::getUnqual(M.getContext())},
false);
250 GuardFnPtrType = PointerType::get(GuardFnType, 0);
252 GuardFnGlobal =
M.getOrInsertGlobal(GuardFnName, GuardFnPtrType, [&] {
254 GlobalVariable::ExternalLinkage,
nullptr,
256 Var->setDSOLocal(
true);
263bool CFGuardImpl::runOnFunction(
Function &
F) {
266 if (cfguard_module_flag != 2)
277 auto *CB = dyn_cast<CallBase>(&
I);
286 if (IndirectCalls.
empty()) {
291 if (GuardMechanism == Mechanism::Dispatch) {
292 for (
CallBase *CB : IndirectCalls) {
293 insertCFGuardDispatch(CB);
296 for (
CallBase *CB : IndirectCalls) {
297 insertCFGuardCheck(CB);
305 CFGuardImpl Impl(GuardMechanism);
306 bool Changed = Impl.doInitialization(*
F.getParent());
307 Changed |= Impl.runOnFunction(
F);
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
OperandBundleDefT< Value * > OperandBundleDef
static bool runOnFunction(Function &F, bool PostInlining)
Module.h This file contains the declarations for the Module class.
FunctionAnalysisManager FAM
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
A container for analyses that lazily runs them and caches their results.
LLVM Basic Block Representation.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
void setCallingConv(CallingConv::ID CC)
void getOperandBundlesAsDefs(SmallVectorImpl< OperandBundleDef > &Defs) const
Return the list of operand bundles attached to this instruction as a vector of OperandBundleDefs.
std::optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
bool isIndirectCall() const
Return true if the callsite is an indirect call.
Value * getCalledOperand() const
static CallBase * Create(CallBase *CB, ArrayRef< OperandBundleDef > Bundles, InsertPosition InsertPt=nullptr)
Create a clone of CB with a different set of operand bundles and insert it before InsertPt.
void setCalledOperand(Value *V)
This class represents a function call, abstracting a target machine's calling convention.
This is an important base class in LLVM.
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
An instruction for reading from memory.
A Module instance is used to store all the information related to an LLVM module.
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
A container for an operand bundle being viewed as a set of values rather than a set of uses.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual bool doInitialization(Module &)
doInitialization - Virtual method overridden by subclasses to do any necessary initialization before ...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Triple - Helper class for working with autoconf configuration names.
bool isOSWindows() const
Tests whether the OS is Windows.
The instances of the Type class are immutable: once they are created, they are never changed.
static Type * getVoidTy(LLVMContext &C)
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
self_iterator getIterator()
@ CFGuard_Check
Special calling convention on Windows for calling the Control Guard Check ICall funtion.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createCFGuardDispatchPass()
Insert Control FLow Guard dispatches on indirect function calls.
void initializeCFGuardPass(PassRegistry &)
FunctionPass * createCFGuardCheckPass()
Insert Control FLow Guard checks on indirect function calls.