xref: /aosp_15_r20/external/llvm/lib/CodeGen/SafeStack.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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