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