29#define DEBUG_TYPE "cfguard"
31STATISTIC(CFGuardCounter,
"Number of Control Flow Guard checks added");
43 enum Mechanism { CF_Check, CF_Dispatch };
49 GuardMechanism = CF_Check;
101 void insertCFGuardCheck(
CallBase *CB);
142 void insertCFGuardDispatch(
CallBase *CB);
149 int cfguard_module_flag = 0;
150 Mechanism GuardMechanism = CF_Check;
158void CFGuard::insertCFGuardCheck(
CallBase *CB) {
161 "Only applicable for Windows targets");
163 "Control Flow Guard checks can only be added to indirect calls");
175 LoadInst *GuardCheckLoad =
B.CreateLoad(GuardFnPtrType, GuardFnGlobal);
180 B.CreateCall(GuardFnType, GuardCheckLoad, {CalledOperand}, Bundles);
187void CFGuard::insertCFGuardDispatch(
CallBase *CB) {
190 "Only applicable for Windows targets");
192 "Control Flow Guard checks can only be added to indirect calls");
196 Type *CalledOperandType = CalledOperand->
getType();
199 PointerType *PTy = PointerType::get(CalledOperandType, 0);
200 if (GuardFnGlobal->getType() != PTy)
204 LoadInst *GuardDispatchLoad =
B.CreateLoad(CalledOperandType, GuardFnGlobal);
212 assert((isa<CallInst>(CB) || isa<InvokeInst>(CB)) &&
213 "Unknown indirect call type");
226bool CFGuard::doInitialization(
Module &M) {
230 mdconst::extract_or_null<ConstantInt>(
M.getModuleFlag(
"cfguard")))
231 cfguard_module_flag = MD->getZExtValue();
234 if (cfguard_module_flag != 2)
239 {Type::getInt8PtrTy(M.getContext())},
false);
240 GuardFnPtrType = PointerType::get(GuardFnType, 0);
244 if (GuardMechanism == CF_Check) {
245 GuardFnName =
"__guard_check_icall_fptr";
246 }
else if (GuardMechanism == CF_Dispatch) {
247 GuardFnName =
"__guard_dispatch_icall_fptr";
249 assert(
false &&
"Invalid CFGuard mechanism");
251 GuardFnGlobal =
M.getOrInsertGlobal(GuardFnName, GuardFnPtrType, [&] {
253 GlobalVariable::ExternalLinkage,
nullptr,
255 Var->setDSOLocal(
true);
262bool CFGuard::runOnFunction(
Function &
F) {
265 if (cfguard_module_flag != 2)
276 auto *CB = dyn_cast<CallBase>(&
I);
285 if (IndirectCalls.
empty()) {
290 if (GuardMechanism == CF_Dispatch) {
291 for (
CallBase *CB : IndirectCalls) {
292 insertCFGuardDispatch(CB);
295 for (
CallBase *CB : IndirectCalls) {
296 insertCFGuardCheck(CB);
307 return new CFGuard(CFGuard::CF_Check);
311 return new CFGuard(CFGuard::CF_Dispatch);
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
OperandBundleDefT< Value * > OperandBundleDef
#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)
LLVM Basic Block Representation.
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.
static CallBase * Create(CallBase *CB, ArrayRef< OperandBundleDef > Bundles, Instruction *InsertPt=nullptr)
Create a clone of CB with a different set of operand bundles and insert it before InsertPt.
Value * getCalledOperand() const
void setCalledOperand(Value *V)
This class represents a function call, abstracting a target machine's calling convention.
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
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...
SymbolTableList< Instruction >::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 ...
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ CFGuard_Check
Special calling convention on Windows for calling the Control Guard Check ICall funtion.
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.