blob: a506ac636a17a21f276b08737819582d66cc522a [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- StackProtector.h - Stack Protector Insertion -------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This pass inserts stack protectors into functions which need them. A variable
11// with a random value in it is stored onto the stack before the local variables
12// are allocated. Upon exiting the block, the stored value is checked. If it's
13// changed, then there was some sort of violation and the program aborts.
14//
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_CODEGEN_STACKPROTECTOR_H
18#define LLVM_CODEGEN_STACKPROTECTOR_H
19
20#include "llvm/ADT/SmallPtrSet.h"
21#include "llvm/ADT/Triple.h"
Andrew Scullcdfcccc2018-10-05 20:58:37 +010022#include "llvm/CodeGen/MachineFrameInfo.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010023#include "llvm/IR/Instructions.h"
24#include "llvm/IR/ValueMap.h"
25#include "llvm/Pass.h"
26
27namespace llvm {
28
29class BasicBlock;
30class DominatorTree;
31class Function;
32class Instruction;
33class Module;
34class TargetLoweringBase;
35class TargetMachine;
36class Type;
37
38class StackProtector : public FunctionPass {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010039private:
Andrew Scullcdfcccc2018-10-05 20:58:37 +010040 /// A mapping of AllocaInsts to their required SSP layout.
41 using SSPLayoutMap = DenseMap<const AllocaInst *,
42 MachineFrameInfo::SSPLayoutKind>;
43
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010044 const TargetMachine *TM = nullptr;
45
46 /// TLI - Keep a pointer of a TargetLowering to consult for determining
47 /// target type sizes.
48 const TargetLoweringBase *TLI = nullptr;
49 Triple Trip;
50
51 Function *F;
52 Module *M;
53
54 DominatorTree *DT;
55
56 /// Layout - Mapping of allocations to the required SSPLayoutKind.
57 /// StackProtector analysis will update this map when determining if an
58 /// AllocaInst triggers a stack protector.
59 SSPLayoutMap Layout;
60
Andrew Scullcdfcccc2018-10-05 20:58:37 +010061 /// The minimum size of buffers that will receive stack smashing
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010062 /// protection when -fstack-protection is used.
63 unsigned SSPBufferSize = 0;
64
65 /// VisitedPHIs - The set of PHI nodes visited when determining
66 /// if a variable's reference has been taken. This set
67 /// is maintained to ensure we don't visit the same PHI node multiple
68 /// times.
69 SmallPtrSet<const PHINode *, 16> VisitedPHIs;
70
71 // A prologue is generated.
72 bool HasPrologue = false;
73
74 // IR checking code is generated.
75 bool HasIRCheck = false;
76
77 /// InsertStackProtectors - Insert code into the prologue and epilogue of
78 /// the function.
79 ///
80 /// - The prologue code loads and stores the stack guard onto the stack.
81 /// - The epilogue checks the value stored in the prologue against the
82 /// original value. It calls __stack_chk_fail if they differ.
83 bool InsertStackProtectors();
84
85 /// CreateFailBB - Create a basic block to jump to when the stack protector
86 /// check fails.
87 BasicBlock *CreateFailBB();
88
89 /// ContainsProtectableArray - Check whether the type either is an array or
90 /// contains an array of sufficient size so that we need stack protectors
91 /// for it.
92 /// \param [out] IsLarge is set to true if a protectable array is found and
93 /// it is "large" ( >= ssp-buffer-size). In the case of a structure with
94 /// multiple arrays, this gets set if any of them is large.
95 bool ContainsProtectableArray(Type *Ty, bool &IsLarge, bool Strong = false,
96 bool InStruct = false) const;
97
Andrew Scullcdfcccc2018-10-05 20:58:37 +010098 /// Check whether a stack allocation has its address taken.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010099 bool HasAddressTaken(const Instruction *AI);
100
101 /// RequiresStackProtector - Check whether or not this function needs a
102 /// stack protector based upon the stack protector level.
103 bool RequiresStackProtector();
104
105public:
106 static char ID; // Pass identification, replacement for typeid.
107
108 StackProtector() : FunctionPass(ID), SSPBufferSize(8) {
109 initializeStackProtectorPass(*PassRegistry::getPassRegistry());
110 }
111
112 void getAnalysisUsage(AnalysisUsage &AU) const override;
113
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100114 // Return true if StackProtector is supposed to be handled by SelectionDAG.
115 bool shouldEmitSDCheck(const BasicBlock &BB) const;
116
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100117 bool runOnFunction(Function &Fn) override;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100118
119 void copyToMachineFrameInfo(MachineFrameInfo &MFI) const;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100120};
121
122} // end namespace llvm
123
124#endif // LLVM_CODEGEN_STACKPROTECTOR_H