xref: /openbsd-src/gnu/llvm/llvm/include/llvm/CodeGen/StackProtector.h (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
1 //===- StackProtector.h - Stack Protector Insertion -------------*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
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.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef LLVM_CODEGEN_STACKPROTECTOR_H
17 #define LLVM_CODEGEN_STACKPROTECTOR_H
18 
19 #include "llvm/ADT/SmallPtrSet.h"
20 #include "llvm/ADT/Triple.h"
21 #include "llvm/Analysis/DomTreeUpdater.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/IR/Instructions.h"
24 #include "llvm/Pass.h"
25 
26 namespace llvm {
27 
28 class BasicBlock;
29 class DominatorTree;
30 class Function;
31 class Instruction;
32 class Module;
33 class TargetLoweringBase;
34 class TargetMachine;
35 class Type;
36 
37 class StackProtector : public FunctionPass {
38 private:
39   static constexpr unsigned DefaultSSPBufferSize = 8;
40 
41   /// A mapping of AllocaInsts to their required SSP layout.
42   using SSPLayoutMap = DenseMap<const AllocaInst *,
43                                 MachineFrameInfo::SSPLayoutKind>;
44 
45   const TargetMachine *TM = nullptr;
46 
47   /// TLI - Keep a pointer of a TargetLowering to consult for determining
48   /// target type sizes.
49   const TargetLoweringBase *TLI = nullptr;
50   Triple Trip;
51 
52   Function *F;
53   Module *M;
54 
55   std::optional<DomTreeUpdater> DTU;
56 
57   /// Layout - Mapping of allocations to the required SSPLayoutKind.
58   /// StackProtector analysis will update this map when determining if an
59   /// AllocaInst triggers a stack protector.
60   SSPLayoutMap Layout;
61 
62   /// The minimum size of buffers that will receive stack smashing
63   /// protection when -fstack-protection is used.
64   unsigned SSPBufferSize = DefaultSSPBufferSize;
65 
66   /// VisitedPHIs - The set of PHI nodes visited when determining
67   /// if a variable's reference has been taken.  This set
68   /// is maintained to ensure we don't visit the same PHI node multiple
69   /// times.
70   SmallPtrSet<const PHINode *, 16> VisitedPHIs;
71 
72   // A prologue is generated.
73   bool HasPrologue = false;
74 
75   // IR checking code is generated.
76   bool HasIRCheck = false;
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   /// Check whether a stack allocation has its address taken.
100   bool HasAddressTaken(const Instruction *AI, TypeSize AllocSize);
101 
102   /// RequiresStackProtector - Check whether or not this function needs a
103   /// stack protector based upon the stack protector level.
104   bool RequiresStackProtector();
105 
106 public:
107   static char ID; // Pass identification, replacement for typeid.
108 
109   StackProtector();
110 
111   void getAnalysisUsage(AnalysisUsage &AU) const override;
112 
113   // Return true if StackProtector is supposed to be handled by SelectionDAG.
114   bool shouldEmitSDCheck(const BasicBlock &BB) const;
115 
116   bool runOnFunction(Function &Fn) override;
117 
118   void copyToMachineFrameInfo(MachineFrameInfo &MFI) const;
119 };
120 
121 } // end namespace llvm
122 
123 #endif // LLVM_CODEGEN_STACKPROTECTOR_H
124