Go to the documentation of this file.
29 #define DEBUG_TYPE "cfguard"
31 STATISTIC(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);
144 bool doInitialization(
Module &M)
override;
149 int cfguard_module_flag = 0;
150 Mechanism GuardMechanism = CF_Check;
158 void 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,
181 {
B.CreateBitCast(CalledOperand,
B.getInt8PtrTy())}, Bundles);
188 void CFGuard::insertCFGuardDispatch(
CallBase *CB) {
191 "Only applicable for Windows targets");
193 "Control Flow Guard checks can only be added to indirect calls");
197 Type *CalledOperandType = CalledOperand->
getType();
201 if (GuardFnGlobal->getType() != PTy)
205 LoadInst *GuardDispatchLoad =
B.CreateLoad(CalledOperandType, GuardFnGlobal);
213 assert((isa<CallInst>(CB) || isa<InvokeInst>(CB)) &&
214 "Unknown indirect call type");
227 bool CFGuard::doInitialization(
Module &M) {
231 mdconst::extract_or_null<ConstantInt>(
M.getModuleFlag(
"cfguard")))
232 cfguard_module_flag = MD->getZExtValue();
235 if (cfguard_module_flag != 2)
240 {Type::getInt8PtrTy(M.getContext())},
false);
245 if (GuardMechanism == CF_Check) {
246 GuardFnName =
"__guard_check_icall_fptr";
247 }
else if (GuardMechanism == CF_Dispatch) {
248 GuardFnName =
"__guard_dispatch_icall_fptr";
250 assert(
false &&
"Invalid CFGuard mechanism");
252 GuardFnGlobal =
M.getOrInsertGlobal(GuardFnName, GuardFnPtrType, [&] {
256 Var->setDSOLocal(
true);
266 if (cfguard_module_flag != 2)
277 auto *CB = dyn_cast<CallBase>(&
I);
279 IndirectCalls.push_back(CB);
286 if (IndirectCalls.empty()) {
291 if (GuardMechanism == CF_Dispatch) {
292 for (
CallBase *CB : IndirectCalls) {
293 insertCFGuardDispatch(CB);
296 for (
CallBase *CB : IndirectCalls) {
297 insertCFGuardCheck(CB);
308 return new CFGuard(CFGuard::CF_Check);
312 return new CFGuard(CFGuard::CF_Dispatch);
This is an optimization pass for GlobalISel generic memory operations.
void getOperandBundlesAsDefs(SmallVectorImpl< OperandBundleDef > &Defs) const
Return the list of operand bundles attached to this instruction as a vector of OperandBundleDefs.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Triple - Helper class for working with autoconf configuration names.
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
The instances of the Type class are immutable: once they are created, they are never changed.
A container for an operand bundle being viewed as a set of values rather than a set of uses.
LLVM Basic Block Representation.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
FunctionPass * createCFGuardDispatchPass()
Insert Control FLow Guard dispatches on indirect function calls.
STATISTIC(NumFunctions, "Total number of functions")
OperandBundleDefT< Value * > OperandBundleDef
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
void initializeCFGuardPass(PassRegistry &)
This is an important base class in LLVM.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Class to represent pointers.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
FunctionPass * createCFGuardCheckPass()
Insert Control FLow Guard checks on indirect function calls.
A Module instance is used to store all the information related to an LLVM module.
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.
std::optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
StringRef - Represent a constant reference to a string, i.e.
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.
An instruction for reading from memory.
bool isOSWindows() const
Tests whether the OS is Windows.
static bool runOnFunction(Function &F, bool PostInlining)
bool isIndirectCall() const
Return true if the callsite is an indirect call.
Value * getCalledOperand() const
void setCalledOperand(Value *V)
@ ExternalLinkage
Externally visible function.
static Type * getVoidTy(LLVMContext &C)
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
@ CFGuard_Check
Special calling convention on Windows for calling the Control Guard Check ICall funtion.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
FunctionPass class - This class is used to implement most global optimizations.
This class represents a function call, abstracting a target machine's calling convention.
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
LLVM Value Representation.
void setCallingConv(CallingConv::ID CC)
Class to represent function types.
reference emplace_back(ArgTypes &&... Args)