1 //===-- StackProtector.h - Stack Protector Insertion ----------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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.
15 //===----------------------------------------------------------------------===//
17 #ifndef LLVM_CODEGEN_STACKPROTECTOR_H
18 #define LLVM_CODEGEN_STACKPROTECTOR_H
20 #include "llvm/ADT/SmallPtrSet.h"
21 #include "llvm/ADT/Triple.h"
22 #include "llvm/IR/Dominators.h"
23 #include "llvm/IR/ValueMap.h"
24 #include "llvm/Pass.h"
25 #include "llvm/Target/TargetLowering.h"
32 class StackProtector : public FunctionPass {
34 /// SSPLayoutKind. Stack Smashing Protection (SSP) rules require that
35 /// vulnerable stack allocations are located close the stack protector.
37 SSPLK_None, ///< Did not trigger a stack protector. No effect on data
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.
47 /// A mapping of AllocaInsts to their required SSP layout.
48 typedef ValueMap<const AllocaInst *, SSPLayoutKind> SSPLayoutMap;
51 const TargetMachine *TM;
53 /// TLI - Keep a pointer of a TargetLowering to consult for determining
54 /// target type sizes.
55 const TargetLoweringBase *TLI;
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.
68 /// \brief The minimum size of buffers that will receive stack smashing
69 /// protection when -fstack-protection is used.
70 unsigned SSPBufferSize;
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
76 SmallPtrSet<const PHINode *, 16> VisitedPHIs;
78 /// InsertStackProtectors - Insert code into the prologue and epilogue of
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();
86 /// CreateFailBB - Create a basic block to jump to when the stack protector
88 BasicBlock *CreateFailBB();
90 /// ContainsProtectableArray - Check whether the type either is an array or
91 /// contains an array of sufficient size so that we need stack protectors
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;
99 /// \brief Check whether a stack allocation has its address taken.
100 bool HasAddressTaken(const Instruction *AI);
102 /// RequiresStackProtector - Check whether or not this function needs a
103 /// stack protector based upon the stack protector level.
104 bool RequiresStackProtector();
107 static char ID; // Pass identification, replacement for typeid.
109 : FunctionPass(ID), TM(nullptr), TLI(nullptr), SSPBufferSize(0) {
110 initializeStackProtectorPass(*PassRegistry::getPassRegistry());
112 StackProtector(const TargetMachine *TM)
113 : FunctionPass(ID), TM(TM), TLI(nullptr), Trip(TM->getTargetTriple()),
115 initializeStackProtectorPass(*PassRegistry::getPassRegistry());
118 void getAnalysisUsage(AnalysisUsage &AU) const override {
119 AU.addPreserved<DominatorTreeWrapperPass>();
122 SSPLayoutKind getSSPLayout(const AllocaInst *AI) const;
123 void adjustForColoring(const AllocaInst *From, const AllocaInst *To);
125 bool runOnFunction(Function &Fn) override;
127 } // end namespace llvm
129 #endif // LLVM_CODEGEN_STACKPROTECTOR_H