1*9880d681SAndroid Build Coastguard Worker //===-- SafeStack.cpp - Safe Stack Insertion ------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This pass splits the stack into the safe stack (kept as-is for LLVM backend)
11*9880d681SAndroid Build Coastguard Worker // and the unsafe stack (explicitly allocated and managed through the runtime
12*9880d681SAndroid Build Coastguard Worker // support library).
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker // http://clang.llvm.org/docs/SafeStack.html
15*9880d681SAndroid Build Coastguard Worker //
16*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
17*9880d681SAndroid Build Coastguard Worker
18*9880d681SAndroid Build Coastguard Worker #include "SafeStackColoring.h"
19*9880d681SAndroid Build Coastguard Worker #include "SafeStackLayout.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Triple.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/BranchProbabilityInfo.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ScalarEvolution.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ScalarEvolutionExpressions.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/Passes.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DIBuilder.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DataLayout.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DerivedTypes.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Function.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/IRBuilder.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/InstIterator.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Instructions.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/IntrinsicInst.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Intrinsics.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/MDBuilder.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/Pass.h"
39*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
40*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
41*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Format.h"
42*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MathExtras.h"
43*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_os_ostream.h"
44*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetLowering.h"
45*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetSubtargetInfo.h"
46*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/BasicBlockUtils.h"
47*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/Local.h"
48*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/ModuleUtils.h"
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker using namespace llvm;
51*9880d681SAndroid Build Coastguard Worker using namespace llvm::safestack;
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "safestack"
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker enum UnsafeStackPtrStorageVal { ThreadLocalUSP, SingleThreadUSP };
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Worker static cl::opt<UnsafeStackPtrStorageVal> USPStorage("safe-stack-usp-storage",
58*9880d681SAndroid Build Coastguard Worker cl::Hidden, cl::init(ThreadLocalUSP),
59*9880d681SAndroid Build Coastguard Worker cl::desc("Type of storage for the unsafe stack pointer"),
60*9880d681SAndroid Build Coastguard Worker cl::values(clEnumValN(ThreadLocalUSP, "thread-local",
61*9880d681SAndroid Build Coastguard Worker "Thread-local storage"),
62*9880d681SAndroid Build Coastguard Worker clEnumValN(SingleThreadUSP, "single-thread",
63*9880d681SAndroid Build Coastguard Worker "Non-thread-local storage"),
64*9880d681SAndroid Build Coastguard Worker clEnumValEnd));
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker namespace llvm {
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard Worker STATISTIC(NumFunctions, "Total number of functions");
69*9880d681SAndroid Build Coastguard Worker STATISTIC(NumUnsafeStackFunctions, "Number of functions with unsafe stack");
70*9880d681SAndroid Build Coastguard Worker STATISTIC(NumUnsafeStackRestorePointsFunctions,
71*9880d681SAndroid Build Coastguard Worker "Number of functions that use setjmp or exceptions");
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Worker STATISTIC(NumAllocas, "Total number of allocas");
74*9880d681SAndroid Build Coastguard Worker STATISTIC(NumUnsafeStaticAllocas, "Number of unsafe static allocas");
75*9880d681SAndroid Build Coastguard Worker STATISTIC(NumUnsafeDynamicAllocas, "Number of unsafe dynamic allocas");
76*9880d681SAndroid Build Coastguard Worker STATISTIC(NumUnsafeByValArguments, "Number of unsafe byval arguments");
77*9880d681SAndroid Build Coastguard Worker STATISTIC(NumUnsafeStackRestorePoints, "Number of setjmps and landingpads");
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard Worker } // namespace llvm
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker namespace {
82*9880d681SAndroid Build Coastguard Worker
83*9880d681SAndroid Build Coastguard Worker /// Rewrite an SCEV expression for a memory access address to an expression that
84*9880d681SAndroid Build Coastguard Worker /// represents offset from the given alloca.
85*9880d681SAndroid Build Coastguard Worker ///
86*9880d681SAndroid Build Coastguard Worker /// The implementation simply replaces all mentions of the alloca with zero.
87*9880d681SAndroid Build Coastguard Worker class AllocaOffsetRewriter : public SCEVRewriteVisitor<AllocaOffsetRewriter> {
88*9880d681SAndroid Build Coastguard Worker const Value *AllocaPtr;
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker public:
AllocaOffsetRewriter(ScalarEvolution & SE,const Value * AllocaPtr)91*9880d681SAndroid Build Coastguard Worker AllocaOffsetRewriter(ScalarEvolution &SE, const Value *AllocaPtr)
92*9880d681SAndroid Build Coastguard Worker : SCEVRewriteVisitor(SE), AllocaPtr(AllocaPtr) {}
93*9880d681SAndroid Build Coastguard Worker
visitUnknown(const SCEVUnknown * Expr)94*9880d681SAndroid Build Coastguard Worker const SCEV *visitUnknown(const SCEVUnknown *Expr) {
95*9880d681SAndroid Build Coastguard Worker if (Expr->getValue() == AllocaPtr)
96*9880d681SAndroid Build Coastguard Worker return SE.getZero(Expr->getType());
97*9880d681SAndroid Build Coastguard Worker return Expr;
98*9880d681SAndroid Build Coastguard Worker }
99*9880d681SAndroid Build Coastguard Worker };
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Worker /// The SafeStack pass splits the stack of each function into the safe
102*9880d681SAndroid Build Coastguard Worker /// stack, which is only accessed through memory safe dereferences (as
103*9880d681SAndroid Build Coastguard Worker /// determined statically), and the unsafe stack, which contains all
104*9880d681SAndroid Build Coastguard Worker /// local variables that are accessed in ways that we can't prove to
105*9880d681SAndroid Build Coastguard Worker /// be safe.
106*9880d681SAndroid Build Coastguard Worker class SafeStack : public FunctionPass {
107*9880d681SAndroid Build Coastguard Worker const TargetMachine *TM;
108*9880d681SAndroid Build Coastguard Worker const TargetLoweringBase *TL;
109*9880d681SAndroid Build Coastguard Worker const DataLayout *DL;
110*9880d681SAndroid Build Coastguard Worker ScalarEvolution *SE;
111*9880d681SAndroid Build Coastguard Worker
112*9880d681SAndroid Build Coastguard Worker Type *StackPtrTy;
113*9880d681SAndroid Build Coastguard Worker Type *IntPtrTy;
114*9880d681SAndroid Build Coastguard Worker Type *Int32Ty;
115*9880d681SAndroid Build Coastguard Worker Type *Int8Ty;
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker Value *UnsafeStackPtr = nullptr;
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Worker /// Unsafe stack alignment. Each stack frame must ensure that the stack is
120*9880d681SAndroid Build Coastguard Worker /// aligned to this value. We need to re-align the unsafe stack if the
121*9880d681SAndroid Build Coastguard Worker /// alignment of any object on the stack exceeds this value.
122*9880d681SAndroid Build Coastguard Worker ///
123*9880d681SAndroid Build Coastguard Worker /// 16 seems like a reasonable upper bound on the alignment of objects that we
124*9880d681SAndroid Build Coastguard Worker /// might expect to appear on the stack on most common targets.
125*9880d681SAndroid Build Coastguard Worker enum { StackAlignment = 16 };
126*9880d681SAndroid Build Coastguard Worker
127*9880d681SAndroid Build Coastguard Worker /// \brief Build a value representing a pointer to the unsafe stack pointer.
128*9880d681SAndroid Build Coastguard Worker Value *getOrCreateUnsafeStackPtr(IRBuilder<> &IRB, Function &F);
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Worker /// \brief Return the value of the stack canary.
131*9880d681SAndroid Build Coastguard Worker Value *getStackGuard(IRBuilder<> &IRB, Function &F);
132*9880d681SAndroid Build Coastguard Worker
133*9880d681SAndroid Build Coastguard Worker /// \brief Load stack guard from the frame and check if it has changed.
134*9880d681SAndroid Build Coastguard Worker void checkStackGuard(IRBuilder<> &IRB, Function &F, ReturnInst &RI,
135*9880d681SAndroid Build Coastguard Worker AllocaInst *StackGuardSlot, Value *StackGuard);
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Worker /// \brief Find all static allocas, dynamic allocas, return instructions and
138*9880d681SAndroid Build Coastguard Worker /// stack restore points (exception unwind blocks and setjmp calls) in the
139*9880d681SAndroid Build Coastguard Worker /// given function and append them to the respective vectors.
140*9880d681SAndroid Build Coastguard Worker void findInsts(Function &F, SmallVectorImpl<AllocaInst *> &StaticAllocas,
141*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<AllocaInst *> &DynamicAllocas,
142*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<Argument *> &ByValArguments,
143*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<ReturnInst *> &Returns,
144*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<Instruction *> &StackRestorePoints);
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker /// \brief Calculate the allocation size of a given alloca. Returns 0 if the
147*9880d681SAndroid Build Coastguard Worker /// size can not be statically determined.
148*9880d681SAndroid Build Coastguard Worker uint64_t getStaticAllocaAllocationSize(const AllocaInst* AI);
149*9880d681SAndroid Build Coastguard Worker
150*9880d681SAndroid Build Coastguard Worker /// \brief Allocate space for all static allocas in \p StaticAllocas,
151*9880d681SAndroid Build Coastguard Worker /// replace allocas with pointers into the unsafe stack and generate code to
152*9880d681SAndroid Build Coastguard Worker /// restore the stack pointer before all return instructions in \p Returns.
153*9880d681SAndroid Build Coastguard Worker ///
154*9880d681SAndroid Build Coastguard Worker /// \returns A pointer to the top of the unsafe stack after all unsafe static
155*9880d681SAndroid Build Coastguard Worker /// allocas are allocated.
156*9880d681SAndroid Build Coastguard Worker Value *moveStaticAllocasToUnsafeStack(IRBuilder<> &IRB, Function &F,
157*9880d681SAndroid Build Coastguard Worker ArrayRef<AllocaInst *> StaticAllocas,
158*9880d681SAndroid Build Coastguard Worker ArrayRef<Argument *> ByValArguments,
159*9880d681SAndroid Build Coastguard Worker ArrayRef<ReturnInst *> Returns,
160*9880d681SAndroid Build Coastguard Worker Instruction *BasePointer,
161*9880d681SAndroid Build Coastguard Worker AllocaInst *StackGuardSlot);
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Worker /// \brief Generate code to restore the stack after all stack restore points
164*9880d681SAndroid Build Coastguard Worker /// in \p StackRestorePoints.
165*9880d681SAndroid Build Coastguard Worker ///
166*9880d681SAndroid Build Coastguard Worker /// \returns A local variable in which to maintain the dynamic top of the
167*9880d681SAndroid Build Coastguard Worker /// unsafe stack if needed.
168*9880d681SAndroid Build Coastguard Worker AllocaInst *
169*9880d681SAndroid Build Coastguard Worker createStackRestorePoints(IRBuilder<> &IRB, Function &F,
170*9880d681SAndroid Build Coastguard Worker ArrayRef<Instruction *> StackRestorePoints,
171*9880d681SAndroid Build Coastguard Worker Value *StaticTop, bool NeedDynamicTop);
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Worker /// \brief Replace all allocas in \p DynamicAllocas with code to allocate
174*9880d681SAndroid Build Coastguard Worker /// space dynamically on the unsafe stack and store the dynamic unsafe stack
175*9880d681SAndroid Build Coastguard Worker /// top to \p DynamicTop if non-null.
176*9880d681SAndroid Build Coastguard Worker void moveDynamicAllocasToUnsafeStack(Function &F, Value *UnsafeStackPtr,
177*9880d681SAndroid Build Coastguard Worker AllocaInst *DynamicTop,
178*9880d681SAndroid Build Coastguard Worker ArrayRef<AllocaInst *> DynamicAllocas);
179*9880d681SAndroid Build Coastguard Worker
180*9880d681SAndroid Build Coastguard Worker bool IsSafeStackAlloca(const Value *AllocaPtr, uint64_t AllocaSize);
181*9880d681SAndroid Build Coastguard Worker
182*9880d681SAndroid Build Coastguard Worker bool IsMemIntrinsicSafe(const MemIntrinsic *MI, const Use &U,
183*9880d681SAndroid Build Coastguard Worker const Value *AllocaPtr, uint64_t AllocaSize);
184*9880d681SAndroid Build Coastguard Worker bool IsAccessSafe(Value *Addr, uint64_t Size, const Value *AllocaPtr,
185*9880d681SAndroid Build Coastguard Worker uint64_t AllocaSize);
186*9880d681SAndroid Build Coastguard Worker
187*9880d681SAndroid Build Coastguard Worker public:
188*9880d681SAndroid Build Coastguard Worker static char ID; // Pass identification, replacement for typeid.
SafeStack(const TargetMachine * TM)189*9880d681SAndroid Build Coastguard Worker SafeStack(const TargetMachine *TM)
190*9880d681SAndroid Build Coastguard Worker : FunctionPass(ID), TM(TM), TL(nullptr), DL(nullptr) {
191*9880d681SAndroid Build Coastguard Worker initializeSafeStackPass(*PassRegistry::getPassRegistry());
192*9880d681SAndroid Build Coastguard Worker }
SafeStack()193*9880d681SAndroid Build Coastguard Worker SafeStack() : SafeStack(nullptr) {}
194*9880d681SAndroid Build Coastguard Worker
getAnalysisUsage(AnalysisUsage & AU) const195*9880d681SAndroid Build Coastguard Worker void getAnalysisUsage(AnalysisUsage &AU) const override {
196*9880d681SAndroid Build Coastguard Worker AU.addRequired<ScalarEvolutionWrapperPass>();
197*9880d681SAndroid Build Coastguard Worker }
198*9880d681SAndroid Build Coastguard Worker
doInitialization(Module & M)199*9880d681SAndroid Build Coastguard Worker bool doInitialization(Module &M) override {
200*9880d681SAndroid Build Coastguard Worker DL = &M.getDataLayout();
201*9880d681SAndroid Build Coastguard Worker
202*9880d681SAndroid Build Coastguard Worker StackPtrTy = Type::getInt8PtrTy(M.getContext());
203*9880d681SAndroid Build Coastguard Worker IntPtrTy = DL->getIntPtrType(M.getContext());
204*9880d681SAndroid Build Coastguard Worker Int32Ty = Type::getInt32Ty(M.getContext());
205*9880d681SAndroid Build Coastguard Worker Int8Ty = Type::getInt8Ty(M.getContext());
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Worker return false;
208*9880d681SAndroid Build Coastguard Worker }
209*9880d681SAndroid Build Coastguard Worker
210*9880d681SAndroid Build Coastguard Worker bool runOnFunction(Function &F) override;
211*9880d681SAndroid Build Coastguard Worker }; // class SafeStack
212*9880d681SAndroid Build Coastguard Worker
getStaticAllocaAllocationSize(const AllocaInst * AI)213*9880d681SAndroid Build Coastguard Worker uint64_t SafeStack::getStaticAllocaAllocationSize(const AllocaInst* AI) {
214*9880d681SAndroid Build Coastguard Worker uint64_t Size = DL->getTypeAllocSize(AI->getAllocatedType());
215*9880d681SAndroid Build Coastguard Worker if (AI->isArrayAllocation()) {
216*9880d681SAndroid Build Coastguard Worker auto C = dyn_cast<ConstantInt>(AI->getArraySize());
217*9880d681SAndroid Build Coastguard Worker if (!C)
218*9880d681SAndroid Build Coastguard Worker return 0;
219*9880d681SAndroid Build Coastguard Worker Size *= C->getZExtValue();
220*9880d681SAndroid Build Coastguard Worker }
221*9880d681SAndroid Build Coastguard Worker return Size;
222*9880d681SAndroid Build Coastguard Worker }
223*9880d681SAndroid Build Coastguard Worker
IsAccessSafe(Value * Addr,uint64_t AccessSize,const Value * AllocaPtr,uint64_t AllocaSize)224*9880d681SAndroid Build Coastguard Worker bool SafeStack::IsAccessSafe(Value *Addr, uint64_t AccessSize,
225*9880d681SAndroid Build Coastguard Worker const Value *AllocaPtr, uint64_t AllocaSize) {
226*9880d681SAndroid Build Coastguard Worker AllocaOffsetRewriter Rewriter(*SE, AllocaPtr);
227*9880d681SAndroid Build Coastguard Worker const SCEV *Expr = Rewriter.visit(SE->getSCEV(Addr));
228*9880d681SAndroid Build Coastguard Worker
229*9880d681SAndroid Build Coastguard Worker uint64_t BitWidth = SE->getTypeSizeInBits(Expr->getType());
230*9880d681SAndroid Build Coastguard Worker ConstantRange AccessStartRange = SE->getUnsignedRange(Expr);
231*9880d681SAndroid Build Coastguard Worker ConstantRange SizeRange =
232*9880d681SAndroid Build Coastguard Worker ConstantRange(APInt(BitWidth, 0), APInt(BitWidth, AccessSize));
233*9880d681SAndroid Build Coastguard Worker ConstantRange AccessRange = AccessStartRange.add(SizeRange);
234*9880d681SAndroid Build Coastguard Worker ConstantRange AllocaRange =
235*9880d681SAndroid Build Coastguard Worker ConstantRange(APInt(BitWidth, 0), APInt(BitWidth, AllocaSize));
236*9880d681SAndroid Build Coastguard Worker bool Safe = AllocaRange.contains(AccessRange);
237*9880d681SAndroid Build Coastguard Worker
238*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "[SafeStack] "
239*9880d681SAndroid Build Coastguard Worker << (isa<AllocaInst>(AllocaPtr) ? "Alloca " : "ByValArgument ")
240*9880d681SAndroid Build Coastguard Worker << *AllocaPtr << "\n"
241*9880d681SAndroid Build Coastguard Worker << " Access " << *Addr << "\n"
242*9880d681SAndroid Build Coastguard Worker << " SCEV " << *Expr
243*9880d681SAndroid Build Coastguard Worker << " U: " << SE->getUnsignedRange(Expr)
244*9880d681SAndroid Build Coastguard Worker << ", S: " << SE->getSignedRange(Expr) << "\n"
245*9880d681SAndroid Build Coastguard Worker << " Range " << AccessRange << "\n"
246*9880d681SAndroid Build Coastguard Worker << " AllocaRange " << AllocaRange << "\n"
247*9880d681SAndroid Build Coastguard Worker << " " << (Safe ? "safe" : "unsafe") << "\n");
248*9880d681SAndroid Build Coastguard Worker
249*9880d681SAndroid Build Coastguard Worker return Safe;
250*9880d681SAndroid Build Coastguard Worker }
251*9880d681SAndroid Build Coastguard Worker
IsMemIntrinsicSafe(const MemIntrinsic * MI,const Use & U,const Value * AllocaPtr,uint64_t AllocaSize)252*9880d681SAndroid Build Coastguard Worker bool SafeStack::IsMemIntrinsicSafe(const MemIntrinsic *MI, const Use &U,
253*9880d681SAndroid Build Coastguard Worker const Value *AllocaPtr,
254*9880d681SAndroid Build Coastguard Worker uint64_t AllocaSize) {
255*9880d681SAndroid Build Coastguard Worker // All MemIntrinsics have destination address in Arg0 and size in Arg2.
256*9880d681SAndroid Build Coastguard Worker if (MI->getRawDest() != U) return true;
257*9880d681SAndroid Build Coastguard Worker const auto *Len = dyn_cast<ConstantInt>(MI->getLength());
258*9880d681SAndroid Build Coastguard Worker // Non-constant size => unsafe. FIXME: try SCEV getRange.
259*9880d681SAndroid Build Coastguard Worker if (!Len) return false;
260*9880d681SAndroid Build Coastguard Worker return IsAccessSafe(U, Len->getZExtValue(), AllocaPtr, AllocaSize);
261*9880d681SAndroid Build Coastguard Worker }
262*9880d681SAndroid Build Coastguard Worker
263*9880d681SAndroid Build Coastguard Worker /// Check whether a given allocation must be put on the safe
264*9880d681SAndroid Build Coastguard Worker /// stack or not. The function analyzes all uses of AI and checks whether it is
265*9880d681SAndroid Build Coastguard Worker /// only accessed in a memory safe way (as decided statically).
IsSafeStackAlloca(const Value * AllocaPtr,uint64_t AllocaSize)266*9880d681SAndroid Build Coastguard Worker bool SafeStack::IsSafeStackAlloca(const Value *AllocaPtr, uint64_t AllocaSize) {
267*9880d681SAndroid Build Coastguard Worker // Go through all uses of this alloca and check whether all accesses to the
268*9880d681SAndroid Build Coastguard Worker // allocated object are statically known to be memory safe and, hence, the
269*9880d681SAndroid Build Coastguard Worker // object can be placed on the safe stack.
270*9880d681SAndroid Build Coastguard Worker SmallPtrSet<const Value *, 16> Visited;
271*9880d681SAndroid Build Coastguard Worker SmallVector<const Value *, 8> WorkList;
272*9880d681SAndroid Build Coastguard Worker WorkList.push_back(AllocaPtr);
273*9880d681SAndroid Build Coastguard Worker
274*9880d681SAndroid Build Coastguard Worker // A DFS search through all uses of the alloca in bitcasts/PHI/GEPs/etc.
275*9880d681SAndroid Build Coastguard Worker while (!WorkList.empty()) {
276*9880d681SAndroid Build Coastguard Worker const Value *V = WorkList.pop_back_val();
277*9880d681SAndroid Build Coastguard Worker for (const Use &UI : V->uses()) {
278*9880d681SAndroid Build Coastguard Worker auto I = cast<const Instruction>(UI.getUser());
279*9880d681SAndroid Build Coastguard Worker assert(V == UI.get());
280*9880d681SAndroid Build Coastguard Worker
281*9880d681SAndroid Build Coastguard Worker switch (I->getOpcode()) {
282*9880d681SAndroid Build Coastguard Worker case Instruction::Load: {
283*9880d681SAndroid Build Coastguard Worker if (!IsAccessSafe(UI, DL->getTypeStoreSize(I->getType()), AllocaPtr,
284*9880d681SAndroid Build Coastguard Worker AllocaSize))
285*9880d681SAndroid Build Coastguard Worker return false;
286*9880d681SAndroid Build Coastguard Worker break;
287*9880d681SAndroid Build Coastguard Worker }
288*9880d681SAndroid Build Coastguard Worker case Instruction::VAArg:
289*9880d681SAndroid Build Coastguard Worker // "va-arg" from a pointer is safe.
290*9880d681SAndroid Build Coastguard Worker break;
291*9880d681SAndroid Build Coastguard Worker case Instruction::Store: {
292*9880d681SAndroid Build Coastguard Worker if (V == I->getOperand(0)) {
293*9880d681SAndroid Build Coastguard Worker // Stored the pointer - conservatively assume it may be unsafe.
294*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "[SafeStack] Unsafe alloca: " << *AllocaPtr
295*9880d681SAndroid Build Coastguard Worker << "\n store of address: " << *I << "\n");
296*9880d681SAndroid Build Coastguard Worker return false;
297*9880d681SAndroid Build Coastguard Worker }
298*9880d681SAndroid Build Coastguard Worker
299*9880d681SAndroid Build Coastguard Worker if (!IsAccessSafe(UI, DL->getTypeStoreSize(I->getOperand(0)->getType()),
300*9880d681SAndroid Build Coastguard Worker AllocaPtr, AllocaSize))
301*9880d681SAndroid Build Coastguard Worker return false;
302*9880d681SAndroid Build Coastguard Worker break;
303*9880d681SAndroid Build Coastguard Worker }
304*9880d681SAndroid Build Coastguard Worker case Instruction::Ret: {
305*9880d681SAndroid Build Coastguard Worker // Information leak.
306*9880d681SAndroid Build Coastguard Worker return false;
307*9880d681SAndroid Build Coastguard Worker }
308*9880d681SAndroid Build Coastguard Worker
309*9880d681SAndroid Build Coastguard Worker case Instruction::Call:
310*9880d681SAndroid Build Coastguard Worker case Instruction::Invoke: {
311*9880d681SAndroid Build Coastguard Worker ImmutableCallSite CS(I);
312*9880d681SAndroid Build Coastguard Worker
313*9880d681SAndroid Build Coastguard Worker if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
314*9880d681SAndroid Build Coastguard Worker if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
315*9880d681SAndroid Build Coastguard Worker II->getIntrinsicID() == Intrinsic::lifetime_end)
316*9880d681SAndroid Build Coastguard Worker continue;
317*9880d681SAndroid Build Coastguard Worker }
318*9880d681SAndroid Build Coastguard Worker
319*9880d681SAndroid Build Coastguard Worker if (const MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I)) {
320*9880d681SAndroid Build Coastguard Worker if (!IsMemIntrinsicSafe(MI, UI, AllocaPtr, AllocaSize)) {
321*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "[SafeStack] Unsafe alloca: " << *AllocaPtr
322*9880d681SAndroid Build Coastguard Worker << "\n unsafe memintrinsic: " << *I
323*9880d681SAndroid Build Coastguard Worker << "\n");
324*9880d681SAndroid Build Coastguard Worker return false;
325*9880d681SAndroid Build Coastguard Worker }
326*9880d681SAndroid Build Coastguard Worker continue;
327*9880d681SAndroid Build Coastguard Worker }
328*9880d681SAndroid Build Coastguard Worker
329*9880d681SAndroid Build Coastguard Worker // LLVM 'nocapture' attribute is only set for arguments whose address
330*9880d681SAndroid Build Coastguard Worker // is not stored, passed around, or used in any other non-trivial way.
331*9880d681SAndroid Build Coastguard Worker // We assume that passing a pointer to an object as a 'nocapture
332*9880d681SAndroid Build Coastguard Worker // readnone' argument is safe.
333*9880d681SAndroid Build Coastguard Worker // FIXME: a more precise solution would require an interprocedural
334*9880d681SAndroid Build Coastguard Worker // analysis here, which would look at all uses of an argument inside
335*9880d681SAndroid Build Coastguard Worker // the function being called.
336*9880d681SAndroid Build Coastguard Worker ImmutableCallSite::arg_iterator B = CS.arg_begin(), E = CS.arg_end();
337*9880d681SAndroid Build Coastguard Worker for (ImmutableCallSite::arg_iterator A = B; A != E; ++A)
338*9880d681SAndroid Build Coastguard Worker if (A->get() == V)
339*9880d681SAndroid Build Coastguard Worker if (!(CS.doesNotCapture(A - B) && (CS.doesNotAccessMemory(A - B) ||
340*9880d681SAndroid Build Coastguard Worker CS.doesNotAccessMemory()))) {
341*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "[SafeStack] Unsafe alloca: " << *AllocaPtr
342*9880d681SAndroid Build Coastguard Worker << "\n unsafe call: " << *I << "\n");
343*9880d681SAndroid Build Coastguard Worker return false;
344*9880d681SAndroid Build Coastguard Worker }
345*9880d681SAndroid Build Coastguard Worker continue;
346*9880d681SAndroid Build Coastguard Worker }
347*9880d681SAndroid Build Coastguard Worker
348*9880d681SAndroid Build Coastguard Worker default:
349*9880d681SAndroid Build Coastguard Worker if (Visited.insert(I).second)
350*9880d681SAndroid Build Coastguard Worker WorkList.push_back(cast<const Instruction>(I));
351*9880d681SAndroid Build Coastguard Worker }
352*9880d681SAndroid Build Coastguard Worker }
353*9880d681SAndroid Build Coastguard Worker }
354*9880d681SAndroid Build Coastguard Worker
355*9880d681SAndroid Build Coastguard Worker // All uses of the alloca are safe, we can place it on the safe stack.
356*9880d681SAndroid Build Coastguard Worker return true;
357*9880d681SAndroid Build Coastguard Worker }
358*9880d681SAndroid Build Coastguard Worker
getOrCreateUnsafeStackPtr(IRBuilder<> & IRB,Function & F)359*9880d681SAndroid Build Coastguard Worker Value *SafeStack::getOrCreateUnsafeStackPtr(IRBuilder<> &IRB, Function &F) {
360*9880d681SAndroid Build Coastguard Worker // Check if there is a target-specific location for the unsafe stack pointer.
361*9880d681SAndroid Build Coastguard Worker if (TL)
362*9880d681SAndroid Build Coastguard Worker if (Value *V = TL->getSafeStackPointerLocation(IRB))
363*9880d681SAndroid Build Coastguard Worker return V;
364*9880d681SAndroid Build Coastguard Worker
365*9880d681SAndroid Build Coastguard Worker // Otherwise, assume the target links with compiler-rt, which provides a
366*9880d681SAndroid Build Coastguard Worker // thread-local variable with a magic name.
367*9880d681SAndroid Build Coastguard Worker Module &M = *F.getParent();
368*9880d681SAndroid Build Coastguard Worker const char *UnsafeStackPtrVar = "__safestack_unsafe_stack_ptr";
369*9880d681SAndroid Build Coastguard Worker auto UnsafeStackPtr =
370*9880d681SAndroid Build Coastguard Worker dyn_cast_or_null<GlobalVariable>(M.getNamedValue(UnsafeStackPtrVar));
371*9880d681SAndroid Build Coastguard Worker
372*9880d681SAndroid Build Coastguard Worker bool UseTLS = USPStorage == ThreadLocalUSP;
373*9880d681SAndroid Build Coastguard Worker
374*9880d681SAndroid Build Coastguard Worker if (!UnsafeStackPtr) {
375*9880d681SAndroid Build Coastguard Worker auto TLSModel = UseTLS ?
376*9880d681SAndroid Build Coastguard Worker GlobalValue::InitialExecTLSModel :
377*9880d681SAndroid Build Coastguard Worker GlobalValue::NotThreadLocal;
378*9880d681SAndroid Build Coastguard Worker // The global variable is not defined yet, define it ourselves.
379*9880d681SAndroid Build Coastguard Worker // We use the initial-exec TLS model because we do not support the
380*9880d681SAndroid Build Coastguard Worker // variable living anywhere other than in the main executable.
381*9880d681SAndroid Build Coastguard Worker UnsafeStackPtr = new GlobalVariable(
382*9880d681SAndroid Build Coastguard Worker M, StackPtrTy, false, GlobalValue::ExternalLinkage, nullptr,
383*9880d681SAndroid Build Coastguard Worker UnsafeStackPtrVar, nullptr, TLSModel);
384*9880d681SAndroid Build Coastguard Worker } else {
385*9880d681SAndroid Build Coastguard Worker // The variable exists, check its type and attributes.
386*9880d681SAndroid Build Coastguard Worker if (UnsafeStackPtr->getValueType() != StackPtrTy)
387*9880d681SAndroid Build Coastguard Worker report_fatal_error(Twine(UnsafeStackPtrVar) + " must have void* type");
388*9880d681SAndroid Build Coastguard Worker if (UseTLS != UnsafeStackPtr->isThreadLocal())
389*9880d681SAndroid Build Coastguard Worker report_fatal_error(Twine(UnsafeStackPtrVar) + " must " +
390*9880d681SAndroid Build Coastguard Worker (UseTLS ? "" : "not ") + "be thread-local");
391*9880d681SAndroid Build Coastguard Worker }
392*9880d681SAndroid Build Coastguard Worker return UnsafeStackPtr;
393*9880d681SAndroid Build Coastguard Worker }
394*9880d681SAndroid Build Coastguard Worker
getStackGuard(IRBuilder<> & IRB,Function & F)395*9880d681SAndroid Build Coastguard Worker Value *SafeStack::getStackGuard(IRBuilder<> &IRB, Function &F) {
396*9880d681SAndroid Build Coastguard Worker Value *StackGuardVar = nullptr;
397*9880d681SAndroid Build Coastguard Worker if (TL)
398*9880d681SAndroid Build Coastguard Worker StackGuardVar = TL->getIRStackGuard(IRB);
399*9880d681SAndroid Build Coastguard Worker if (!StackGuardVar)
400*9880d681SAndroid Build Coastguard Worker StackGuardVar =
401*9880d681SAndroid Build Coastguard Worker F.getParent()->getOrInsertGlobal("__stack_chk_guard", StackPtrTy);
402*9880d681SAndroid Build Coastguard Worker return IRB.CreateLoad(StackGuardVar, "StackGuard");
403*9880d681SAndroid Build Coastguard Worker }
404*9880d681SAndroid Build Coastguard Worker
findInsts(Function & F,SmallVectorImpl<AllocaInst * > & StaticAllocas,SmallVectorImpl<AllocaInst * > & DynamicAllocas,SmallVectorImpl<Argument * > & ByValArguments,SmallVectorImpl<ReturnInst * > & Returns,SmallVectorImpl<Instruction * > & StackRestorePoints)405*9880d681SAndroid Build Coastguard Worker void SafeStack::findInsts(Function &F,
406*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<AllocaInst *> &StaticAllocas,
407*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<AllocaInst *> &DynamicAllocas,
408*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<Argument *> &ByValArguments,
409*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<ReturnInst *> &Returns,
410*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<Instruction *> &StackRestorePoints) {
411*9880d681SAndroid Build Coastguard Worker for (Instruction &I : instructions(&F)) {
412*9880d681SAndroid Build Coastguard Worker if (auto AI = dyn_cast<AllocaInst>(&I)) {
413*9880d681SAndroid Build Coastguard Worker ++NumAllocas;
414*9880d681SAndroid Build Coastguard Worker
415*9880d681SAndroid Build Coastguard Worker uint64_t Size = getStaticAllocaAllocationSize(AI);
416*9880d681SAndroid Build Coastguard Worker if (IsSafeStackAlloca(AI, Size))
417*9880d681SAndroid Build Coastguard Worker continue;
418*9880d681SAndroid Build Coastguard Worker
419*9880d681SAndroid Build Coastguard Worker if (AI->isStaticAlloca()) {
420*9880d681SAndroid Build Coastguard Worker ++NumUnsafeStaticAllocas;
421*9880d681SAndroid Build Coastguard Worker StaticAllocas.push_back(AI);
422*9880d681SAndroid Build Coastguard Worker } else {
423*9880d681SAndroid Build Coastguard Worker ++NumUnsafeDynamicAllocas;
424*9880d681SAndroid Build Coastguard Worker DynamicAllocas.push_back(AI);
425*9880d681SAndroid Build Coastguard Worker }
426*9880d681SAndroid Build Coastguard Worker } else if (auto RI = dyn_cast<ReturnInst>(&I)) {
427*9880d681SAndroid Build Coastguard Worker Returns.push_back(RI);
428*9880d681SAndroid Build Coastguard Worker } else if (auto CI = dyn_cast<CallInst>(&I)) {
429*9880d681SAndroid Build Coastguard Worker // setjmps require stack restore.
430*9880d681SAndroid Build Coastguard Worker if (CI->getCalledFunction() && CI->canReturnTwice())
431*9880d681SAndroid Build Coastguard Worker StackRestorePoints.push_back(CI);
432*9880d681SAndroid Build Coastguard Worker } else if (auto LP = dyn_cast<LandingPadInst>(&I)) {
433*9880d681SAndroid Build Coastguard Worker // Exception landing pads require stack restore.
434*9880d681SAndroid Build Coastguard Worker StackRestorePoints.push_back(LP);
435*9880d681SAndroid Build Coastguard Worker } else if (auto II = dyn_cast<IntrinsicInst>(&I)) {
436*9880d681SAndroid Build Coastguard Worker if (II->getIntrinsicID() == Intrinsic::gcroot)
437*9880d681SAndroid Build Coastguard Worker llvm::report_fatal_error(
438*9880d681SAndroid Build Coastguard Worker "gcroot intrinsic not compatible with safestack attribute");
439*9880d681SAndroid Build Coastguard Worker }
440*9880d681SAndroid Build Coastguard Worker }
441*9880d681SAndroid Build Coastguard Worker for (Argument &Arg : F.args()) {
442*9880d681SAndroid Build Coastguard Worker if (!Arg.hasByValAttr())
443*9880d681SAndroid Build Coastguard Worker continue;
444*9880d681SAndroid Build Coastguard Worker uint64_t Size =
445*9880d681SAndroid Build Coastguard Worker DL->getTypeStoreSize(Arg.getType()->getPointerElementType());
446*9880d681SAndroid Build Coastguard Worker if (IsSafeStackAlloca(&Arg, Size))
447*9880d681SAndroid Build Coastguard Worker continue;
448*9880d681SAndroid Build Coastguard Worker
449*9880d681SAndroid Build Coastguard Worker ++NumUnsafeByValArguments;
450*9880d681SAndroid Build Coastguard Worker ByValArguments.push_back(&Arg);
451*9880d681SAndroid Build Coastguard Worker }
452*9880d681SAndroid Build Coastguard Worker }
453*9880d681SAndroid Build Coastguard Worker
454*9880d681SAndroid Build Coastguard Worker AllocaInst *
createStackRestorePoints(IRBuilder<> & IRB,Function & F,ArrayRef<Instruction * > StackRestorePoints,Value * StaticTop,bool NeedDynamicTop)455*9880d681SAndroid Build Coastguard Worker SafeStack::createStackRestorePoints(IRBuilder<> &IRB, Function &F,
456*9880d681SAndroid Build Coastguard Worker ArrayRef<Instruction *> StackRestorePoints,
457*9880d681SAndroid Build Coastguard Worker Value *StaticTop, bool NeedDynamicTop) {
458*9880d681SAndroid Build Coastguard Worker assert(StaticTop && "The stack top isn't set.");
459*9880d681SAndroid Build Coastguard Worker
460*9880d681SAndroid Build Coastguard Worker if (StackRestorePoints.empty())
461*9880d681SAndroid Build Coastguard Worker return nullptr;
462*9880d681SAndroid Build Coastguard Worker
463*9880d681SAndroid Build Coastguard Worker // We need the current value of the shadow stack pointer to restore
464*9880d681SAndroid Build Coastguard Worker // after longjmp or exception catching.
465*9880d681SAndroid Build Coastguard Worker
466*9880d681SAndroid Build Coastguard Worker // FIXME: On some platforms this could be handled by the longjmp/exception
467*9880d681SAndroid Build Coastguard Worker // runtime itself.
468*9880d681SAndroid Build Coastguard Worker
469*9880d681SAndroid Build Coastguard Worker AllocaInst *DynamicTop = nullptr;
470*9880d681SAndroid Build Coastguard Worker if (NeedDynamicTop) {
471*9880d681SAndroid Build Coastguard Worker // If we also have dynamic alloca's, the stack pointer value changes
472*9880d681SAndroid Build Coastguard Worker // throughout the function. For now we store it in an alloca.
473*9880d681SAndroid Build Coastguard Worker DynamicTop = IRB.CreateAlloca(StackPtrTy, /*ArraySize=*/nullptr,
474*9880d681SAndroid Build Coastguard Worker "unsafe_stack_dynamic_ptr");
475*9880d681SAndroid Build Coastguard Worker IRB.CreateStore(StaticTop, DynamicTop);
476*9880d681SAndroid Build Coastguard Worker }
477*9880d681SAndroid Build Coastguard Worker
478*9880d681SAndroid Build Coastguard Worker // Restore current stack pointer after longjmp/exception catch.
479*9880d681SAndroid Build Coastguard Worker for (Instruction *I : StackRestorePoints) {
480*9880d681SAndroid Build Coastguard Worker ++NumUnsafeStackRestorePoints;
481*9880d681SAndroid Build Coastguard Worker
482*9880d681SAndroid Build Coastguard Worker IRB.SetInsertPoint(I->getNextNode());
483*9880d681SAndroid Build Coastguard Worker Value *CurrentTop = DynamicTop ? IRB.CreateLoad(DynamicTop) : StaticTop;
484*9880d681SAndroid Build Coastguard Worker IRB.CreateStore(CurrentTop, UnsafeStackPtr);
485*9880d681SAndroid Build Coastguard Worker }
486*9880d681SAndroid Build Coastguard Worker
487*9880d681SAndroid Build Coastguard Worker return DynamicTop;
488*9880d681SAndroid Build Coastguard Worker }
489*9880d681SAndroid Build Coastguard Worker
checkStackGuard(IRBuilder<> & IRB,Function & F,ReturnInst & RI,AllocaInst * StackGuardSlot,Value * StackGuard)490*9880d681SAndroid Build Coastguard Worker void SafeStack::checkStackGuard(IRBuilder<> &IRB, Function &F, ReturnInst &RI,
491*9880d681SAndroid Build Coastguard Worker AllocaInst *StackGuardSlot, Value *StackGuard) {
492*9880d681SAndroid Build Coastguard Worker Value *V = IRB.CreateLoad(StackGuardSlot);
493*9880d681SAndroid Build Coastguard Worker Value *Cmp = IRB.CreateICmpNE(StackGuard, V);
494*9880d681SAndroid Build Coastguard Worker
495*9880d681SAndroid Build Coastguard Worker auto SuccessProb = BranchProbabilityInfo::getBranchProbStackProtector(true);
496*9880d681SAndroid Build Coastguard Worker auto FailureProb = BranchProbabilityInfo::getBranchProbStackProtector(false);
497*9880d681SAndroid Build Coastguard Worker MDNode *Weights = MDBuilder(F.getContext())
498*9880d681SAndroid Build Coastguard Worker .createBranchWeights(SuccessProb.getNumerator(),
499*9880d681SAndroid Build Coastguard Worker FailureProb.getNumerator());
500*9880d681SAndroid Build Coastguard Worker Instruction *CheckTerm =
501*9880d681SAndroid Build Coastguard Worker SplitBlockAndInsertIfThen(Cmp, &RI,
502*9880d681SAndroid Build Coastguard Worker /* Unreachable */ true, Weights);
503*9880d681SAndroid Build Coastguard Worker IRBuilder<> IRBFail(CheckTerm);
504*9880d681SAndroid Build Coastguard Worker // FIXME: respect -fsanitize-trap / -ftrap-function here?
505*9880d681SAndroid Build Coastguard Worker Constant *StackChkFail = F.getParent()->getOrInsertFunction(
506*9880d681SAndroid Build Coastguard Worker "__stack_chk_fail", IRB.getVoidTy(), nullptr);
507*9880d681SAndroid Build Coastguard Worker IRBFail.CreateCall(StackChkFail, {});
508*9880d681SAndroid Build Coastguard Worker }
509*9880d681SAndroid Build Coastguard Worker
510*9880d681SAndroid Build Coastguard Worker /// We explicitly compute and set the unsafe stack layout for all unsafe
511*9880d681SAndroid Build Coastguard Worker /// static alloca instructions. We save the unsafe "base pointer" in the
512*9880d681SAndroid Build Coastguard Worker /// prologue into a local variable and restore it in the epilogue.
moveStaticAllocasToUnsafeStack(IRBuilder<> & IRB,Function & F,ArrayRef<AllocaInst * > StaticAllocas,ArrayRef<Argument * > ByValArguments,ArrayRef<ReturnInst * > Returns,Instruction * BasePointer,AllocaInst * StackGuardSlot)513*9880d681SAndroid Build Coastguard Worker Value *SafeStack::moveStaticAllocasToUnsafeStack(
514*9880d681SAndroid Build Coastguard Worker IRBuilder<> &IRB, Function &F, ArrayRef<AllocaInst *> StaticAllocas,
515*9880d681SAndroid Build Coastguard Worker ArrayRef<Argument *> ByValArguments, ArrayRef<ReturnInst *> Returns,
516*9880d681SAndroid Build Coastguard Worker Instruction *BasePointer, AllocaInst *StackGuardSlot) {
517*9880d681SAndroid Build Coastguard Worker if (StaticAllocas.empty() && ByValArguments.empty())
518*9880d681SAndroid Build Coastguard Worker return BasePointer;
519*9880d681SAndroid Build Coastguard Worker
520*9880d681SAndroid Build Coastguard Worker DIBuilder DIB(*F.getParent());
521*9880d681SAndroid Build Coastguard Worker
522*9880d681SAndroid Build Coastguard Worker StackColoring SSC(F, StaticAllocas);
523*9880d681SAndroid Build Coastguard Worker SSC.run();
524*9880d681SAndroid Build Coastguard Worker SSC.removeAllMarkers();
525*9880d681SAndroid Build Coastguard Worker
526*9880d681SAndroid Build Coastguard Worker // Unsafe stack always grows down.
527*9880d681SAndroid Build Coastguard Worker StackLayout SSL(StackAlignment);
528*9880d681SAndroid Build Coastguard Worker if (StackGuardSlot) {
529*9880d681SAndroid Build Coastguard Worker Type *Ty = StackGuardSlot->getAllocatedType();
530*9880d681SAndroid Build Coastguard Worker unsigned Align =
531*9880d681SAndroid Build Coastguard Worker std::max(DL->getPrefTypeAlignment(Ty), StackGuardSlot->getAlignment());
532*9880d681SAndroid Build Coastguard Worker SSL.addObject(StackGuardSlot, getStaticAllocaAllocationSize(StackGuardSlot),
533*9880d681SAndroid Build Coastguard Worker Align, SSC.getFullLiveRange());
534*9880d681SAndroid Build Coastguard Worker }
535*9880d681SAndroid Build Coastguard Worker
536*9880d681SAndroid Build Coastguard Worker for (Argument *Arg : ByValArguments) {
537*9880d681SAndroid Build Coastguard Worker Type *Ty = Arg->getType()->getPointerElementType();
538*9880d681SAndroid Build Coastguard Worker uint64_t Size = DL->getTypeStoreSize(Ty);
539*9880d681SAndroid Build Coastguard Worker if (Size == 0)
540*9880d681SAndroid Build Coastguard Worker Size = 1; // Don't create zero-sized stack objects.
541*9880d681SAndroid Build Coastguard Worker
542*9880d681SAndroid Build Coastguard Worker // Ensure the object is properly aligned.
543*9880d681SAndroid Build Coastguard Worker unsigned Align = std::max((unsigned)DL->getPrefTypeAlignment(Ty),
544*9880d681SAndroid Build Coastguard Worker Arg->getParamAlignment());
545*9880d681SAndroid Build Coastguard Worker SSL.addObject(Arg, Size, Align, SSC.getFullLiveRange());
546*9880d681SAndroid Build Coastguard Worker }
547*9880d681SAndroid Build Coastguard Worker
548*9880d681SAndroid Build Coastguard Worker for (AllocaInst *AI : StaticAllocas) {
549*9880d681SAndroid Build Coastguard Worker Type *Ty = AI->getAllocatedType();
550*9880d681SAndroid Build Coastguard Worker uint64_t Size = getStaticAllocaAllocationSize(AI);
551*9880d681SAndroid Build Coastguard Worker if (Size == 0)
552*9880d681SAndroid Build Coastguard Worker Size = 1; // Don't create zero-sized stack objects.
553*9880d681SAndroid Build Coastguard Worker
554*9880d681SAndroid Build Coastguard Worker // Ensure the object is properly aligned.
555*9880d681SAndroid Build Coastguard Worker unsigned Align =
556*9880d681SAndroid Build Coastguard Worker std::max((unsigned)DL->getPrefTypeAlignment(Ty), AI->getAlignment());
557*9880d681SAndroid Build Coastguard Worker
558*9880d681SAndroid Build Coastguard Worker SSL.addObject(AI, Size, Align, SSC.getLiveRange(AI));
559*9880d681SAndroid Build Coastguard Worker }
560*9880d681SAndroid Build Coastguard Worker
561*9880d681SAndroid Build Coastguard Worker SSL.computeLayout();
562*9880d681SAndroid Build Coastguard Worker unsigned FrameAlignment = SSL.getFrameAlignment();
563*9880d681SAndroid Build Coastguard Worker
564*9880d681SAndroid Build Coastguard Worker // FIXME: tell SSL that we start at a less-then-MaxAlignment aligned location
565*9880d681SAndroid Build Coastguard Worker // (AlignmentSkew).
566*9880d681SAndroid Build Coastguard Worker if (FrameAlignment > StackAlignment) {
567*9880d681SAndroid Build Coastguard Worker // Re-align the base pointer according to the max requested alignment.
568*9880d681SAndroid Build Coastguard Worker assert(isPowerOf2_32(FrameAlignment));
569*9880d681SAndroid Build Coastguard Worker IRB.SetInsertPoint(BasePointer->getNextNode());
570*9880d681SAndroid Build Coastguard Worker BasePointer = cast<Instruction>(IRB.CreateIntToPtr(
571*9880d681SAndroid Build Coastguard Worker IRB.CreateAnd(IRB.CreatePtrToInt(BasePointer, IntPtrTy),
572*9880d681SAndroid Build Coastguard Worker ConstantInt::get(IntPtrTy, ~uint64_t(FrameAlignment - 1))),
573*9880d681SAndroid Build Coastguard Worker StackPtrTy));
574*9880d681SAndroid Build Coastguard Worker }
575*9880d681SAndroid Build Coastguard Worker
576*9880d681SAndroid Build Coastguard Worker IRB.SetInsertPoint(BasePointer->getNextNode());
577*9880d681SAndroid Build Coastguard Worker
578*9880d681SAndroid Build Coastguard Worker if (StackGuardSlot) {
579*9880d681SAndroid Build Coastguard Worker unsigned Offset = SSL.getObjectOffset(StackGuardSlot);
580*9880d681SAndroid Build Coastguard Worker Value *Off = IRB.CreateGEP(BasePointer, // BasePointer is i8*
581*9880d681SAndroid Build Coastguard Worker ConstantInt::get(Int32Ty, -Offset));
582*9880d681SAndroid Build Coastguard Worker Value *NewAI =
583*9880d681SAndroid Build Coastguard Worker IRB.CreateBitCast(Off, StackGuardSlot->getType(), "StackGuardSlot");
584*9880d681SAndroid Build Coastguard Worker
585*9880d681SAndroid Build Coastguard Worker // Replace alloc with the new location.
586*9880d681SAndroid Build Coastguard Worker StackGuardSlot->replaceAllUsesWith(NewAI);
587*9880d681SAndroid Build Coastguard Worker StackGuardSlot->eraseFromParent();
588*9880d681SAndroid Build Coastguard Worker }
589*9880d681SAndroid Build Coastguard Worker
590*9880d681SAndroid Build Coastguard Worker for (Argument *Arg : ByValArguments) {
591*9880d681SAndroid Build Coastguard Worker unsigned Offset = SSL.getObjectOffset(Arg);
592*9880d681SAndroid Build Coastguard Worker Type *Ty = Arg->getType()->getPointerElementType();
593*9880d681SAndroid Build Coastguard Worker
594*9880d681SAndroid Build Coastguard Worker uint64_t Size = DL->getTypeStoreSize(Ty);
595*9880d681SAndroid Build Coastguard Worker if (Size == 0)
596*9880d681SAndroid Build Coastguard Worker Size = 1; // Don't create zero-sized stack objects.
597*9880d681SAndroid Build Coastguard Worker
598*9880d681SAndroid Build Coastguard Worker Value *Off = IRB.CreateGEP(BasePointer, // BasePointer is i8*
599*9880d681SAndroid Build Coastguard Worker ConstantInt::get(Int32Ty, -Offset));
600*9880d681SAndroid Build Coastguard Worker Value *NewArg = IRB.CreateBitCast(Off, Arg->getType(),
601*9880d681SAndroid Build Coastguard Worker Arg->getName() + ".unsafe-byval");
602*9880d681SAndroid Build Coastguard Worker
603*9880d681SAndroid Build Coastguard Worker // Replace alloc with the new location.
604*9880d681SAndroid Build Coastguard Worker replaceDbgDeclare(Arg, BasePointer, BasePointer->getNextNode(), DIB,
605*9880d681SAndroid Build Coastguard Worker /*Deref=*/true, -Offset);
606*9880d681SAndroid Build Coastguard Worker Arg->replaceAllUsesWith(NewArg);
607*9880d681SAndroid Build Coastguard Worker IRB.SetInsertPoint(cast<Instruction>(NewArg)->getNextNode());
608*9880d681SAndroid Build Coastguard Worker IRB.CreateMemCpy(Off, Arg, Size, Arg->getParamAlignment());
609*9880d681SAndroid Build Coastguard Worker }
610*9880d681SAndroid Build Coastguard Worker
611*9880d681SAndroid Build Coastguard Worker // Allocate space for every unsafe static AllocaInst on the unsafe stack.
612*9880d681SAndroid Build Coastguard Worker for (AllocaInst *AI : StaticAllocas) {
613*9880d681SAndroid Build Coastguard Worker IRB.SetInsertPoint(AI);
614*9880d681SAndroid Build Coastguard Worker unsigned Offset = SSL.getObjectOffset(AI);
615*9880d681SAndroid Build Coastguard Worker
616*9880d681SAndroid Build Coastguard Worker uint64_t Size = getStaticAllocaAllocationSize(AI);
617*9880d681SAndroid Build Coastguard Worker if (Size == 0)
618*9880d681SAndroid Build Coastguard Worker Size = 1; // Don't create zero-sized stack objects.
619*9880d681SAndroid Build Coastguard Worker
620*9880d681SAndroid Build Coastguard Worker replaceDbgDeclareForAlloca(AI, BasePointer, DIB, /*Deref=*/true, -Offset);
621*9880d681SAndroid Build Coastguard Worker replaceDbgValueForAlloca(AI, BasePointer, DIB, -Offset);
622*9880d681SAndroid Build Coastguard Worker
623*9880d681SAndroid Build Coastguard Worker // Replace uses of the alloca with the new location.
624*9880d681SAndroid Build Coastguard Worker // Insert address calculation close to each use to work around PR27844.
625*9880d681SAndroid Build Coastguard Worker std::string Name = std::string(AI->getName()) + ".unsafe";
626*9880d681SAndroid Build Coastguard Worker while (!AI->use_empty()) {
627*9880d681SAndroid Build Coastguard Worker Use &U = *AI->use_begin();
628*9880d681SAndroid Build Coastguard Worker Instruction *User = cast<Instruction>(U.getUser());
629*9880d681SAndroid Build Coastguard Worker
630*9880d681SAndroid Build Coastguard Worker Instruction *InsertBefore;
631*9880d681SAndroid Build Coastguard Worker if (auto *PHI = dyn_cast<PHINode>(User))
632*9880d681SAndroid Build Coastguard Worker InsertBefore = PHI->getIncomingBlock(U)->getTerminator();
633*9880d681SAndroid Build Coastguard Worker else
634*9880d681SAndroid Build Coastguard Worker InsertBefore = User;
635*9880d681SAndroid Build Coastguard Worker
636*9880d681SAndroid Build Coastguard Worker IRBuilder<> IRBUser(InsertBefore);
637*9880d681SAndroid Build Coastguard Worker Value *Off = IRBUser.CreateGEP(BasePointer, // BasePointer is i8*
638*9880d681SAndroid Build Coastguard Worker ConstantInt::get(Int32Ty, -Offset));
639*9880d681SAndroid Build Coastguard Worker Value *Replacement = IRBUser.CreateBitCast(Off, AI->getType(), Name);
640*9880d681SAndroid Build Coastguard Worker
641*9880d681SAndroid Build Coastguard Worker if (auto *PHI = dyn_cast<PHINode>(User)) {
642*9880d681SAndroid Build Coastguard Worker // PHI nodes may have multiple incoming edges from the same BB (why??),
643*9880d681SAndroid Build Coastguard Worker // all must be updated at once with the same incoming value.
644*9880d681SAndroid Build Coastguard Worker auto *BB = PHI->getIncomingBlock(U);
645*9880d681SAndroid Build Coastguard Worker for (unsigned I = 0; I < PHI->getNumIncomingValues(); ++I)
646*9880d681SAndroid Build Coastguard Worker if (PHI->getIncomingBlock(I) == BB)
647*9880d681SAndroid Build Coastguard Worker PHI->setIncomingValue(I, Replacement);
648*9880d681SAndroid Build Coastguard Worker } else {
649*9880d681SAndroid Build Coastguard Worker U.set(Replacement);
650*9880d681SAndroid Build Coastguard Worker }
651*9880d681SAndroid Build Coastguard Worker }
652*9880d681SAndroid Build Coastguard Worker
653*9880d681SAndroid Build Coastguard Worker AI->eraseFromParent();
654*9880d681SAndroid Build Coastguard Worker }
655*9880d681SAndroid Build Coastguard Worker
656*9880d681SAndroid Build Coastguard Worker // Re-align BasePointer so that our callees would see it aligned as
657*9880d681SAndroid Build Coastguard Worker // expected.
658*9880d681SAndroid Build Coastguard Worker // FIXME: no need to update BasePointer in leaf functions.
659*9880d681SAndroid Build Coastguard Worker unsigned FrameSize = alignTo(SSL.getFrameSize(), StackAlignment);
660*9880d681SAndroid Build Coastguard Worker
661*9880d681SAndroid Build Coastguard Worker // Update shadow stack pointer in the function epilogue.
662*9880d681SAndroid Build Coastguard Worker IRB.SetInsertPoint(BasePointer->getNextNode());
663*9880d681SAndroid Build Coastguard Worker
664*9880d681SAndroid Build Coastguard Worker Value *StaticTop =
665*9880d681SAndroid Build Coastguard Worker IRB.CreateGEP(BasePointer, ConstantInt::get(Int32Ty, -FrameSize),
666*9880d681SAndroid Build Coastguard Worker "unsafe_stack_static_top");
667*9880d681SAndroid Build Coastguard Worker IRB.CreateStore(StaticTop, UnsafeStackPtr);
668*9880d681SAndroid Build Coastguard Worker return StaticTop;
669*9880d681SAndroid Build Coastguard Worker }
670*9880d681SAndroid Build Coastguard Worker
moveDynamicAllocasToUnsafeStack(Function & F,Value * UnsafeStackPtr,AllocaInst * DynamicTop,ArrayRef<AllocaInst * > DynamicAllocas)671*9880d681SAndroid Build Coastguard Worker void SafeStack::moveDynamicAllocasToUnsafeStack(
672*9880d681SAndroid Build Coastguard Worker Function &F, Value *UnsafeStackPtr, AllocaInst *DynamicTop,
673*9880d681SAndroid Build Coastguard Worker ArrayRef<AllocaInst *> DynamicAllocas) {
674*9880d681SAndroid Build Coastguard Worker DIBuilder DIB(*F.getParent());
675*9880d681SAndroid Build Coastguard Worker
676*9880d681SAndroid Build Coastguard Worker for (AllocaInst *AI : DynamicAllocas) {
677*9880d681SAndroid Build Coastguard Worker IRBuilder<> IRB(AI);
678*9880d681SAndroid Build Coastguard Worker
679*9880d681SAndroid Build Coastguard Worker // Compute the new SP value (after AI).
680*9880d681SAndroid Build Coastguard Worker Value *ArraySize = AI->getArraySize();
681*9880d681SAndroid Build Coastguard Worker if (ArraySize->getType() != IntPtrTy)
682*9880d681SAndroid Build Coastguard Worker ArraySize = IRB.CreateIntCast(ArraySize, IntPtrTy, false);
683*9880d681SAndroid Build Coastguard Worker
684*9880d681SAndroid Build Coastguard Worker Type *Ty = AI->getAllocatedType();
685*9880d681SAndroid Build Coastguard Worker uint64_t TySize = DL->getTypeAllocSize(Ty);
686*9880d681SAndroid Build Coastguard Worker Value *Size = IRB.CreateMul(ArraySize, ConstantInt::get(IntPtrTy, TySize));
687*9880d681SAndroid Build Coastguard Worker
688*9880d681SAndroid Build Coastguard Worker Value *SP = IRB.CreatePtrToInt(IRB.CreateLoad(UnsafeStackPtr), IntPtrTy);
689*9880d681SAndroid Build Coastguard Worker SP = IRB.CreateSub(SP, Size);
690*9880d681SAndroid Build Coastguard Worker
691*9880d681SAndroid Build Coastguard Worker // Align the SP value to satisfy the AllocaInst, type and stack alignments.
692*9880d681SAndroid Build Coastguard Worker unsigned Align = std::max(
693*9880d681SAndroid Build Coastguard Worker std::max((unsigned)DL->getPrefTypeAlignment(Ty), AI->getAlignment()),
694*9880d681SAndroid Build Coastguard Worker (unsigned)StackAlignment);
695*9880d681SAndroid Build Coastguard Worker
696*9880d681SAndroid Build Coastguard Worker assert(isPowerOf2_32(Align));
697*9880d681SAndroid Build Coastguard Worker Value *NewTop = IRB.CreateIntToPtr(
698*9880d681SAndroid Build Coastguard Worker IRB.CreateAnd(SP, ConstantInt::get(IntPtrTy, ~uint64_t(Align - 1))),
699*9880d681SAndroid Build Coastguard Worker StackPtrTy);
700*9880d681SAndroid Build Coastguard Worker
701*9880d681SAndroid Build Coastguard Worker // Save the stack pointer.
702*9880d681SAndroid Build Coastguard Worker IRB.CreateStore(NewTop, UnsafeStackPtr);
703*9880d681SAndroid Build Coastguard Worker if (DynamicTop)
704*9880d681SAndroid Build Coastguard Worker IRB.CreateStore(NewTop, DynamicTop);
705*9880d681SAndroid Build Coastguard Worker
706*9880d681SAndroid Build Coastguard Worker Value *NewAI = IRB.CreatePointerCast(NewTop, AI->getType());
707*9880d681SAndroid Build Coastguard Worker if (AI->hasName() && isa<Instruction>(NewAI))
708*9880d681SAndroid Build Coastguard Worker NewAI->takeName(AI);
709*9880d681SAndroid Build Coastguard Worker
710*9880d681SAndroid Build Coastguard Worker replaceDbgDeclareForAlloca(AI, NewAI, DIB, /*Deref=*/true);
711*9880d681SAndroid Build Coastguard Worker AI->replaceAllUsesWith(NewAI);
712*9880d681SAndroid Build Coastguard Worker AI->eraseFromParent();
713*9880d681SAndroid Build Coastguard Worker }
714*9880d681SAndroid Build Coastguard Worker
715*9880d681SAndroid Build Coastguard Worker if (!DynamicAllocas.empty()) {
716*9880d681SAndroid Build Coastguard Worker // Now go through the instructions again, replacing stacksave/stackrestore.
717*9880d681SAndroid Build Coastguard Worker for (inst_iterator It = inst_begin(&F), Ie = inst_end(&F); It != Ie;) {
718*9880d681SAndroid Build Coastguard Worker Instruction *I = &*(It++);
719*9880d681SAndroid Build Coastguard Worker auto II = dyn_cast<IntrinsicInst>(I);
720*9880d681SAndroid Build Coastguard Worker if (!II)
721*9880d681SAndroid Build Coastguard Worker continue;
722*9880d681SAndroid Build Coastguard Worker
723*9880d681SAndroid Build Coastguard Worker if (II->getIntrinsicID() == Intrinsic::stacksave) {
724*9880d681SAndroid Build Coastguard Worker IRBuilder<> IRB(II);
725*9880d681SAndroid Build Coastguard Worker Instruction *LI = IRB.CreateLoad(UnsafeStackPtr);
726*9880d681SAndroid Build Coastguard Worker LI->takeName(II);
727*9880d681SAndroid Build Coastguard Worker II->replaceAllUsesWith(LI);
728*9880d681SAndroid Build Coastguard Worker II->eraseFromParent();
729*9880d681SAndroid Build Coastguard Worker } else if (II->getIntrinsicID() == Intrinsic::stackrestore) {
730*9880d681SAndroid Build Coastguard Worker IRBuilder<> IRB(II);
731*9880d681SAndroid Build Coastguard Worker Instruction *SI = IRB.CreateStore(II->getArgOperand(0), UnsafeStackPtr);
732*9880d681SAndroid Build Coastguard Worker SI->takeName(II);
733*9880d681SAndroid Build Coastguard Worker assert(II->use_empty());
734*9880d681SAndroid Build Coastguard Worker II->eraseFromParent();
735*9880d681SAndroid Build Coastguard Worker }
736*9880d681SAndroid Build Coastguard Worker }
737*9880d681SAndroid Build Coastguard Worker }
738*9880d681SAndroid Build Coastguard Worker }
739*9880d681SAndroid Build Coastguard Worker
runOnFunction(Function & F)740*9880d681SAndroid Build Coastguard Worker bool SafeStack::runOnFunction(Function &F) {
741*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "[SafeStack] Function: " << F.getName() << "\n");
742*9880d681SAndroid Build Coastguard Worker
743*9880d681SAndroid Build Coastguard Worker if (!F.hasFnAttribute(Attribute::SafeStack)) {
744*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "[SafeStack] safestack is not requested"
745*9880d681SAndroid Build Coastguard Worker " for this function\n");
746*9880d681SAndroid Build Coastguard Worker return false;
747*9880d681SAndroid Build Coastguard Worker }
748*9880d681SAndroid Build Coastguard Worker
749*9880d681SAndroid Build Coastguard Worker if (F.isDeclaration()) {
750*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "[SafeStack] function definition"
751*9880d681SAndroid Build Coastguard Worker " is not available\n");
752*9880d681SAndroid Build Coastguard Worker return false;
753*9880d681SAndroid Build Coastguard Worker }
754*9880d681SAndroid Build Coastguard Worker
755*9880d681SAndroid Build Coastguard Worker TL = TM ? TM->getSubtargetImpl(F)->getTargetLowering() : nullptr;
756*9880d681SAndroid Build Coastguard Worker SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
757*9880d681SAndroid Build Coastguard Worker
758*9880d681SAndroid Build Coastguard Worker ++NumFunctions;
759*9880d681SAndroid Build Coastguard Worker
760*9880d681SAndroid Build Coastguard Worker SmallVector<AllocaInst *, 16> StaticAllocas;
761*9880d681SAndroid Build Coastguard Worker SmallVector<AllocaInst *, 4> DynamicAllocas;
762*9880d681SAndroid Build Coastguard Worker SmallVector<Argument *, 4> ByValArguments;
763*9880d681SAndroid Build Coastguard Worker SmallVector<ReturnInst *, 4> Returns;
764*9880d681SAndroid Build Coastguard Worker
765*9880d681SAndroid Build Coastguard Worker // Collect all points where stack gets unwound and needs to be restored
766*9880d681SAndroid Build Coastguard Worker // This is only necessary because the runtime (setjmp and unwind code) is
767*9880d681SAndroid Build Coastguard Worker // not aware of the unsafe stack and won't unwind/restore it prorerly.
768*9880d681SAndroid Build Coastguard Worker // To work around this problem without changing the runtime, we insert
769*9880d681SAndroid Build Coastguard Worker // instrumentation to restore the unsafe stack pointer when necessary.
770*9880d681SAndroid Build Coastguard Worker SmallVector<Instruction *, 4> StackRestorePoints;
771*9880d681SAndroid Build Coastguard Worker
772*9880d681SAndroid Build Coastguard Worker // Find all static and dynamic alloca instructions that must be moved to the
773*9880d681SAndroid Build Coastguard Worker // unsafe stack, all return instructions and stack restore points.
774*9880d681SAndroid Build Coastguard Worker findInsts(F, StaticAllocas, DynamicAllocas, ByValArguments, Returns,
775*9880d681SAndroid Build Coastguard Worker StackRestorePoints);
776*9880d681SAndroid Build Coastguard Worker
777*9880d681SAndroid Build Coastguard Worker if (StaticAllocas.empty() && DynamicAllocas.empty() &&
778*9880d681SAndroid Build Coastguard Worker ByValArguments.empty() && StackRestorePoints.empty())
779*9880d681SAndroid Build Coastguard Worker return false; // Nothing to do in this function.
780*9880d681SAndroid Build Coastguard Worker
781*9880d681SAndroid Build Coastguard Worker if (!StaticAllocas.empty() || !DynamicAllocas.empty() ||
782*9880d681SAndroid Build Coastguard Worker !ByValArguments.empty())
783*9880d681SAndroid Build Coastguard Worker ++NumUnsafeStackFunctions; // This function has the unsafe stack.
784*9880d681SAndroid Build Coastguard Worker
785*9880d681SAndroid Build Coastguard Worker if (!StackRestorePoints.empty())
786*9880d681SAndroid Build Coastguard Worker ++NumUnsafeStackRestorePointsFunctions;
787*9880d681SAndroid Build Coastguard Worker
788*9880d681SAndroid Build Coastguard Worker IRBuilder<> IRB(&F.front(), F.begin()->getFirstInsertionPt());
789*9880d681SAndroid Build Coastguard Worker UnsafeStackPtr = getOrCreateUnsafeStackPtr(IRB, F);
790*9880d681SAndroid Build Coastguard Worker
791*9880d681SAndroid Build Coastguard Worker // Load the current stack pointer (we'll also use it as a base pointer).
792*9880d681SAndroid Build Coastguard Worker // FIXME: use a dedicated register for it ?
793*9880d681SAndroid Build Coastguard Worker Instruction *BasePointer =
794*9880d681SAndroid Build Coastguard Worker IRB.CreateLoad(UnsafeStackPtr, false, "unsafe_stack_ptr");
795*9880d681SAndroid Build Coastguard Worker assert(BasePointer->getType() == StackPtrTy);
796*9880d681SAndroid Build Coastguard Worker
797*9880d681SAndroid Build Coastguard Worker AllocaInst *StackGuardSlot = nullptr;
798*9880d681SAndroid Build Coastguard Worker // FIXME: implement weaker forms of stack protector.
799*9880d681SAndroid Build Coastguard Worker if (F.hasFnAttribute(Attribute::StackProtect) ||
800*9880d681SAndroid Build Coastguard Worker F.hasFnAttribute(Attribute::StackProtectStrong) ||
801*9880d681SAndroid Build Coastguard Worker F.hasFnAttribute(Attribute::StackProtectReq)) {
802*9880d681SAndroid Build Coastguard Worker Value *StackGuard = getStackGuard(IRB, F);
803*9880d681SAndroid Build Coastguard Worker StackGuardSlot = IRB.CreateAlloca(StackPtrTy, nullptr);
804*9880d681SAndroid Build Coastguard Worker IRB.CreateStore(StackGuard, StackGuardSlot);
805*9880d681SAndroid Build Coastguard Worker
806*9880d681SAndroid Build Coastguard Worker for (ReturnInst *RI : Returns) {
807*9880d681SAndroid Build Coastguard Worker IRBuilder<> IRBRet(RI);
808*9880d681SAndroid Build Coastguard Worker checkStackGuard(IRBRet, F, *RI, StackGuardSlot, StackGuard);
809*9880d681SAndroid Build Coastguard Worker }
810*9880d681SAndroid Build Coastguard Worker }
811*9880d681SAndroid Build Coastguard Worker
812*9880d681SAndroid Build Coastguard Worker // The top of the unsafe stack after all unsafe static allocas are
813*9880d681SAndroid Build Coastguard Worker // allocated.
814*9880d681SAndroid Build Coastguard Worker Value *StaticTop =
815*9880d681SAndroid Build Coastguard Worker moveStaticAllocasToUnsafeStack(IRB, F, StaticAllocas, ByValArguments,
816*9880d681SAndroid Build Coastguard Worker Returns, BasePointer, StackGuardSlot);
817*9880d681SAndroid Build Coastguard Worker
818*9880d681SAndroid Build Coastguard Worker // Safe stack object that stores the current unsafe stack top. It is updated
819*9880d681SAndroid Build Coastguard Worker // as unsafe dynamic (non-constant-sized) allocas are allocated and freed.
820*9880d681SAndroid Build Coastguard Worker // This is only needed if we need to restore stack pointer after longjmp
821*9880d681SAndroid Build Coastguard Worker // or exceptions, and we have dynamic allocations.
822*9880d681SAndroid Build Coastguard Worker // FIXME: a better alternative might be to store the unsafe stack pointer
823*9880d681SAndroid Build Coastguard Worker // before setjmp / invoke instructions.
824*9880d681SAndroid Build Coastguard Worker AllocaInst *DynamicTop = createStackRestorePoints(
825*9880d681SAndroid Build Coastguard Worker IRB, F, StackRestorePoints, StaticTop, !DynamicAllocas.empty());
826*9880d681SAndroid Build Coastguard Worker
827*9880d681SAndroid Build Coastguard Worker // Handle dynamic allocas.
828*9880d681SAndroid Build Coastguard Worker moveDynamicAllocasToUnsafeStack(F, UnsafeStackPtr, DynamicTop,
829*9880d681SAndroid Build Coastguard Worker DynamicAllocas);
830*9880d681SAndroid Build Coastguard Worker
831*9880d681SAndroid Build Coastguard Worker // Restore the unsafe stack pointer before each return.
832*9880d681SAndroid Build Coastguard Worker for (ReturnInst *RI : Returns) {
833*9880d681SAndroid Build Coastguard Worker IRB.SetInsertPoint(RI);
834*9880d681SAndroid Build Coastguard Worker IRB.CreateStore(BasePointer, UnsafeStackPtr);
835*9880d681SAndroid Build Coastguard Worker }
836*9880d681SAndroid Build Coastguard Worker
837*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "[SafeStack] safestack applied\n");
838*9880d681SAndroid Build Coastguard Worker return true;
839*9880d681SAndroid Build Coastguard Worker }
840*9880d681SAndroid Build Coastguard Worker
841*9880d681SAndroid Build Coastguard Worker } // anonymous namespace
842*9880d681SAndroid Build Coastguard Worker
843*9880d681SAndroid Build Coastguard Worker char SafeStack::ID = 0;
844*9880d681SAndroid Build Coastguard Worker INITIALIZE_TM_PASS_BEGIN(SafeStack, "safe-stack",
845*9880d681SAndroid Build Coastguard Worker "Safe Stack instrumentation pass", false, false)
846*9880d681SAndroid Build Coastguard Worker INITIALIZE_TM_PASS_END(SafeStack, "safe-stack",
847*9880d681SAndroid Build Coastguard Worker "Safe Stack instrumentation pass", false, false)
848*9880d681SAndroid Build Coastguard Worker
createSafeStackPass(const llvm::TargetMachine * TM)849*9880d681SAndroid Build Coastguard Worker FunctionPass *llvm::createSafeStackPass(const llvm::TargetMachine *TM) {
850*9880d681SAndroid Build Coastguard Worker return new SafeStack(TM);
851*9880d681SAndroid Build Coastguard Worker }
852