1//===-- StackProtector.h - Stack Protector Insertion ----------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This pass inserts stack protectors into functions which need them. A variable 11// with a random value in it is stored onto the stack before the local variables 12// are allocated. Upon exiting the block, the stored value is checked. If it's 13// changed, then there was some sort of violation and the program aborts. 14// 15//===----------------------------------------------------------------------===// 16 17#ifndef LLVM_CODEGEN_STACKPROTECTOR_H 18#define LLVM_CODEGEN_STACKPROTECTOR_H 19 20#include "llvm/ADT/SmallPtrSet.h" 21#include "llvm/ADT/Triple.h" 22#include "llvm/ADT/ValueMap.h" 23#include "llvm/Pass.h" 24#include "llvm/Target/TargetLowering.h" 25 26namespace llvm { 27class DominatorTree; 28class Function; 29class Module; 30class PHINode; 31 32class StackProtector : public FunctionPass { 33public: 34 /// SSPLayoutKind. Stack Smashing Protection (SSP) rules require that 35 /// vulnerable stack allocations are located close the stack protector. 36 enum SSPLayoutKind { 37 SSPLK_None, ///< Did not trigger a stack protector. No effect on data 38 ///< layout. 39 SSPLK_LargeArray, ///< Array or nested array >= SSP-buffer-size. Closest 40 ///< to the stack protector. 41 SSPLK_SmallArray, ///< Array or nested array < SSP-buffer-size. 2nd closest 42 ///< to the stack protector. 43 SSPLK_AddrOf ///< The address of this allocation is exposed and 44 ///< triggered protection. 3rd closest to the protector. 45 }; 46 47 /// A mapping of AllocaInsts to their required SSP layout. 48 typedef ValueMap<const AllocaInst *, SSPLayoutKind> SSPLayoutMap; 49 50private: 51 const TargetMachine *TM; 52 53 /// TLI - Keep a pointer of a TargetLowering to consult for determining 54 /// target type sizes. 55 const TargetLoweringBase *TLI; 56 const Triple Trip; 57 58 Function *F; 59 Module *M; 60 61 DominatorTree *DT; 62 63 /// Layout - Mapping of allocations to the required SSPLayoutKind. 64 /// StackProtector analysis will update this map when determining if an 65 /// AllocaInst triggers a stack protector. 66 SSPLayoutMap Layout; 67 68 /// \brief The minimum size of buffers that will receive stack smashing 69 /// protection when -fstack-protection is used. 70 unsigned SSPBufferSize; 71 72 /// VisitedPHIs - The set of PHI nodes visited when determining 73 /// if a variable's reference has been taken. This set 74 /// is maintained to ensure we don't visit the same PHI node multiple 75 /// times. 76 SmallPtrSet<const PHINode *, 16> VisitedPHIs; 77 78 /// InsertStackProtectors - Insert code into the prologue and epilogue of 79 /// the function. 80 /// 81 /// - The prologue code loads and stores the stack guard onto the stack. 82 /// - The epilogue checks the value stored in the prologue against the 83 /// original value. It calls __stack_chk_fail if they differ. 84 bool InsertStackProtectors(); 85 86 /// CreateFailBB - Create a basic block to jump to when the stack protector 87 /// check fails. 88 BasicBlock *CreateFailBB(); 89 90 /// ContainsProtectableArray - Check whether the type either is an array or 91 /// contains an array of sufficient size so that we need stack protectors 92 /// for it. 93 /// \param [out] IsLarge is set to true if a protectable array is found and 94 /// it is "large" ( >= ssp-buffer-size). In the case of a structure with 95 /// multiple arrays, this gets set if any of them is large. 96 bool ContainsProtectableArray(Type *Ty, bool &IsLarge, bool Strong = false, 97 bool InStruct = false) const; 98 99 /// \brief Check whether a stack allocation has its address taken. 100 bool HasAddressTaken(const Instruction *AI); 101 102 /// RequiresStackProtector - Check whether or not this function needs a 103 /// stack protector based upon the stack protector level. 104 bool RequiresStackProtector(); 105 106public: 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