30#define DEBUG_TYPE "cfguard"
32STATISTIC(CFGuardCounter,
"Number of Control Flow Guard checks added");
47 CFGuardImpl(Mechanism M) : GuardMechanism(M) {
49 switch (GuardMechanism) {
50 case Mechanism::Check:
53 case Mechanism::Dispatch:
102 void insertCFGuardCheck(
CallBase *CB);
143 void insertCFGuardDispatch(
CallBase *CB);
145 bool doInitialization(
Module &M);
152 Mechanism GuardMechanism = Mechanism::Check;
173void 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);
193 CallInst *GuardCheck =
194 B.CreateCall(GuardFnType, GuardCheckLoad, {CalledOperand}, Bundles);
201void CFGuardImpl::insertCFGuardDispatch(CallBase *CB) {
203 "Only applicable for Windows targets");
205 "Control Flow Guard checks can only be added to indirect calls");
209 Type *CalledOperandType = CalledOperand->
getType();
212 LoadInst *GuardDispatchLoad =
B.CreateLoad(CalledOperandType, GuardFnGlobal);
221 "Unknown indirect call type");
234bool CFGuardImpl::doInitialization(
Module &M) {
236 CFGuardModuleFlag =
M.getControlFlowGuardMode();
239 if (CFGuardModuleFlag != ControlFlowGuardMode::Enabled)
244 FunctionType::get(Type::getVoidTy(
M.getContext()),
245 {PointerType::getUnqual(M.getContext())},
false);
246 GuardFnPtrType = PointerType::get(
M.getContext(), 0);
248 GuardFnGlobal =
M.getOrInsertGlobal(GuardFnName, GuardFnPtrType, [&] {
249 auto *Var =
new GlobalVariable(M, GuardFnPtrType,
false,
250 GlobalVariable::ExternalLinkage,
nullptr,
252 Var->setDSOLocal(
true);
259bool CFGuardImpl::runOnFunction(Function &
F) {
261 if (CFGuardModuleFlag != ControlFlowGuardMode::Enabled)
270 for (BasicBlock &BB :
F) {
271 for (Instruction &
I : BB) {
281 if (IndirectCalls.
empty())
285 if (GuardMechanism == Mechanism::Dispatch) {
286 for (CallBase *CB : IndirectCalls)
287 insertCFGuardDispatch(CB);
289 for (CallBase *CB : IndirectCalls)
290 insertCFGuardCheck(CB);
297 CFGuardImpl Impl(GuardMechanism);
298 bool Changed = Impl.doInitialization(*
F.getParent());
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
constexpr StringRef GuardCheckFunctionName
constexpr StringRef GuardDispatchFunctionName
static bool runOnFunction(Function &F, bool PostInlining)
Module.h This file contains the declarations for the Module class.
Machine Check Debug Module
FunctionAnalysisManager FAM
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
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_ABI 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)
LLVM_ABI 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.
CallingConv::ID getCallingConv() const
LLVM_ABI bool isIndirectCall() const
Return true if the callsite is an indirect call.
unsigned countOperandBundlesOfType(StringRef Name) const
Return the number of operand bundles with the tag Name attached to this instruction.
Value * getCalledOperand() const
static LLVM_ABI 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 is an important base class in LLVM.
FunctionPass class - This class is used to implement most global optimizations.
LinkageTypes getLinkage() const
@ ExternalLinkage
Externally visible function.
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
A Module instance is used to store all the information related to an LLVM module.
const Triple & 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.
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)
StringRef - Represent a constant reference to a string, i.e.
bool isOSWindows() const
Tests whether the OS is Windows.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
self_iterator getIterator()
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.
FunctionAddr VTableAddr Value
LLVM_ABI bool isCFGuardCall(const CallBase *CB)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isCFGuardFunction(const GlobalValue *GV)
LLVM_ABI FunctionPass * createCFGuardDispatchPass()
Insert Control FLow Guard dispatches on indirect function calls.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
OperandBundleDefT< Value * > OperandBundleDef
LLVM_ABI FunctionPass * createCFGuardCheckPass()
Insert Control FLow Guard checks on indirect function calls.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.