54 #define DEBUG_TYPE "stack-protector" 56 STATISTIC(NumFunProtected,
"Number of functions protected");
57 STATISTIC(NumAddrTaken,
"Number of local variables that have their address" 66 "Insert stack protectors",
false,
true)
82 getAnalysisIfAvailable<DominatorTreeWrapperPass>();
84 TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
95 if (!RequiresStackProtector())
107 return InsertStackProtectors();
113 bool StackProtector::ContainsProtectableArray(
Type *Ty,
bool &IsLarge,
115 bool InStruct)
const {
118 if (
ArrayType *AT = dyn_cast<ArrayType>(Ty)) {
119 if (!AT->getElementType()->isIntegerTy(8)) {
124 if (!Strong && (InStruct || !Trip.
isOSDarwin()))
130 if (SSPBufferSize <= M->getDataLayout().getTypeAllocSize(AT)) {
144 bool NeedsProtector =
false;
148 if (ContainsProtectableArray(*
I, IsLarge, Strong,
true)) {
154 NeedsProtector =
true;
157 return NeedsProtector;
160 bool StackProtector::HasAddressTaken(
const Instruction *AI) {
162 if (
const StoreInst *
SI = dyn_cast<StoreInst>(U)) {
163 if (AI ==
SI->getValueOperand())
166 if (AI ==
SI->getOperand(0))
168 }
else if (
const CallInst *CI = dyn_cast<CallInst>(U)) {
170 if (!isa<DbgInfoIntrinsic>(CI) && !CI->isLifetimeStartOrEnd())
172 }
else if (isa<InvokeInst>(U)) {
174 }
else if (
const SelectInst *
SI = dyn_cast<SelectInst>(U)) {
175 if (HasAddressTaken(
SI))
177 }
else if (
const PHINode *PN = dyn_cast<PHINode>(U)) {
180 if (VisitedPHIs.insert(PN).second)
181 if (HasAddressTaken(PN))
184 if (HasAddressTaken(
GEP))
186 }
else if (
const BitCastInst *BI = dyn_cast<BitCastInst>(U)) {
187 if (HasAddressTaken(BI))
199 if (
const CallInst *CI = dyn_cast<CallInst>(&
I))
200 if (CI->getCalledFunction() ==
219 bool StackProtector::RequiresStackProtector() {
221 bool NeedsProtector =
false;
235 <<
"Stack protection applied to function " 237 <<
" due to a function attribute or command-line switch";
239 NeedsProtector =
true;
243 else if (HasPrologue)
244 NeedsProtector =
true;
250 if (
const AllocaInst *AI = dyn_cast<AllocaInst>(&
I)) {
251 if (AI->isArrayAllocation()) {
252 auto RemarkBuilder = [&]() {
255 <<
"Stack protection applied to function " 257 <<
" due to a call to alloca or use of a variable length " 260 if (
const auto *CI = dyn_cast<ConstantInt>(AI->getArraySize())) {
261 if (CI->getLimitedValue(SSPBufferSize) >= SSPBufferSize) {
264 Layout.
insert(std::make_pair(AI,
266 ORE.
emit(RemarkBuilder);
267 NeedsProtector =
true;
270 Layout.
insert(std::make_pair(AI,
272 ORE.
emit(RemarkBuilder);
273 NeedsProtector =
true;
277 Layout.
insert(std::make_pair(AI,
279 ORE.
emit(RemarkBuilder);
280 NeedsProtector =
true;
285 bool IsLarge =
false;
286 if (ContainsProtectableArray(AI->getAllocatedType(), IsLarge, Strong)) {
287 Layout.
insert(std::make_pair(AI, IsLarge
292 <<
"Stack protection applied to function " 294 <<
" due to a stack allocated buffer or struct containing a " 297 NeedsProtector =
true;
301 if (Strong && HasAddressTaken(AI)) {
307 <<
"Stack protection applied to function " 309 <<
" due to the address of a local variable being taken";
311 NeedsProtector =
true;
317 return NeedsProtector;
324 bool *SupportsSelectionDAGSP =
nullptr) {
326 return B.
CreateLoad(Guard,
true,
"StackGuard");
339 if (SupportsSelectionDAGSP)
340 *SupportsSelectionDAGSP =
true;
357 bool SupportsSelectionDAGSP =
false;
360 AI =
B.CreateAlloca(PtrTy,
nullptr,
"StackGuardSlot");
365 return SupportsSelectionDAGSP;
374 bool StackProtector::InsertStackProtectors() {
378 bool SupportsSelectionDAGSP =
398 if (SupportsSelectionDAGSP)
405 assert(SPCall &&
"Call to llvm.stackprotector is missing");
484 .createBranchWeights(SuccessProb.getNumerator(),
485 FailureProb.getNumerator());
536 if (LI == Layout.
end())
Return a value (possibly void), from a function.
bool isOSDarwin() const
isOSDarwin - Is this a "Darwin" OS (OS X, iOS, or watchOS).
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
BranchInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
DILocation * get() const
Get the underlying DILocation.
DiagnosticInfoOptimizationBase::Argument NV
This class represents lattice values for constants.
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
unsigned EnableFastISel
EnableFastISel - This flag enables fast-path instruction selection which trades away generated code q...
A Module instance is used to store all the information related to an LLVM module. ...
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
This class represents a function call, abstracting a target machine's calling convention.
virtual const TargetLowering * getTargetLowering() const
void copyToMachineFrameInfo(MachineFrameInfo &MFI) const
LLVMContext & getContext() const
All values hold a context through their type.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
STATISTIC(NumFunctions, "Total number of functions")
block Block Frequency true
An instruction for reading from memory.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
static bool CreatePrologue(Function *F, Module *M, ReturnInst *RI, const TargetLoweringBase *TLI, AllocaInst *&AI)
Insert code into the entry block that stores the stack guard variable onto the stack: ...
Value * getArgOperand(unsigned i) const
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
This class represents the LLVM 'select' instruction.
bool isStringAttribute() const
Return true if the attribute is a string (target-dependent) attribute.
Class to represent struct types.
static cl::opt< bool > EnableSelectionDAGSP("enable-selectiondag-sp", cl::init(true), cl::Hidden)
The address of this allocation is exposed and triggered protection.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
This file contains the simple types necessary to represent the attributes associated with functions a...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
DominatorTree & getDomTree()
Target-Independent Code Generator Pass Configuration Options.
This class represents a cast from a pointer to an integer.
Class to represent array types.
This class represents a no-op cast from one type to another.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
AttributeList getAttributes() const
Return the attribute list for this Function.
An instruction for storing to memory.
bool hasPersonalityFn() const
Check whether this function has a personality function.
void SetCurrentDebugLocation(DebugLoc L)
Set location information used by debugging information.
Type::subtype_iterator element_iterator
Function * getDeclaration(Module *M, ID id, ArrayRef< Type *> Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Class to represent pointers.
bool runOnFunction(Function &Fn) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass...
void setObjectSSPLayout(int ObjectIdx, SSPLayoutKind Kind)
Array or nested array >= SSP-buffer-size.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
iterator find(const_arg_type_t< KeyT > Val)
unsigned EnableGlobalISel
EnableGlobalISel - This flag enables global instruction selection.
const BasicBlock & getEntryBlock() const
virtual Value * getIRStackGuard(IRBuilder<> &IRB) const
If the target has a standard location for the stack protector guard, returns the address of that loca...
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
initializer< Ty > init(const Ty &Val)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
UnreachableInst * CreateUnreachable()
DISubprogram * getSubprogram() const
Get the attached subprogram.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const Instruction & front() const
element_iterator element_end() const
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
void setCallingConv(CallingConv::ID CC)
FunctionPass class - This class is used to implement most global optimizations.
const Triple & getTargetTriple() const
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
self_iterator getIterator()
FunctionPass * createStackProtectorPass()
createStackProtectorPass - This pass adds stack protectors to functions.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
virtual bool useStackGuardXorFP() const
If this function returns true, stack protection checks should XOR the frame pointer (or whichever poi...
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
This base class for TargetLowering contains the SelectionDAG-independent parts that can be used from ...
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
static const CallInst * findStackProtectorIntrinsic(Function &F)
Search for the first call to the llvm.stackprotector intrinsic and return it if present.
Iterator for intrusive lists based on ilist_node.
void moveAfter(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it right after MovePos in the function M...
bool isFuncletEHPersonality(EHPersonality Pers)
Returns true if this is a personality function that invokes handler funclets (which must return to it...
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
Module.h This file contains the declarations for the Module class.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
Constant * CreateGlobalStringPtr(StringRef Str, const Twine &Name="", unsigned AddressSpace=0)
Same as CreateGlobalString, but return a pointer with "i8*" type instead of a pointer to array of i8...
iterator_range< user_iterator > users()
element_iterator element_begin() const
virtual Value * getSSPStackGuardCheck(const Module &M) const
If the target has a standard stack protection check function that performs validation and error handl...
const AllocaInst * getObjectAllocation(int ObjectIdx) const
Return the underlying Alloca of the specified stack object if it exists.
INITIALIZE_PASS_BEGIN(StackProtector, DEBUG_TYPE, "Insert stack protectors", false, true) INITIALIZE_PASS_END(StackProtector
StringRef getValueAsString() const
Return the attribute's value as a string.
StringRef getName() const
Return a constant reference to the value's name.
DomTreeNodeBase< NodeT > * addNewBlock(NodeT *BB, NodeT *DomBB)
Add a new node to the dominator tree information.
void setAttributes(AttributeList A)
Set the parameter attributes for this call.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value *> Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
LLVM_NODISCARD bool empty() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
Constant * getPersonalityFn() const
Get the personality function associated with this function.
Array or nested array < SSP-buffer-size.
virtual void insertSSPDeclarations(Module &M) const
Inserts necessary declarations for SSP (stack protection) purpose.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Legacy analysis pass which computes a DominatorTree.
static Value * getStackGuard(const TargetLoweringBase *TLI, Module *M, IRBuilder<> &B, bool *SupportsSelectionDAGSP=nullptr)
Create a stack guard loading and populate whether SelectionDAG SSP is supported.
bool shouldEmitSDCheck(const BasicBlock &BB) const
static BranchProbability getBranchProbStackProtector(bool IsLikely)
This file describes how to lower LLVM code to machine code.
an instruction to allocate memory on the stack