42 #define DEBUG_TYPE "stack-protector"
44 STATISTIC(NumFunProtected,
"Number of functions protected");
45 STATISTIC(NumAddrTaken,
"Number of local variables that have their address"
70 if (I != Layout.
end()) {
78 if (I == Layout.
end())
79 Layout.
insert(std::make_pair(To, Kind));
89 getAnalysisIfAvailable<DominatorTreeWrapperPass>();
98 if (!RequiresStackProtector())
102 return InsertStackProtectors();
108 bool StackProtector::ContainsProtectableArray(
Type *Ty,
bool &IsLarge,
110 bool InStruct)
const {
113 if (
ArrayType *AT = dyn_cast<ArrayType>(Ty)) {
114 if (!AT->getElementType()->isIntegerTy(8)) {
119 if (!Strong && (InStruct || !Trip.
isOSDarwin()))
125 if (SSPBufferSize <= M->getDataLayout().getTypeAllocSize(AT)) {
139 bool NeedsProtector =
false;
143 if (ContainsProtectableArray(*
I, IsLarge, Strong,
true)) {
149 NeedsProtector =
true;
152 return NeedsProtector;
155 bool StackProtector::HasAddressTaken(
const Instruction *AI) {
157 if (
const StoreInst *
SI = dyn_cast<StoreInst>(U)) {
158 if (AI ==
SI->getValueOperand())
161 if (AI ==
SI->getOperand(0))
163 }
else if (isa<CallInst>(U)) {
165 }
else if (isa<InvokeInst>(U)) {
167 }
else if (
const SelectInst *
SI = dyn_cast<SelectInst>(U)) {
168 if (HasAddressTaken(
SI))
170 }
else if (
const PHINode *PN = dyn_cast<PHINode>(U)) {
173 if (VisitedPHIs.insert(PN).second)
174 if (HasAddressTaken(PN))
177 if (HasAddressTaken(
GEP))
179 }
else if (
const BitCastInst *BI = dyn_cast<BitCastInst>(U)) {
180 if (HasAddressTaken(BI))
200 bool StackProtector::RequiresStackProtector() {
202 bool NeedsProtector =
false;
204 NeedsProtector =
true;
213 if (
const AllocaInst *AI = dyn_cast<AllocaInst>(&
I)) {
214 if (AI->isArrayAllocation()) {
220 if (
const auto *CI = dyn_cast<ConstantInt>(AI->getArraySize())) {
221 if (CI->getLimitedValue(SSPBufferSize) >= SSPBufferSize) {
225 NeedsProtector =
true;
229 NeedsProtector =
true;
234 NeedsProtector =
true;
239 bool IsLarge =
false;
240 if (ContainsProtectableArray(AI->getAllocatedType(), IsLarge, Strong)) {
243 NeedsProtector =
true;
247 if (Strong && HasAddressTaken(AI)) {
250 NeedsProtector =
true;
256 return NeedsProtector;
277 unsigned SearchCounter = 0;
278 const unsigned MaxSearch = 4;
279 bool NoInterposingChain =
true;
282 I != E && SearchCounter < MaxSearch; ++
I) {
287 if (isa<DbgInfoIntrinsic>(Inst))
302 if (
CallInst *CI = dyn_cast<CallInst>(Inst)) {
303 if (CI->isTailCall() &&
334 bool SupportsSelectionDAGSP =
false;
346 cast<GlobalValue>(StackGuardVar)
349 SupportsSelectionDAGSP =
true;
354 AI = B.CreateAlloca(PtrTy,
nullptr,
"StackGuardSlot");
355 LoadInst *LI = B.CreateLoad(StackGuardVar,
"StackGuard");
359 return SupportsSelectionDAGSP;
368 bool StackProtector::InsertStackProtectors() {
369 bool HasPrologue =
false;
370 bool SupportsSelectionDAGSP =
373 Value *StackGuardVar =
nullptr;
383 SupportsSelectionDAGSP &=
387 if (SupportsSelectionDAGSP) {
397 assert(InsertionPt !=
nullptr &&
398 "BB must have a terminator instruction at this point.");
453 LoadInst *LI1 = B.CreateLoad(StackGuardVar);
455 Value *Cmp = B.CreateICmpEQ(LI1, LI2);
456 unsigned SuccessWeight =
458 unsigned FailureWeight =
461 .createBranchWeights(SuccessWeight, FailureWeight);
462 B.CreateCondBr(Cmp, NewBB, FailBB, Weights);
486 B.CreateCall(StackChkFail, B.CreateGlobalStringPtr(F->getName(),
"SSH"));
491 B.CreateCall(StackChkFail, {});
493 B.CreateUnreachable();
DomTreeNodeBase< NodeT > * addNewBlock(NodeT *BB, NodeT *DomBB)
addNewBlock - Add a new node to the dominator tree information.
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.
ReturnInst - Return a value (possibly void), from a function.
iplist< Instruction >::iterator eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing basic block and deletes it...
STATISTIC(NumFunctions,"Total number of functions")
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
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. ...
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
CallInst - This class represents a function call, abstracting a target machine's calling convention...
static PointerType * get(Type *ElementType, unsigned AddressSpace)
PointerType::get - This constructs a pointer to an object of the specified type in a numbered address...
bool mayHaveSideEffects() const
mayHaveSideEffects - Return true if the instruction may have side effects.
static Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
const Function * getParent() const
Return the enclosing method, or null if none.
const Instruction & front() const
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
LoadInst - an instruction for reading from memory.
reverse_iterator rbegin()
bool returnTypeIsEligibleForTailCall(const Function *F, const Instruction *I, const ReturnInst *Ret, const TargetLoweringBase &TLI)
Test if given that the input instruction is in the tail call position if the return type or any attri...
static CallInst * FindPotentialTailCall(BasicBlock *BB, ReturnInst *RI, const TargetLoweringBase *TLI)
Identify if RI has a previous instruction in the "Tail Position" and return it.
element_iterator element_end() const
Did not trigger a stack protector.
SelectInst - This class represents the LLVM 'select' instruction.
Type::subtype_iterator element_iterator
static CallInst * Create(Value *Func, ArrayRef< Value * > Args, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
StructType - Class to represent struct types.
static cl::opt< bool > EnableSelectionDAGSP("enable-selectiondag-sp", cl::init(true), cl::Hidden)
INITIALIZE_PASS(StackProtector,"stack-protector","Insert stack protectors", false, true) FunctionPass *llvm
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...
DominatorTree & getDomTree()
element_iterator element_begin() const
The address of this allocation is exposed and triggered protection.
This class represents a cast from a pointer to an integer.
static bool InstructionWillNotHaveChain(const Instruction *I)
bool mayReadFromMemory() const
mayReadFromMemory - Return true if this instruction may read memory.
ArrayType - Class to represent array types.
bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
iterator find(const KeyT &Val)
SSPLayoutKind
SSPLayoutKind.
This class represents a no-op cast from one type to another.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
StoreInst - an instruction for storing to memory.
PointerType - Class to represent pointers.
bool runOnFunction(Function &Fn) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass...
virtual bool getStackCookieLocation(unsigned &, unsigned &) const
Return true if the target stores stack protector cookies at a fixed offset in some non-standard addre...
InstListType::reverse_iterator reverse_iterator
GetElementPtrInst - an instruction for type-safe pointer arithmetic to access elements of arrays and ...
initializer< Ty > init(const Ty &Val)
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeSet AttributeList)
Look up the specified function in the module symbol table.
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.
Constant * getOrInsertGlobal(StringRef Name, Type *Ty)
Look up the specified global in the module symbol table.
This is an important base class in LLVM.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool CreatePrologue(Function *F, Module *M, ReturnInst *RI, const TargetLoweringBase *TLI, const Triple &TT, AllocaInst *&AI, Value *&StackGuardVar)
Insert code into the entry block that stores the __stack_chk_guard variable onto the stack: ...
static Type * getVoidTy(LLVMContext &C)
static uint32_t getBranchWeightStackProtector(bool IsLikely)
FunctionPass class - This class is used to implement most global optimizations.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
void adjustForColoring(const AllocaInst *From, const AllocaInst *To)
SSPLayoutKind getSSPLayout(const AllocaInst *AI) const
LLVMContext & getContext() const
All values hold a context through their type.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Triple - Helper class for working with autoconf configuration names.
This base class for TargetLowering contains the SelectionDAG-independent parts that can be used from ...
bool isOSDarwin() const
isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
void moveAfter(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it right after MovePos in the function M...
FunctionPass * createStackProtectorPass(const TargetMachine *TM)
createStackProtectorPass - This pass adds stack protectors to functions.
Module.h This file contains the declarations for the Module class.
virtual const TargetLowering * getTargetLowering() const
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
const BasicBlock & getEntryBlock() const
iterator_range< user_iterator > users()
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
static IntegerType * getInt32Ty(LLVMContext &C)
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
bool isStringAttribute() const
Return true if the attribute is a string (target-dependent) attribute.
BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
StringRef getValueAsString() const
Return the attribute's value as a string.
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
Primary interface to the complete machine description for the target machine.
bool isSafeToSpeculativelyExecute(const Value *V, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
isSafeToSpeculativelyExecute - Return true if the instruction does not have any effects besides calcu...
Legacy analysis pass which computes a DominatorTree.
Stack protection required.
Array or nested array >= SSP-buffer-size.
bool erase(const KeyT &Val)
Array or nested array < SSP-buffer-size.
AllocaInst - an instruction to allocate memory on the stack.