1 //===- StackProtector.h - Stack Protector Insertion -------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This pass inserts stack protectors into functions which need them. A variable
10 // with a random value in it is stored onto the stack before the local variables
11 // are allocated. Upon exiting the block, the stored value is checked. If it's
12 // changed, then there was some sort of violation and the program aborts.
14 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_CODEGEN_STACKPROTECTOR_H
17 #define LLVM_CODEGEN_STACKPROTECTOR_H
19 #include "llvm/ADT/SmallPtrSet.h"
20 #include "llvm/ADT/Triple.h"
21 #include "llvm/CodeGen/MachineFrameInfo.h"
22 #include "llvm/IR/Instructions.h"
23 #include "llvm/IR/ValueMap.h"
24 #include "llvm/Pass.h"
33 class TargetLoweringBase
;
37 class StackProtector
: public FunctionPass
{
39 /// A mapping of AllocaInsts to their required SSP layout.
40 using SSPLayoutMap
= DenseMap
<const AllocaInst
*,
41 MachineFrameInfo::SSPLayoutKind
>;
43 const TargetMachine
*TM
= nullptr;
45 /// TLI - Keep a pointer of a TargetLowering to consult for determining
46 /// target type sizes.
47 const TargetLoweringBase
*TLI
= nullptr;
55 /// Layout - Mapping of allocations to the required SSPLayoutKind.
56 /// StackProtector analysis will update this map when determining if an
57 /// AllocaInst triggers a stack protector.
60 /// The minimum size of buffers that will receive stack smashing
61 /// protection when -fstack-protection is used.
62 unsigned SSPBufferSize
= 0;
64 /// VisitedPHIs - The set of PHI nodes visited when determining
65 /// if a variable's reference has been taken. This set
66 /// is maintained to ensure we don't visit the same PHI node multiple
68 SmallPtrSet
<const PHINode
*, 16> VisitedPHIs
;
70 // A prologue is generated.
71 bool HasPrologue
= false;
73 // IR checking code is generated.
74 bool HasIRCheck
= false;
76 /// InsertStackProtectors - Insert code into the prologue and epilogue of
79 /// - The prologue code loads and stores the stack guard onto the stack.
80 /// - The epilogue checks the value stored in the prologue against the
81 /// original value. It calls __stack_chk_fail if they differ.
82 bool InsertStackProtectors();
84 /// CreateFailBB - Create a basic block to jump to when the stack protector
86 BasicBlock
*CreateFailBB();
88 /// ContainsProtectableArray - Check whether the type either is an array or
89 /// contains an array of sufficient size so that we need stack protectors
91 /// \param [out] IsLarge is set to true if a protectable array is found and
92 /// it is "large" ( >= ssp-buffer-size). In the case of a structure with
93 /// multiple arrays, this gets set if any of them is large.
94 bool ContainsProtectableArray(Type
*Ty
, bool &IsLarge
, bool Strong
= false,
95 bool InStruct
= false) const;
97 /// Check whether a stack allocation has its address taken.
98 bool HasAddressTaken(const Instruction
*AI
);
100 /// RequiresStackProtector - Check whether or not this function needs a
101 /// stack protector based upon the stack protector level.
102 bool RequiresStackProtector();
105 static char ID
; // Pass identification, replacement for typeid.
107 StackProtector() : FunctionPass(ID
), SSPBufferSize(8) {
108 initializeStackProtectorPass(*PassRegistry::getPassRegistry());
111 void getAnalysisUsage(AnalysisUsage
&AU
) const override
;
113 // Return true if StackProtector is supposed to be handled by SelectionDAG.
114 bool shouldEmitSDCheck(const BasicBlock
&BB
) const;
116 bool runOnFunction(Function
&Fn
) override
;
118 void copyToMachineFrameInfo(MachineFrameInfo
&MFI
) const;
121 } // end namespace llvm
123 #endif // LLVM_CODEGEN_STACKPROTECTOR_H