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/Analysis/DomTreeUpdater.h"
21 #include "llvm/CodeGen/MachineFrameInfo.h"
22 #include "llvm/IR/Instructions.h"
23 #include "llvm/Pass.h"
24 #include "llvm/TargetParser/Triple.h"
25 
26 namespace llvm {
27 
28 class BasicBlock;
29 class Function;
30 class Module;
31 class TargetLoweringBase;
32 class TargetMachine;
33 
34 class StackProtector : public FunctionPass {
35 private:
36   static constexpr unsigned DefaultSSPBufferSize = 8;
37 
38   /// A mapping of AllocaInsts to their required SSP layout.
39   using SSPLayoutMap = DenseMap<const AllocaInst *,
40                                 MachineFrameInfo::SSPLayoutKind>;
41 
42   const TargetMachine *TM = nullptr;
43 
44   /// TLI - Keep a pointer of a TargetLowering to consult for determining
45   /// target type sizes.
46   const TargetLoweringBase *TLI = nullptr;
47   Triple Trip;
48 
49   Function *F = nullptr;
50   Module *M = nullptr;
51 
52   std::optional<DomTreeUpdater> DTU;
53 
54   /// Layout - Mapping of allocations to the required SSPLayoutKind.
55   /// StackProtector analysis will update this map when determining if an
56   /// AllocaInst triggers a stack protector.
57   SSPLayoutMap Layout;
58 
59   /// The minimum size of buffers that will receive stack smashing
60   /// protection when -fstack-protection is used.
61   unsigned SSPBufferSize = DefaultSSPBufferSize;
62 
63   // A prologue is generated.
64   bool HasPrologue = false;
65 
66   // IR checking code is generated.
67   bool HasIRCheck = false;
68 
69   /// InsertStackProtectors - Insert code into the prologue and epilogue of
70   /// the function.
71   ///
72   ///  - The prologue code loads and stores the stack guard onto the stack.
73   ///  - The epilogue checks the value stored in the prologue against the
74   ///    original value. It calls __stack_chk_fail if they differ.
75   bool InsertStackProtectors();
76 
77   /// CreateFailBB - Create a basic block to jump to when the stack protector
78   /// check fails.
79   BasicBlock *CreateFailBB();
80 
81 public:
82   static char ID; // Pass identification, replacement for typeid.
83 
84   StackProtector();
85 
86   void getAnalysisUsage(AnalysisUsage &AU) const override;
87 
88   // Return true if StackProtector is supposed to be handled by SelectionDAG.
89   bool shouldEmitSDCheck(const BasicBlock &BB) const;
90 
91   bool runOnFunction(Function &Fn) override;
92 
93   void copyToMachineFrameInfo(MachineFrameInfo &MFI) const;
94 
95   /// Check whether or not \p F needs a stack protector based upon the stack
96   /// protector level.
97   static bool requiresStackProtector(Function *F, SSPLayoutMap *Layout = nullptr);
98 
99 };
100 
101 } // end namespace llvm
102 
103 #endif // LLVM_CODEGEN_STACKPROTECTOR_H
104