llvm.org GIT mirror llvm / release_50 include / llvm / CodeGen / StackProtector.h
release_50

Tree @release_50 (Download .tar.gz)

StackProtector.h @release_50

096e40d
18ebd48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
643c0a4
7225e27
18ebd48
 
 
096e40d
643c0a4
 
18ebd48
643c0a4
18ebd48
643c0a4
6764d46
643c0a4
18ebd48
 
4598b40
ec4b539
4598b40
 
9794186
 
 
 
 
 
 
 
4598b40
 
 
643c0a4
4598b40
 
096e40d
18ebd48
 
 
096e40d
ae1c853
18ebd48
 
 
 
 
 
4598b40
 
 
 
 
18ebd48
 
096e40d
18ebd48
 
 
 
 
62406fd
18ebd48
1a7750e
 
 
 
 
 
18ebd48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4598b40
 
 
 
18ebd48
 
 
 
 
 
 
 
62406fd
18ebd48
62406fd
096e40d
ae1c853
18ebd48
 
 
6764d46
18ebd48
4598b40
1a7750e
 
 
 
07b072b
4598b40
9f998de
18ebd48
096e40d
18ebd48
 
 
//===- StackProtector.h - Stack Protector Insertion -------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass inserts stack protectors into functions which need them. A variable
// with a random value in it is stored onto the stack before the local variables
// are allocated. Upon exiting the block, the stored value is checked. If it's
// changed, then there was some sort of violation and the program aborts.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CODEGEN_STACKPROTECTOR_H
#define LLVM_CODEGEN_STACKPROTECTOR_H

#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Triple.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/ValueMap.h"
#include "llvm/Pass.h"

namespace llvm {

class BasicBlock;
class DominatorTree;
class Function;
class Instruction;
class Module;
class TargetLoweringBase;
class TargetMachine;
class Type;

class StackProtector : public FunctionPass {
public:
  /// SSPLayoutKind.  Stack Smashing Protection (SSP) rules require that
  /// vulnerable stack allocations are located close the stack protector.
  enum SSPLayoutKind {
    SSPLK_None,       ///< Did not trigger a stack protector.  No effect on data
                      ///< layout.
    SSPLK_LargeArray, ///< Array or nested array >= SSP-buffer-size.  Closest
                      ///< to the stack protector.
    SSPLK_SmallArray, ///< Array or nested array < SSP-buffer-size. 2nd closest
                      ///< to the stack protector.
    SSPLK_AddrOf      ///< The address of this allocation is exposed and
                      ///< triggered protection.  3rd closest to the protector.
  };

  /// A mapping of AllocaInsts to their required SSP layout.
  using SSPLayoutMap = ValueMap<const AllocaInst *, SSPLayoutKind>;

private:
  const TargetMachine *TM = nullptr;

  /// TLI - Keep a pointer of a TargetLowering to consult for determining
  /// target type sizes.
  const TargetLoweringBase *TLI = nullptr;
  Triple Trip;

  Function *F;
  Module *M;

  DominatorTree *DT;

  /// Layout - Mapping of allocations to the required SSPLayoutKind.
  /// StackProtector analysis will update this map when determining if an
  /// AllocaInst triggers a stack protector.
  SSPLayoutMap Layout;

  /// \brief The minimum size of buffers that will receive stack smashing
  /// protection when -fstack-protection is used.
  unsigned SSPBufferSize = 0;

  /// VisitedPHIs - The set of PHI nodes visited when determining
  /// if a variable's reference has been taken.  This set
  /// is maintained to ensure we don't visit the same PHI node multiple
  /// times.
  SmallPtrSet<const PHINode *, 16> VisitedPHIs;

  // A prologue is generated.
  bool HasPrologue = false;

  // IR checking code is generated.
  bool HasIRCheck = false;

  /// InsertStackProtectors - Insert code into the prologue and epilogue of
  /// the function.
  ///
  ///  - The prologue code loads and stores the stack guard onto the stack.
  ///  - The epilogue checks the value stored in the prologue against the
  ///    original value. It calls __stack_chk_fail if they differ.
  bool InsertStackProtectors();

  /// CreateFailBB - Create a basic block to jump to when the stack protector
  /// check fails.
  BasicBlock *CreateFailBB();

  /// ContainsProtectableArray - Check whether the type either is an array or
  /// contains an array of sufficient size so that we need stack protectors
  /// for it.
  /// \param [out] IsLarge is set to true if a protectable array is found and
  /// it is "large" ( >= ssp-buffer-size).  In the case of a structure with
  /// multiple arrays, this gets set if any of them is large.
  bool ContainsProtectableArray(Type *Ty, bool &IsLarge, bool Strong = false,
                                bool InStruct = false) const;

  /// \brief Check whether a stack allocation has its address taken.
  bool HasAddressTaken(const Instruction *AI);

  /// RequiresStackProtector - Check whether or not this function needs a
  /// stack protector based upon the stack protector level.
  bool RequiresStackProtector();

public:
  static char ID; // Pass identification, replacement for typeid.

  StackProtector() : FunctionPass(ID), SSPBufferSize(8) {
    initializeStackProtectorPass(*PassRegistry::getPassRegistry());
  }

  void getAnalysisUsage(AnalysisUsage &AU) const override;

  SSPLayoutKind getSSPLayout(const AllocaInst *AI) const;

  // Return true if StackProtector is supposed to be handled by SelectionDAG.
  bool shouldEmitSDCheck(const BasicBlock &BB) const;

  void adjustForColoring(const AllocaInst *From, const AllocaInst *To);

  bool runOnFunction(Function &Fn) override;
};

} // end namespace llvm

#endif // LLVM_CODEGEN_STACKPROTECTOR_H