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/IR/PassManager.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 SSPLayoutInfo { 35 friend class StackProtectorPass; 36 friend class SSPLayoutAnalysis; 37 friend class StackProtector; 38 static constexpr unsigned DefaultSSPBufferSize = 8; 39 40 /// A mapping of AllocaInsts to their required SSP layout. 41 using SSPLayoutMap = 42 DenseMap<const AllocaInst *, MachineFrameInfo::SSPLayoutKind>; 43 44 /// Layout - Mapping of allocations to the required SSPLayoutKind. 45 /// StackProtector analysis will update this map when determining if an 46 /// AllocaInst triggers a stack protector. 47 SSPLayoutMap Layout; 48 49 /// The minimum size of buffers that will receive stack smashing 50 /// protection when -fstack-protection is used. 51 unsigned SSPBufferSize = DefaultSSPBufferSize; 52 53 bool RequireStackProtector = false; 54 55 // A prologue is generated. 56 bool HasPrologue = false; 57 58 // IR checking code is generated. 59 bool HasIRCheck = false; 60 61 public: 62 // Return true if StackProtector is supposed to be handled by SelectionDAG. 63 bool shouldEmitSDCheck(const BasicBlock &BB) const; 64 65 void copyToMachineFrameInfo(MachineFrameInfo &MFI) const; 66 }; 67 68 class SSPLayoutAnalysis : public AnalysisInfoMixin<SSPLayoutAnalysis> { 69 friend AnalysisInfoMixin<SSPLayoutAnalysis>; 70 using SSPLayoutMap = SSPLayoutInfo::SSPLayoutMap; 71 72 static AnalysisKey Key; 73 74 public: 75 using Result = SSPLayoutInfo; 76 77 Result run(Function &F, FunctionAnalysisManager &FAM); 78 79 /// Check whether or not \p F needs a stack protector based upon the stack 80 /// protector level. 81 static bool requiresStackProtector(Function *F, 82 SSPLayoutMap *Layout = nullptr); 83 }; 84 85 class StackProtectorPass : public PassInfoMixin<StackProtectorPass> { 86 const TargetMachine *TM; 87 88 public: StackProtectorPass(const TargetMachine * TM)89 explicit StackProtectorPass(const TargetMachine *TM) : TM(TM) {} 90 PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM); 91 }; 92 93 class StackProtector : public FunctionPass { 94 private: 95 /// A mapping of AllocaInsts to their required SSP layout. 96 using SSPLayoutMap = SSPLayoutInfo::SSPLayoutMap; 97 98 const TargetMachine *TM = nullptr; 99 100 Function *F = nullptr; 101 Module *M = nullptr; 102 103 std::optional<DomTreeUpdater> DTU; 104 105 SSPLayoutInfo LayoutInfo; 106 107 public: 108 static char ID; // Pass identification, replacement for typeid. 109 110 StackProtector(); 111 getLayoutInfo()112 SSPLayoutInfo &getLayoutInfo() { return LayoutInfo; } 113 114 void getAnalysisUsage(AnalysisUsage &AU) const override; 115 116 // Return true if StackProtector is supposed to be handled by SelectionDAG. shouldEmitSDCheck(const BasicBlock & BB)117 bool shouldEmitSDCheck(const BasicBlock &BB) const { 118 return LayoutInfo.shouldEmitSDCheck(BB); 119 } 120 121 bool runOnFunction(Function &Fn) override; 122 copyToMachineFrameInfo(MachineFrameInfo & MFI)123 void copyToMachineFrameInfo(MachineFrameInfo &MFI) const { 124 LayoutInfo.copyToMachineFrameInfo(MFI); 125 } 126 127 /// Check whether or not \p F needs a stack protector based upon the stack 128 /// protector level. 129 static bool requiresStackProtector(Function *F, 130 SSPLayoutMap *Layout = nullptr) { 131 return SSPLayoutAnalysis::requiresStackProtector(F, Layout); 132 } 133 }; 134 135 } // end namespace llvm 136 137 #endif // LLVM_CODEGEN_STACKPROTECTOR_H 138