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