29#define DEBUG_TYPE "cfguard"
31STATISTIC(CFGuardCounter,
"Number of Control Flow Guard checks added");
88 void insertCFGuardCheck(
CallBase *CB);
129 void insertCFGuardDispatch(
CallBase *CB);
131 bool doInitialization(
Module &M);
137 Mechanism GuardMechanism = Mechanism::Check;
158void CFGuardImpl::insertCFGuardCheck(
CallBase *CB) {
160 "Only applicable for Windows targets");
162 "Control Flow Guard checks can only be added to indirect calls");
174 LoadInst *GuardCheckLoad =
B.CreateLoad(GuardFnPtrType, GuardFnGlobal);
178 CallInst *GuardCheck =
179 B.CreateCall(GuardFnType, GuardCheckLoad, {CalledOperand}, Bundles);
186void CFGuardImpl::insertCFGuardDispatch(CallBase *CB) {
188 "Only applicable for Windows targets");
190 "Control Flow Guard checks can only be added to indirect calls");
194 Type *CalledOperandType = CalledOperand->
getType();
197 LoadInst *GuardDispatchLoad =
B.CreateLoad(CalledOperandType, GuardFnGlobal);
206 "Unknown indirect call type");
219bool CFGuardImpl::doInitialization(
Module &M) {
221 CFGuardModuleFlag =
M.getControlFlowGuardMode();
224 if (CFGuardModuleFlag != ControlFlowGuardMode::Enabled)
229 ControlFlowGuardMechanism::Automatic;
231 M.getModuleFlag(
"cfguard-mechanism")))
234 switch (MechanismOverride) {
235 case ControlFlowGuardMechanism::Check:
236 GuardMechanism = Mechanism::Check;
238 case ControlFlowGuardMechanism::Dispatch:
239 GuardMechanism = Mechanism::Dispatch;
244 M.getTargetTriple().isX86_64() ? Mechanism::Dispatch : Mechanism::Check;
250 FunctionType::get(Type::getVoidTy(
M.getContext()),
251 {PointerType::getUnqual(M.getContext())},
false);
252 GuardFnPtrType = PointerType::get(
M.getContext(), 0);
254 StringRef GuardFnName = GuardMechanism == Mechanism::Check
257 GuardFnGlobal =
M.getOrInsertGlobal(GuardFnName, GuardFnPtrType, [&] {
258 auto *Var =
new GlobalVariable(M, GuardFnPtrType,
false,
259 GlobalVariable::ExternalLinkage,
nullptr,
261 Var->setDSOLocal(
true);
268bool CFGuardImpl::runOnFunction(
Function &
F) {
270 if (CFGuardModuleFlag != ControlFlowGuardMode::Enabled)
279 for (BasicBlock &BB :
F) {
280 for (Instruction &
I : BB) {
290 if (IndirectCalls.
empty())
294 if (GuardMechanism == Mechanism::Dispatch) {
295 for (CallBase *CB : IndirectCalls)
296 insertCFGuardDispatch(CB);
298 for (CallBase *CB : IndirectCalls)
299 insertCFGuardCheck(CB);
307 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
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)
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()
@ CFGuard_Check
Special calling convention on Windows for calling the Control Guard Check ICall funtion.
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract_or_null(Y &&MD)
Extract a Value from Metadata, if any, allowing null.
This is an optimization pass for GlobalISel generic memory operations.
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)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
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...
LLVM_ABI FunctionPass * createCFGuardPass()
Insert Control Flow Guard checks on indirect function calls.
OperandBundleDefT< Value * > OperandBundleDef
ControlFlowGuardMechanism
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.