43 #define DEBUG_TYPE "stack-protector"
45 STATISTIC(NumFunProtected,
"Number of functions protected");
46 STATISTIC(NumAddrTaken,
"Number of local variables that have their address"
71 if (I != Layout.
end()) {
79 if (I == Layout.
end())
80 Layout.
insert(std::make_pair(To, Kind));
90 getAnalysisIfAvailable<DominatorTreeWrapperPass>();
101 if (!RequiresStackProtector())
113 return InsertStackProtectors();
119 bool StackProtector::ContainsProtectableArray(
Type *Ty,
bool &IsLarge,
121 bool InStruct)
const {
124 if (
ArrayType *AT = dyn_cast<ArrayType>(Ty)) {
125 if (!AT->getElementType()->isIntegerTy(8)) {
130 if (!Strong && (InStruct || !Trip.
isOSDarwin()))
136 if (SSPBufferSize <= M->getDataLayout().getTypeAllocSize(AT)) {
150 bool NeedsProtector =
false;
154 if (ContainsProtectableArray(*
I, IsLarge, Strong,
true)) {
160 NeedsProtector =
true;
163 return NeedsProtector;
166 bool StackProtector::HasAddressTaken(
const Instruction *AI) {
168 if (
const StoreInst *SI = dyn_cast<StoreInst>(U)) {
169 if (AI ==
SI->getValueOperand())
171 }
else if (
const PtrToIntInst *SI = dyn_cast<PtrToIntInst>(U)) {
172 if (AI ==
SI->getOperand(0))
174 }
else if (isa<CallInst>(U)) {
176 }
else if (isa<InvokeInst>(U)) {
178 }
else if (
const SelectInst *SI = dyn_cast<SelectInst>(U)) {
179 if (HasAddressTaken(SI))
181 }
else if (
const PHINode *PN = dyn_cast<PHINode>(U)) {
184 if (VisitedPHIs.insert(PN).second)
185 if (HasAddressTaken(PN))
188 if (HasAddressTaken(
GEP))
190 }
else if (
const BitCastInst *BI = dyn_cast<BitCastInst>(U)) {
191 if (HasAddressTaken(BI))
211 bool StackProtector::RequiresStackProtector() {
213 bool NeedsProtector =
false;
216 if (
const CallInst *CI = dyn_cast<CallInst>(&
I))
217 if (CI->getCalledFunction() ==
219 Intrinsic::stackprotector))
222 if (F->hasFnAttribute(Attribute::SafeStack))
225 if (F->hasFnAttribute(Attribute::StackProtectReq)) {
226 NeedsProtector =
true;
228 }
else if (F->hasFnAttribute(Attribute::StackProtectStrong))
230 else if (HasPrologue)
231 NeedsProtector =
true;
232 else if (!F->hasFnAttribute(Attribute::StackProtect))
237 if (
const AllocaInst *AI = dyn_cast<AllocaInst>(&
I)) {
238 if (AI->isArrayAllocation()) {
239 if (
const auto *CI = dyn_cast<ConstantInt>(AI->getArraySize())) {
240 if (CI->getLimitedValue(SSPBufferSize) >= SSPBufferSize) {
244 NeedsProtector =
true;
248 NeedsProtector =
true;
253 NeedsProtector =
true;
258 bool IsLarge =
false;
259 if (ContainsProtectableArray(AI->getAllocatedType(), IsLarge, Strong)) {
262 NeedsProtector =
true;
266 if (Strong && HasAddressTaken(AI)) {
269 NeedsProtector =
true;
275 return NeedsProtector;
282 bool *SupportsSelectionDAGSP =
nullptr) {
284 return B.
CreateLoad(Guard,
true,
"StackGuard");
297 if (SupportsSelectionDAGSP)
298 *SupportsSelectionDAGSP =
true;
315 bool SupportsSelectionDAGSP =
false;
318 AI =
B.CreateAlloca(PtrTy,
nullptr,
"StackGuardSlot");
323 return SupportsSelectionDAGSP;
332 bool StackProtector::InsertStackProtectors() {
333 bool SupportsSelectionDAGSP =
351 if (SupportsSelectionDAGSP)
366 LoadInst *Guard =
B.CreateLoad(AI,
true,
"Guard");
423 Value *Cmp =
B.CreateICmpEQ(Guard, LI2);
429 .createBranchWeights(SuccessProb.getNumerator(),
430 FailureProb.getNumerator());
431 B.CreateCondBr(Cmp, NewBB, FailBB, Weights);
446 B.SetCurrentDebugLocation(
DebugLoc::get(0, 0, F->getSubprogram()));
453 B.CreateCall(StackChkFail,
B.CreateGlobalStringPtr(F->getName(),
"SSH"));
458 B.CreateCall(StackChkFail, {});
460 B.CreateUnreachable();
DomTreeNodeBase< NodeT > * addNewBlock(NodeT *BB, NodeT *DomBB)
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.
Return a value (possibly void), from a function.
SymbolTableList< Instruction >::iterator 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)
INITIALIZE_TM_PASS(StackProtector,"stack-protector","Insert stack protectors", false, true) FunctionPass *llvm
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...
This class represents a function call, abstracting a target machine's calling convention.
const Instruction & front() const
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
An instruction for reading from memory.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
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: ...
void setCallingConv(CallingConv::ID CC)
element_iterator element_end() const
Did not trigger a stack protector.
This class represents the LLVM 'select' instruction.
DILocation * get() const
Get the underlying DILocation.
Type::subtype_iterator element_iterator
Class to represent struct types.
static cl::opt< bool > EnableSelectionDAGSP("enable-selectiondag-sp", cl::init(true), cl::Hidden)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Constant * getPersonalityFn() const
Get the personality function associated with this function.
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.
virtual Value * getIRStackGuard(IRBuilder<> &IRB) const
If the target has a standard location for the stack protector guard, returns the address of that loca...
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.
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
An instruction for storing to memory.
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 setAttributes(AttributeSet Attrs)
Set the parameter attributes for this call.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
LoadInst * CreateLoad(Value *Ptr, const char *Name)
initializer< Ty > init(const Ty &Val)
bool shouldEmitSDCheck(const BasicBlock &BB) const
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.
virtual void insertSSPDeclarations(Module &M) const
Inserts necessary declarations for SSP (stack protection) purpose.
This is an important base class in LLVM.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
bool hasPersonalityFn() const
Check whether this function has a personality function.
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
static Type * getVoidTy(LLVMContext &C)
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)
self_iterator getIterator()
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)
This base class for TargetLowering contains the SelectionDAG-independent parts that can be used from ...
virtual Value * getSSPStackGuardCheck(const Module &M) const
If the target has a standard stack protection check function that performs validation and error handl...
bool isOSDarwin() const
isOSDarwin - Is this a "Darwin" OS (OS X, iOS, or watchOS).
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
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...
FunctionPass * createStackProtectorPass(const TargetMachine *TM)
createStackProtectorPass - This pass adds stack protectors to functions.
bool isFuncletEHPersonality(EHPersonality Pers)
Returns true if this is a personality function that invokes handler funclets (which must return to it...
Module.h This file contains the declarations for the Module class.
virtual const TargetLowering * getTargetLowering() const
const BasicBlock & getEntryBlock() const
AttributeSet getAttributes() const
Return the attribute list for this Function.
iterator_range< user_iterator > users()
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
CallInst * CreateCall(Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
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.
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.
static BranchProbability getBranchProbStackProtector(bool IsLikely)
Array or nested array >= SSP-buffer-size.
bool erase(const KeyT &Val)
Array or nested array < SSP-buffer-size.
an instruction to allocate memory on the stack