1142425Snectar//===-- StackProtector.h - Stack Protector Insertion ----------------------===// 2160814Ssimon// 3142425Snectar// The LLVM Compiler Infrastructure 4142425Snectar// 5142425Snectar// This file is distributed under the University of Illinois Open Source 6142425Snectar// License. See LICENSE.TXT for details. 7142425Snectar// 8142425Snectar//===----------------------------------------------------------------------===// 9142425Snectar// 10142425Snectar// This pass inserts stack protectors into functions which need them. A variable 11142425Snectar// with a random value in it is stored onto the stack before the local variables 12142425Snectar// are allocated. Upon exiting the block, the stored value is checked. If it's 13142425Snectar// changed, then there was some sort of violation and the program aborts. 14142425Snectar// 15142425Snectar//===----------------------------------------------------------------------===// 16142425Snectar 17142425Snectar#ifndef LLVM_CODEGEN_STACKPROTECTOR_H 18160814Ssimon#define LLVM_CODEGEN_STACKPROTECTOR_H 19142425Snectar 20142425Snectar#include "llvm/ADT/SmallPtrSet.h" 21142425Snectar#include "llvm/ADT/Triple.h" 22142425Snectar#include "llvm/ADT/ValueMap.h" 23142425Snectar#include "llvm/Pass.h" 24142425Snectar#include "llvm/Target/TargetLowering.h" 25142425Snectar 26142425Snectarnamespace llvm { 27142425Snectarclass DominatorTree; 28142425Snectarclass Function; 29142425Snectarclass Module; 30142425Snectarclass PHINode; 31142425Snectar 32142425Snectarclass StackProtector : public FunctionPass { 33142425Snectarpublic: 34142425Snectar /// SSPLayoutKind. Stack Smashing Protection (SSP) rules require that 35142425Snectar /// vulnerable stack allocations are located close the stack protector. 36142425Snectar enum SSPLayoutKind { 37142425Snectar SSPLK_None, ///< Did not trigger a stack protector. No effect on data 38142425Snectar ///< layout. 39142425Snectar SSPLK_LargeArray, ///< Array or nested array >= SSP-buffer-size. Closest 40142425Snectar ///< to the stack protector. 41142425Snectar SSPLK_SmallArray, ///< Array or nested array < SSP-buffer-size. 2nd closest 42142425Snectar ///< to the stack protector. 43142425Snectar SSPLK_AddrOf ///< The address of this allocation is exposed and 44142425Snectar ///< triggered protection. 3rd closest to the protector. 45160814Ssimon }; 46160814Ssimon 47160814Ssimon /// A mapping of AllocaInsts to their required SSP layout. 48160814Ssimon typedef ValueMap<const AllocaInst *, SSPLayoutKind> SSPLayoutMap; 49160814Ssimon 50160814Ssimonprivate: 51142425Snectar const TargetMachine *TM; 52160814Ssimon 53160814Ssimon /// TLI - Keep a pointer of a TargetLowering to consult for determining 54142425Snectar /// target type sizes. 55142425Snectar const TargetLoweringBase *TLI; 56142425Snectar const Triple Trip; 57142425Snectar 58142425Snectar Function *F; 59142425Snectar Module *M; 60142425Snectar 61142425Snectar DominatorTree *DT; 62142425Snectar 63142425Snectar /// Layout - Mapping of allocations to the required SSPLayoutKind. 64160814Ssimon /// StackProtector analysis will update this map when determining if an 65160814Ssimon /// AllocaInst triggers a stack protector. 66142425Snectar SSPLayoutMap Layout; 67142425Snectar 68142425Snectar /// \brief The minimum size of buffers that will receive stack smashing 69142425Snectar /// protection when -fstack-protection is used. 70142425Snectar unsigned SSPBufferSize; 71142425Snectar 72142425Snectar /// VisitedPHIs - The set of PHI nodes visited when determining 73142425Snectar /// if a variable's reference has been taken. This set 74142425Snectar /// is maintained to ensure we don't visit the same PHI node multiple 75142425Snectar /// times. 76142425Snectar SmallPtrSet<const PHINode *, 16> VisitedPHIs; 77142425Snectar 78142425Snectar /// InsertStackProtectors - Insert code into the prologue and epilogue of 79142425Snectar /// the function. 80160814Ssimon /// 81142425Snectar /// - The prologue code loads and stores the stack guard onto the stack. 82142425Snectar /// - The epilogue checks the value stored in the prologue against the 83142425Snectar /// original value. It calls __stack_chk_fail if they differ. 84142425Snectar bool InsertStackProtectors(); 85142425Snectar 86142425Snectar /// CreateFailBB - Create a basic block to jump to when the stack protector 87142425Snectar /// check fails. 88160814Ssimon BasicBlock *CreateFailBB(); 89142425Snectar 90142425Snectar /// ContainsProtectableArray - Check whether the type either is an array or 91142425Snectar /// contains an array of sufficient size so that we need stack protectors 92142425Snectar /// for it. 93142425Snectar /// \param [out] IsLarge is set to true if a protectable array is found and 94142425Snectar /// it is "large" ( >= ssp-buffer-size). In the case of a structure with 95142425Snectar /// multiple arrays, this gets set if any of them is large. 96142425Snectar bool ContainsProtectableArray(Type *Ty, bool &IsLarge, bool Strong = false, 97142425Snectar bool InStruct = false) const; 98142425Snectar 99142425Snectar /// \brief Check whether a stack allocation has its address taken. 100142425Snectar bool HasAddressTaken(const Instruction *AI); 101142425Snectar 102142425Snectar /// RequiresStackProtector - Check whether or not this function needs a 103142425Snectar /// stack protector based upon the stack protector level. 104142425Snectar bool RequiresStackProtector(); 105142425Snectar 106142425Snectarpublic: 107 static char ID; // Pass identification, replacement for typeid. 108 StackProtector() : FunctionPass(ID), TM(0), TLI(0), SSPBufferSize(0) { 109 initializeStackProtectorPass(*PassRegistry::getPassRegistry()); 110 } 111 StackProtector(const TargetMachine *TM) 112 : FunctionPass(ID), TM(TM), TLI(0), Trip(TM->getTargetTriple()), 113 SSPBufferSize(8) { 114 initializeStackProtectorPass(*PassRegistry::getPassRegistry()); 115 } 116 117 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 118 AU.addPreserved<DominatorTree>(); 119 } 120 121 SSPLayoutKind getSSPLayout(const AllocaInst *AI) const; 122 123 virtual bool runOnFunction(Function &Fn); 124}; 125} // end namespace llvm 126 127#endif // LLVM_CODEGEN_STACKPROTECTOR_H 128