17 #define DEBUG_TYPE "stack-protector"
41 STATISTIC(NumFunProtected,
"Number of functions protected");
42 STATISTIC(NumAddrTaken,
"Number of local variables that have their address"
64 DT = getAnalysisIfAvailable<DominatorTree>();
67 if (!RequiresStackProtector())
71 AttributeSet::FunctionIndex,
"stack-protector-buffer-size");
76 return InsertStackProtectors();
82 bool StackProtector::ContainsProtectableArray(
Type *Ty,
bool &IsLarge,
84 bool InStruct)
const {
87 if (
ArrayType *AT = dyn_cast<ArrayType>(Ty)) {
88 if (!AT->getElementType()->isIntegerTy(8)) {
93 if (!Strong && (InStruct || !Trip.
isOSDarwin()))
99 if (SSPBufferSize <= TLI->getDataLayout()->getTypeAllocSize(AT)) {
113 bool NeedsProtector =
false;
117 if (ContainsProtectableArray(*
I, IsLarge, Strong,
true)) {
123 NeedsProtector =
true;
126 return NeedsProtector;
129 bool StackProtector::HasAddressTaken(
const Instruction *AI) {
133 if (
const StoreInst *SI = dyn_cast<StoreInst>(U)) {
134 if (AI == SI->getValueOperand())
136 }
else if (
const PtrToIntInst *SI = dyn_cast<PtrToIntInst>(U)) {
139 }
else if (isa<CallInst>(U)) {
141 }
else if (isa<InvokeInst>(U)) {
143 }
else if (
const SelectInst *SI = dyn_cast<SelectInst>(U)) {
144 if (HasAddressTaken(SI))
146 }
else if (
const PHINode *PN = dyn_cast<PHINode>(U)) {
149 if (VisitedPHIs.insert(PN))
150 if (HasAddressTaken(PN))
153 if (HasAddressTaken(GEP))
155 }
else if (
const BitCastInst *BI = dyn_cast<BitCastInst>(U)) {
156 if (HasAddressTaken(BI))
176 bool StackProtector::RequiresStackProtector() {
178 bool NeedsProtector =
false;
181 NeedsProtector =
true;
195 if (
AllocaInst *AI = dyn_cast<AllocaInst>(II)) {
196 if (AI->isArrayAllocation()) {
203 dyn_cast<ConstantInt>(AI->getArraySize())) {
204 if (CI->getLimitedValue(SSPBufferSize) >= SSPBufferSize) {
208 NeedsProtector =
true;
212 NeedsProtector =
true;
217 NeedsProtector =
true;
222 bool IsLarge =
false;
223 if (ContainsProtectableArray(AI->getAllocatedType(), IsLarge, Strong)) {
226 NeedsProtector =
true;
230 if (Strong && HasAddressTaken(AI)) {
233 NeedsProtector =
true;
239 return NeedsProtector;
260 unsigned SearchCounter = 0;
261 const unsigned MaxSearch = 4;
262 bool NoInterposingChain =
true;
266 I != E && SearchCounter < MaxSearch; ++
I) {
271 if (isa<DbgInfoIntrinsic>(Inst))
286 if (
CallInst *CI = dyn_cast<CallInst>(Inst)) {
287 if (CI->isTailCall() &&
318 bool SupportsSelectionDAGSP =
false;
329 cast<GlobalValue>(StackGuardVar)
332 SupportsSelectionDAGSP =
true;
337 AI = B.CreateAlloca(PtrTy, 0,
"StackGuardSlot");
338 LoadInst *
LI = B.CreateLoad(StackGuardVar,
"StackGuard");
342 return SupportsSelectionDAGSP;
351 bool StackProtector::InsertStackProtectors() {
352 bool HasPrologue =
false;
353 bool SupportsSelectionDAGSP =
356 Value *StackGuardVar = 0;
366 SupportsSelectionDAGSP &=
370 if (SupportsSelectionDAGSP) {
380 assert(InsertionPt != 0 &&
"BB must have a terminator instruction at "
437 LoadInst *LI1 = B.CreateLoad(StackGuardVar);
439 Value *Cmp = B.CreateICmpEQ(LI1, LI2);
440 B.CreateCondBr(Cmp, NewBB, FailBB);
463 B.CreateCall(StackChkFail, B.CreateGlobalStringPtr(F->
getName(),
"SSH"));
467 B.CreateCall(StackChkFail);
469 B.CreateUnreachable();
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
virtual bool runOnFunction(Function &Fn)
virtual const TargetLowering * getTargetLowering() const
LLVMContext & getContext() const
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
The main container class for the LLVM Intermediate Representation.
bool isReachableFromEntry(const BasicBlock *A) const
ValueT lookup(const KeyT &Val) const
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
static PointerType * get(Type *ElementType, unsigned AddressSpace)
bool mayHaveSideEffects() const
const Function * getParent() const
Return the enclosing method, or null if none.
const Instruction & front() const
reverse_iterator rbegin()
bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const
Return true if the attribute exists at the given index.
bool returnTypeIsEligibleForTailCall(const Function *F, const Instruction *I, const ReturnInst *Ret, const TargetLoweringBase &TLI)
LoopInfoBase< BlockT, LoopT > * LI
StringRef getName() const
static CallInst * FindPotentialTailCall(BasicBlock *BB, ReturnInst *RI, const TargetLoweringBase *TLI)
element_iterator element_end() const
Type::subtype_iterator element_iterator
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...
element_iterator element_begin() const
This class represents a cast from a pointer to an integer.
static bool InstructionWillNotHaveChain(const Instruction *I)
bool mayReadFromMemory() const
This class represents a no-op cast from one type to another.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
static Constant * getIntToPtr(Constant *C, Type *Ty)
virtual bool getStackCookieLocation(unsigned &, unsigned &) const
InstListType::reverse_iterator reverse_iterator
initializer< Ty > init(const Ty &Val)
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeSet AttributeList)
LLVM Basic Block Representation.
Constant * getOrInsertGlobal(StringRef Name, Type *Ty)
LLVM Constant Representation.
static bool CreatePrologue(Function *F, Module *M, ReturnInst *RI, const TargetLoweringBase *TLI, const Triple &Trip, AllocaInst *&AI, Value *&StackGuardVar)
static Type * getVoidTy(LLVMContext &C)
ItTy next(ItTy it, Dist n)
Value * getOperand(unsigned i) const
SSPLayoutKind getSSPLayout(const AllocaInst *AI) const
enable_if_c< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
LLVMContext & getContext() const
All values hold a context through their type.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
static CallInst * Create(Value *Func, ArrayRef< Value * > Args, const Twine &NameStr="", Instruction *InsertBefore=0)
bool isSafeToSpeculativelyExecute(const Value *V, const DataLayout *TD=0)
bool isOSDarwin() const
isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
void moveAfter(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it right after MovePos in the function M...
Class for constant integers.
FunctionPass * createStackProtectorPass(const TargetMachine *TM)
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
const BasicBlock & getEntryBlock() const
AttributeSet getAttributes() const
Return the attribute list for this Function.
STATISTIC(NumFunProtected,"Number of functions protected")
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...
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=0, BasicBlock *InsertBefore=0)
Creates a new BasicBlock.
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.
DomTreeNode * addNewBlock(BasicBlock *BB, BasicBlock *DomBB)
Attribute getAttribute(unsigned Index, Attribute::AttrKind Kind) const
Return the attribute object that exists at the given index.
StringRef getValueAsString() const
Return the attribute's value as a string. This requires the attribute to be a string attribute...
LLVM Value Representation.
Stack protection required.