1 //===- StackProtector.h - Stack Protector Insertion -------------*- C++ -*-===// 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/CodeGen/MachineFrameInfo.h" 23 #include "llvm/IR/Instructions.h" 24 #include "llvm/IR/ValueMap.h" 25 #include "llvm/Pass.h" 26 27 namespace llvm { 28 29 class BasicBlock; 30 class DominatorTree; 31 class Function; 32 class Instruction; 33 class Module; 34 class TargetLoweringBase; 35 class TargetMachine; 36 class Type; 37 38 class StackProtector : public FunctionPass { 39 private: 40 /// A mapping of AllocaInsts to their required SSP layout. 41 using SSPLayoutMap = DenseMap<const AllocaInst *, 42 MachineFrameInfo::SSPLayoutKind>; 43 44 const TargetMachine *TM = nullptr; 45 46 /// TLI - Keep a pointer of a TargetLowering to consult for determining 47 /// target type sizes. 48 const TargetLoweringBase *TLI = nullptr; 49 Triple Trip; 50 51 Function *F; 52 Module *M; 53 54 DominatorTree *DT; 55 56 /// Layout - Mapping of allocations to the required SSPLayoutKind. 57 /// StackProtector analysis will update this map when determining if an 58 /// AllocaInst triggers a stack protector. 59 SSPLayoutMap Layout; 60 61 /// The minimum size of buffers that will receive stack smashing 62 /// protection when -fstack-protection is used. 63 unsigned SSPBufferSize = 0; 64 65 /// VisitedPHIs - The set of PHI nodes visited when determining 66 /// if a variable's reference has been taken. This set 67 /// is maintained to ensure we don't visit the same PHI node multiple 68 /// times. 69 SmallPtrSet<const PHINode *, 16> VisitedPHIs; 70 71 // A prologue is generated. 72 bool HasPrologue = false; 73 74 // IR checking code is generated. 75 bool HasIRCheck = false; 76 77 /// InsertStackProtectors - Insert code into the prologue and epilogue of 78 /// the function. 79 /// 80 /// - The prologue code loads and stores the stack guard onto the stack. 81 /// - The epilogue checks the value stored in the prologue against the 82 /// original value. It calls __stack_chk_fail if they differ. 83 bool InsertStackProtectors(); 84 85 /// CreateFailBB - Create a basic block to jump to when the stack protector 86 /// check fails. 87 BasicBlock *CreateFailBB(); 88 89 /// ContainsProtectableArray - Check whether the type either is an array or 90 /// contains an array of sufficient size so that we need stack protectors 91 /// for it. 92 /// \param [out] IsLarge is set to true if a protectable array is found and 93 /// it is "large" ( >= ssp-buffer-size). In the case of a structure with 94 /// multiple arrays, this gets set if any of them is large. 95 bool ContainsProtectableArray(Type *Ty, bool &IsLarge, bool Strong = false, 96 bool InStruct = false) const; 97 98 /// Check whether a stack allocation has its address taken. 99 bool HasAddressTaken(const Instruction *AI); 100 101 /// RequiresStackProtector - Check whether or not this function needs a 102 /// stack protector based upon the stack protector level. 103 bool RequiresStackProtector(); 104 105 public: 106 static char ID; // Pass identification, replacement for typeid. 107 StackProtector()108 StackProtector() : FunctionPass(ID), SSPBufferSize(8) { 109 initializeStackProtectorPass(*PassRegistry::getPassRegistry()); 110 } 111 112 void getAnalysisUsage(AnalysisUsage &AU) const override; 113 114 // Return true if StackProtector is supposed to be handled by SelectionDAG. 115 bool shouldEmitSDCheck(const BasicBlock &BB) const; 116 117 bool runOnFunction(Function &Fn) override; 118 119 void copyToMachineFrameInfo(MachineFrameInfo &MFI) const; 120 }; 121 122 } // end namespace llvm 123 124 #endif // LLVM_CODEGEN_STACKPROTECTOR_H 125