Home | History | Annotate | Line # | Download | only in CodeGen
      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/CodeGen/MachineFrameInfo.h"
     22 #include "llvm/IR/Instructions.h"
     23 #include "llvm/IR/ValueMap.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   /// A mapping of AllocaInsts to their required SSP layout.
     40   using SSPLayoutMap = DenseMap<const AllocaInst *,
     41                                 MachineFrameInfo::SSPLayoutKind>;
     42 
     43   const TargetMachine *TM = nullptr;
     44 
     45   /// TLI - Keep a pointer of a TargetLowering to consult for determining
     46   /// target type sizes.
     47   const TargetLoweringBase *TLI = nullptr;
     48   Triple Trip;
     49 
     50   Function *F;
     51   Module *M;
     52 
     53   DominatorTree *DT;
     54 
     55   /// Layout - Mapping of allocations to the required SSPLayoutKind.
     56   /// StackProtector analysis will update this map when determining if an
     57   /// AllocaInst triggers a stack protector.
     58   SSPLayoutMap Layout;
     59 
     60   /// The minimum size of buffers that will receive stack smashing
     61   /// protection when -fstack-protection is used.
     62   unsigned SSPBufferSize = 0;
     63 
     64   /// VisitedPHIs - The set of PHI nodes visited when determining
     65   /// if a variable's reference has been taken.  This set
     66   /// is maintained to ensure we don't visit the same PHI node multiple
     67   /// times.
     68   SmallPtrSet<const PHINode *, 16> VisitedPHIs;
     69 
     70   // A prologue is generated.
     71   bool HasPrologue = false;
     72 
     73   // IR checking code is generated.
     74   bool HasIRCheck = false;
     75 
     76   /// InsertStackProtectors - Insert code into the prologue and epilogue of
     77   /// the function.
     78   ///
     79   ///  - The prologue code loads and stores the stack guard onto the stack.
     80   ///  - The epilogue checks the value stored in the prologue against the
     81   ///    original value. It calls __stack_chk_fail if they differ.
     82   bool InsertStackProtectors();
     83 
     84   /// CreateFailBB - Create a basic block to jump to when the stack protector
     85   /// check fails.
     86   BasicBlock *CreateFailBB();
     87 
     88   /// ContainsProtectableArray - Check whether the type either is an array or
     89   /// contains an array of sufficient size so that we need stack protectors
     90   /// for it.
     91   /// \param [out] IsLarge is set to true if a protectable array is found and
     92   /// it is "large" ( >= ssp-buffer-size).  In the case of a structure with
     93   /// multiple arrays, this gets set if any of them is large.
     94   bool ContainsProtectableArray(Type *Ty, bool &IsLarge, bool Strong = false,
     95                                 bool InStruct = false) const;
     96 
     97   /// Check whether a stack allocation has its address taken.
     98   bool HasAddressTaken(const Instruction *AI, uint64_t AllocSize);
     99 
    100   /// RequiresStackProtector - Check whether or not this function needs a
    101   /// stack protector based upon the stack protector level.
    102   bool RequiresStackProtector();
    103 
    104 public:
    105   static char ID; // Pass identification, replacement for typeid.
    106 
    107   StackProtector();
    108 
    109   void getAnalysisUsage(AnalysisUsage &AU) const override;
    110 
    111   // Return true if StackProtector is supposed to be handled by SelectionDAG.
    112   bool shouldEmitSDCheck(const BasicBlock &BB) const;
    113 
    114   bool runOnFunction(Function &Fn) override;
    115 
    116   void copyToMachineFrameInfo(MachineFrameInfo &MFI) const;
    117 };
    118 
    119 } // end namespace llvm
    120 
    121 #endif // LLVM_CODEGEN_STACKPROTECTOR_H
    122