106f32e7eSjoerg //===- SafeStack.cpp - Safe Stack Insertion -------------------------------===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg // This pass splits the stack into the safe stack (kept as-is for LLVM backend)
1006f32e7eSjoerg // and the unsafe stack (explicitly allocated and managed through the runtime
1106f32e7eSjoerg // support library).
1206f32e7eSjoerg //
1306f32e7eSjoerg // http://clang.llvm.org/docs/SafeStack.html
1406f32e7eSjoerg //
1506f32e7eSjoerg //===----------------------------------------------------------------------===//
1606f32e7eSjoerg 
1706f32e7eSjoerg #include "SafeStackLayout.h"
1806f32e7eSjoerg #include "llvm/ADT/APInt.h"
1906f32e7eSjoerg #include "llvm/ADT/ArrayRef.h"
20*da58b97aSjoerg #include "llvm/ADT/BitVector.h"
2106f32e7eSjoerg #include "llvm/ADT/SmallPtrSet.h"
2206f32e7eSjoerg #include "llvm/ADT/SmallVector.h"
2306f32e7eSjoerg #include "llvm/ADT/Statistic.h"
2406f32e7eSjoerg #include "llvm/Analysis/AssumptionCache.h"
2506f32e7eSjoerg #include "llvm/Analysis/BranchProbabilityInfo.h"
26*da58b97aSjoerg #include "llvm/Analysis/DomTreeUpdater.h"
2706f32e7eSjoerg #include "llvm/Analysis/InlineCost.h"
2806f32e7eSjoerg #include "llvm/Analysis/LoopInfo.h"
2906f32e7eSjoerg #include "llvm/Analysis/ScalarEvolution.h"
3006f32e7eSjoerg #include "llvm/Analysis/ScalarEvolutionExpressions.h"
31*da58b97aSjoerg #include "llvm/Analysis/StackLifetime.h"
3206f32e7eSjoerg #include "llvm/Analysis/TargetLibraryInfo.h"
3306f32e7eSjoerg #include "llvm/CodeGen/TargetLowering.h"
3406f32e7eSjoerg #include "llvm/CodeGen/TargetPassConfig.h"
3506f32e7eSjoerg #include "llvm/CodeGen/TargetSubtargetInfo.h"
3606f32e7eSjoerg #include "llvm/IR/Argument.h"
3706f32e7eSjoerg #include "llvm/IR/Attributes.h"
3806f32e7eSjoerg #include "llvm/IR/ConstantRange.h"
3906f32e7eSjoerg #include "llvm/IR/Constants.h"
4006f32e7eSjoerg #include "llvm/IR/DIBuilder.h"
4106f32e7eSjoerg #include "llvm/IR/DataLayout.h"
4206f32e7eSjoerg #include "llvm/IR/DerivedTypes.h"
4306f32e7eSjoerg #include "llvm/IR/Dominators.h"
4406f32e7eSjoerg #include "llvm/IR/Function.h"
4506f32e7eSjoerg #include "llvm/IR/IRBuilder.h"
4606f32e7eSjoerg #include "llvm/IR/InstIterator.h"
4706f32e7eSjoerg #include "llvm/IR/Instruction.h"
4806f32e7eSjoerg #include "llvm/IR/Instructions.h"
4906f32e7eSjoerg #include "llvm/IR/IntrinsicInst.h"
5006f32e7eSjoerg #include "llvm/IR/Intrinsics.h"
5106f32e7eSjoerg #include "llvm/IR/MDBuilder.h"
5206f32e7eSjoerg #include "llvm/IR/Module.h"
5306f32e7eSjoerg #include "llvm/IR/Type.h"
5406f32e7eSjoerg #include "llvm/IR/Use.h"
5506f32e7eSjoerg #include "llvm/IR/User.h"
5606f32e7eSjoerg #include "llvm/IR/Value.h"
57*da58b97aSjoerg #include "llvm/InitializePasses.h"
5806f32e7eSjoerg #include "llvm/Pass.h"
5906f32e7eSjoerg #include "llvm/Support/Casting.h"
6006f32e7eSjoerg #include "llvm/Support/Debug.h"
6106f32e7eSjoerg #include "llvm/Support/ErrorHandling.h"
6206f32e7eSjoerg #include "llvm/Support/MathExtras.h"
6306f32e7eSjoerg #include "llvm/Support/raw_ostream.h"
6406f32e7eSjoerg #include "llvm/Target/TargetMachine.h"
6506f32e7eSjoerg #include "llvm/Transforms/Utils/BasicBlockUtils.h"
6606f32e7eSjoerg #include "llvm/Transforms/Utils/Cloning.h"
67*da58b97aSjoerg #include "llvm/Transforms/Utils/Local.h"
6806f32e7eSjoerg #include <algorithm>
6906f32e7eSjoerg #include <cassert>
7006f32e7eSjoerg #include <cstdint>
7106f32e7eSjoerg #include <string>
7206f32e7eSjoerg #include <utility>
7306f32e7eSjoerg 
7406f32e7eSjoerg using namespace llvm;
7506f32e7eSjoerg using namespace llvm::safestack;
7606f32e7eSjoerg 
7706f32e7eSjoerg #define DEBUG_TYPE "safe-stack"
7806f32e7eSjoerg 
7906f32e7eSjoerg namespace llvm {
8006f32e7eSjoerg 
8106f32e7eSjoerg STATISTIC(NumFunctions, "Total number of functions");
8206f32e7eSjoerg STATISTIC(NumUnsafeStackFunctions, "Number of functions with unsafe stack");
8306f32e7eSjoerg STATISTIC(NumUnsafeStackRestorePointsFunctions,
8406f32e7eSjoerg           "Number of functions that use setjmp or exceptions");
8506f32e7eSjoerg 
8606f32e7eSjoerg STATISTIC(NumAllocas, "Total number of allocas");
8706f32e7eSjoerg STATISTIC(NumUnsafeStaticAllocas, "Number of unsafe static allocas");
8806f32e7eSjoerg STATISTIC(NumUnsafeDynamicAllocas, "Number of unsafe dynamic allocas");
8906f32e7eSjoerg STATISTIC(NumUnsafeByValArguments, "Number of unsafe byval arguments");
9006f32e7eSjoerg STATISTIC(NumUnsafeStackRestorePoints, "Number of setjmps and landingpads");
9106f32e7eSjoerg 
9206f32e7eSjoerg } // namespace llvm
9306f32e7eSjoerg 
9406f32e7eSjoerg /// Use __safestack_pointer_address even if the platform has a faster way of
9506f32e7eSjoerg /// access safe stack pointer.
9606f32e7eSjoerg static cl::opt<bool>
9706f32e7eSjoerg     SafeStackUsePointerAddress("safestack-use-pointer-address",
9806f32e7eSjoerg                                   cl::init(false), cl::Hidden);
9906f32e7eSjoerg 
100*da58b97aSjoerg // Disabled by default due to PR32143.
101*da58b97aSjoerg static cl::opt<bool> ClColoring("safe-stack-coloring",
102*da58b97aSjoerg                                 cl::desc("enable safe stack coloring"),
103*da58b97aSjoerg                                 cl::Hidden, cl::init(false));
10406f32e7eSjoerg 
10506f32e7eSjoerg namespace {
10606f32e7eSjoerg 
10706f32e7eSjoerg /// Rewrite an SCEV expression for a memory access address to an expression that
10806f32e7eSjoerg /// represents offset from the given alloca.
10906f32e7eSjoerg ///
11006f32e7eSjoerg /// The implementation simply replaces all mentions of the alloca with zero.
11106f32e7eSjoerg class AllocaOffsetRewriter : public SCEVRewriteVisitor<AllocaOffsetRewriter> {
11206f32e7eSjoerg   const Value *AllocaPtr;
11306f32e7eSjoerg 
11406f32e7eSjoerg public:
AllocaOffsetRewriter(ScalarEvolution & SE,const Value * AllocaPtr)11506f32e7eSjoerg   AllocaOffsetRewriter(ScalarEvolution &SE, const Value *AllocaPtr)
11606f32e7eSjoerg       : SCEVRewriteVisitor(SE), AllocaPtr(AllocaPtr) {}
11706f32e7eSjoerg 
visitUnknown(const SCEVUnknown * Expr)11806f32e7eSjoerg   const SCEV *visitUnknown(const SCEVUnknown *Expr) {
11906f32e7eSjoerg     if (Expr->getValue() == AllocaPtr)
12006f32e7eSjoerg       return SE.getZero(Expr->getType());
12106f32e7eSjoerg     return Expr;
12206f32e7eSjoerg   }
12306f32e7eSjoerg };
12406f32e7eSjoerg 
12506f32e7eSjoerg /// The SafeStack pass splits the stack of each function into the safe
12606f32e7eSjoerg /// stack, which is only accessed through memory safe dereferences (as
12706f32e7eSjoerg /// determined statically), and the unsafe stack, which contains all
12806f32e7eSjoerg /// local variables that are accessed in ways that we can't prove to
12906f32e7eSjoerg /// be safe.
13006f32e7eSjoerg class SafeStack {
13106f32e7eSjoerg   Function &F;
13206f32e7eSjoerg   const TargetLoweringBase &TL;
13306f32e7eSjoerg   const DataLayout &DL;
134*da58b97aSjoerg   DomTreeUpdater *DTU;
13506f32e7eSjoerg   ScalarEvolution &SE;
13606f32e7eSjoerg 
13706f32e7eSjoerg   Type *StackPtrTy;
13806f32e7eSjoerg   Type *IntPtrTy;
13906f32e7eSjoerg   Type *Int32Ty;
14006f32e7eSjoerg   Type *Int8Ty;
14106f32e7eSjoerg 
14206f32e7eSjoerg   Value *UnsafeStackPtr = nullptr;
14306f32e7eSjoerg 
14406f32e7eSjoerg   /// Unsafe stack alignment. Each stack frame must ensure that the stack is
14506f32e7eSjoerg   /// aligned to this value. We need to re-align the unsafe stack if the
14606f32e7eSjoerg   /// alignment of any object on the stack exceeds this value.
14706f32e7eSjoerg   ///
14806f32e7eSjoerg   /// 16 seems like a reasonable upper bound on the alignment of objects that we
14906f32e7eSjoerg   /// might expect to appear on the stack on most common targets.
15006f32e7eSjoerg   enum { StackAlignment = 16 };
15106f32e7eSjoerg 
15206f32e7eSjoerg   /// Return the value of the stack canary.
15306f32e7eSjoerg   Value *getStackGuard(IRBuilder<> &IRB, Function &F);
15406f32e7eSjoerg 
15506f32e7eSjoerg   /// Load stack guard from the frame and check if it has changed.
156*da58b97aSjoerg   void checkStackGuard(IRBuilder<> &IRB, Function &F, Instruction &RI,
15706f32e7eSjoerg                        AllocaInst *StackGuardSlot, Value *StackGuard);
15806f32e7eSjoerg 
15906f32e7eSjoerg   /// Find all static allocas, dynamic allocas, return instructions and
16006f32e7eSjoerg   /// stack restore points (exception unwind blocks and setjmp calls) in the
16106f32e7eSjoerg   /// given function and append them to the respective vectors.
16206f32e7eSjoerg   void findInsts(Function &F, SmallVectorImpl<AllocaInst *> &StaticAllocas,
16306f32e7eSjoerg                  SmallVectorImpl<AllocaInst *> &DynamicAllocas,
16406f32e7eSjoerg                  SmallVectorImpl<Argument *> &ByValArguments,
165*da58b97aSjoerg                  SmallVectorImpl<Instruction *> &Returns,
16606f32e7eSjoerg                  SmallVectorImpl<Instruction *> &StackRestorePoints);
16706f32e7eSjoerg 
16806f32e7eSjoerg   /// Calculate the allocation size of a given alloca. Returns 0 if the
16906f32e7eSjoerg   /// size can not be statically determined.
17006f32e7eSjoerg   uint64_t getStaticAllocaAllocationSize(const AllocaInst* AI);
17106f32e7eSjoerg 
17206f32e7eSjoerg   /// Allocate space for all static allocas in \p StaticAllocas,
173*da58b97aSjoerg   /// replace allocas with pointers into the unsafe stack.
17406f32e7eSjoerg   ///
17506f32e7eSjoerg   /// \returns A pointer to the top of the unsafe stack after all unsafe static
17606f32e7eSjoerg   /// allocas are allocated.
17706f32e7eSjoerg   Value *moveStaticAllocasToUnsafeStack(IRBuilder<> &IRB, Function &F,
17806f32e7eSjoerg                                         ArrayRef<AllocaInst *> StaticAllocas,
17906f32e7eSjoerg                                         ArrayRef<Argument *> ByValArguments,
18006f32e7eSjoerg                                         Instruction *BasePointer,
18106f32e7eSjoerg                                         AllocaInst *StackGuardSlot);
18206f32e7eSjoerg 
18306f32e7eSjoerg   /// Generate code to restore the stack after all stack restore points
18406f32e7eSjoerg   /// in \p StackRestorePoints.
18506f32e7eSjoerg   ///
18606f32e7eSjoerg   /// \returns A local variable in which to maintain the dynamic top of the
18706f32e7eSjoerg   /// unsafe stack if needed.
18806f32e7eSjoerg   AllocaInst *
18906f32e7eSjoerg   createStackRestorePoints(IRBuilder<> &IRB, Function &F,
19006f32e7eSjoerg                            ArrayRef<Instruction *> StackRestorePoints,
19106f32e7eSjoerg                            Value *StaticTop, bool NeedDynamicTop);
19206f32e7eSjoerg 
19306f32e7eSjoerg   /// Replace all allocas in \p DynamicAllocas with code to allocate
19406f32e7eSjoerg   /// space dynamically on the unsafe stack and store the dynamic unsafe stack
19506f32e7eSjoerg   /// top to \p DynamicTop if non-null.
19606f32e7eSjoerg   void moveDynamicAllocasToUnsafeStack(Function &F, Value *UnsafeStackPtr,
19706f32e7eSjoerg                                        AllocaInst *DynamicTop,
19806f32e7eSjoerg                                        ArrayRef<AllocaInst *> DynamicAllocas);
19906f32e7eSjoerg 
20006f32e7eSjoerg   bool IsSafeStackAlloca(const Value *AllocaPtr, uint64_t AllocaSize);
20106f32e7eSjoerg 
20206f32e7eSjoerg   bool IsMemIntrinsicSafe(const MemIntrinsic *MI, const Use &U,
20306f32e7eSjoerg                           const Value *AllocaPtr, uint64_t AllocaSize);
20406f32e7eSjoerg   bool IsAccessSafe(Value *Addr, uint64_t Size, const Value *AllocaPtr,
20506f32e7eSjoerg                     uint64_t AllocaSize);
20606f32e7eSjoerg 
207*da58b97aSjoerg   bool ShouldInlinePointerAddress(CallInst &CI);
20806f32e7eSjoerg   void TryInlinePointerAddress();
20906f32e7eSjoerg 
21006f32e7eSjoerg public:
SafeStack(Function & F,const TargetLoweringBase & TL,const DataLayout & DL,DomTreeUpdater * DTU,ScalarEvolution & SE)21106f32e7eSjoerg   SafeStack(Function &F, const TargetLoweringBase &TL, const DataLayout &DL,
212*da58b97aSjoerg             DomTreeUpdater *DTU, ScalarEvolution &SE)
213*da58b97aSjoerg       : F(F), TL(TL), DL(DL), DTU(DTU), SE(SE),
21406f32e7eSjoerg         StackPtrTy(Type::getInt8PtrTy(F.getContext())),
21506f32e7eSjoerg         IntPtrTy(DL.getIntPtrType(F.getContext())),
21606f32e7eSjoerg         Int32Ty(Type::getInt32Ty(F.getContext())),
21706f32e7eSjoerg         Int8Ty(Type::getInt8Ty(F.getContext())) {}
21806f32e7eSjoerg 
21906f32e7eSjoerg   // Run the transformation on the associated function.
22006f32e7eSjoerg   // Returns whether the function was changed.
22106f32e7eSjoerg   bool run();
22206f32e7eSjoerg };
22306f32e7eSjoerg 
getStaticAllocaAllocationSize(const AllocaInst * AI)22406f32e7eSjoerg uint64_t SafeStack::getStaticAllocaAllocationSize(const AllocaInst* AI) {
22506f32e7eSjoerg   uint64_t Size = DL.getTypeAllocSize(AI->getAllocatedType());
22606f32e7eSjoerg   if (AI->isArrayAllocation()) {
22706f32e7eSjoerg     auto C = dyn_cast<ConstantInt>(AI->getArraySize());
22806f32e7eSjoerg     if (!C)
22906f32e7eSjoerg       return 0;
23006f32e7eSjoerg     Size *= C->getZExtValue();
23106f32e7eSjoerg   }
23206f32e7eSjoerg   return Size;
23306f32e7eSjoerg }
23406f32e7eSjoerg 
IsAccessSafe(Value * Addr,uint64_t AccessSize,const Value * AllocaPtr,uint64_t AllocaSize)23506f32e7eSjoerg bool SafeStack::IsAccessSafe(Value *Addr, uint64_t AccessSize,
23606f32e7eSjoerg                              const Value *AllocaPtr, uint64_t AllocaSize) {
23706f32e7eSjoerg   AllocaOffsetRewriter Rewriter(SE, AllocaPtr);
23806f32e7eSjoerg   const SCEV *Expr = Rewriter.visit(SE.getSCEV(Addr));
23906f32e7eSjoerg 
24006f32e7eSjoerg   uint64_t BitWidth = SE.getTypeSizeInBits(Expr->getType());
24106f32e7eSjoerg   ConstantRange AccessStartRange = SE.getUnsignedRange(Expr);
24206f32e7eSjoerg   ConstantRange SizeRange =
24306f32e7eSjoerg       ConstantRange(APInt(BitWidth, 0), APInt(BitWidth, AccessSize));
24406f32e7eSjoerg   ConstantRange AccessRange = AccessStartRange.add(SizeRange);
24506f32e7eSjoerg   ConstantRange AllocaRange =
24606f32e7eSjoerg       ConstantRange(APInt(BitWidth, 0), APInt(BitWidth, AllocaSize));
24706f32e7eSjoerg   bool Safe = AllocaRange.contains(AccessRange);
24806f32e7eSjoerg 
24906f32e7eSjoerg   LLVM_DEBUG(
25006f32e7eSjoerg       dbgs() << "[SafeStack] "
25106f32e7eSjoerg              << (isa<AllocaInst>(AllocaPtr) ? "Alloca " : "ByValArgument ")
25206f32e7eSjoerg              << *AllocaPtr << "\n"
25306f32e7eSjoerg              << "            Access " << *Addr << "\n"
25406f32e7eSjoerg              << "            SCEV " << *Expr
25506f32e7eSjoerg              << " U: " << SE.getUnsignedRange(Expr)
25606f32e7eSjoerg              << ", S: " << SE.getSignedRange(Expr) << "\n"
25706f32e7eSjoerg              << "            Range " << AccessRange << "\n"
25806f32e7eSjoerg              << "            AllocaRange " << AllocaRange << "\n"
25906f32e7eSjoerg              << "            " << (Safe ? "safe" : "unsafe") << "\n");
26006f32e7eSjoerg 
26106f32e7eSjoerg   return Safe;
26206f32e7eSjoerg }
26306f32e7eSjoerg 
IsMemIntrinsicSafe(const MemIntrinsic * MI,const Use & U,const Value * AllocaPtr,uint64_t AllocaSize)26406f32e7eSjoerg bool SafeStack::IsMemIntrinsicSafe(const MemIntrinsic *MI, const Use &U,
26506f32e7eSjoerg                                    const Value *AllocaPtr,
26606f32e7eSjoerg                                    uint64_t AllocaSize) {
26706f32e7eSjoerg   if (auto MTI = dyn_cast<MemTransferInst>(MI)) {
26806f32e7eSjoerg     if (MTI->getRawSource() != U && MTI->getRawDest() != U)
26906f32e7eSjoerg       return true;
27006f32e7eSjoerg   } else {
27106f32e7eSjoerg     if (MI->getRawDest() != U)
27206f32e7eSjoerg       return true;
27306f32e7eSjoerg   }
27406f32e7eSjoerg 
27506f32e7eSjoerg   const auto *Len = dyn_cast<ConstantInt>(MI->getLength());
27606f32e7eSjoerg   // Non-constant size => unsafe. FIXME: try SCEV getRange.
27706f32e7eSjoerg   if (!Len) return false;
27806f32e7eSjoerg   return IsAccessSafe(U, Len->getZExtValue(), AllocaPtr, AllocaSize);
27906f32e7eSjoerg }
28006f32e7eSjoerg 
28106f32e7eSjoerg /// Check whether a given allocation must be put on the safe
28206f32e7eSjoerg /// stack or not. The function analyzes all uses of AI and checks whether it is
28306f32e7eSjoerg /// only accessed in a memory safe way (as decided statically).
IsSafeStackAlloca(const Value * AllocaPtr,uint64_t AllocaSize)28406f32e7eSjoerg bool SafeStack::IsSafeStackAlloca(const Value *AllocaPtr, uint64_t AllocaSize) {
28506f32e7eSjoerg   // Go through all uses of this alloca and check whether all accesses to the
28606f32e7eSjoerg   // allocated object are statically known to be memory safe and, hence, the
28706f32e7eSjoerg   // object can be placed on the safe stack.
28806f32e7eSjoerg   SmallPtrSet<const Value *, 16> Visited;
28906f32e7eSjoerg   SmallVector<const Value *, 8> WorkList;
29006f32e7eSjoerg   WorkList.push_back(AllocaPtr);
29106f32e7eSjoerg 
29206f32e7eSjoerg   // A DFS search through all uses of the alloca in bitcasts/PHI/GEPs/etc.
29306f32e7eSjoerg   while (!WorkList.empty()) {
29406f32e7eSjoerg     const Value *V = WorkList.pop_back_val();
29506f32e7eSjoerg     for (const Use &UI : V->uses()) {
29606f32e7eSjoerg       auto I = cast<const Instruction>(UI.getUser());
29706f32e7eSjoerg       assert(V == UI.get());
29806f32e7eSjoerg 
29906f32e7eSjoerg       switch (I->getOpcode()) {
30006f32e7eSjoerg       case Instruction::Load:
30106f32e7eSjoerg         if (!IsAccessSafe(UI, DL.getTypeStoreSize(I->getType()), AllocaPtr,
30206f32e7eSjoerg                           AllocaSize))
30306f32e7eSjoerg           return false;
30406f32e7eSjoerg         break;
30506f32e7eSjoerg 
30606f32e7eSjoerg       case Instruction::VAArg:
30706f32e7eSjoerg         // "va-arg" from a pointer is safe.
30806f32e7eSjoerg         break;
30906f32e7eSjoerg       case Instruction::Store:
31006f32e7eSjoerg         if (V == I->getOperand(0)) {
31106f32e7eSjoerg           // Stored the pointer - conservatively assume it may be unsafe.
31206f32e7eSjoerg           LLVM_DEBUG(dbgs()
31306f32e7eSjoerg                      << "[SafeStack] Unsafe alloca: " << *AllocaPtr
31406f32e7eSjoerg                      << "\n            store of address: " << *I << "\n");
31506f32e7eSjoerg           return false;
31606f32e7eSjoerg         }
31706f32e7eSjoerg 
31806f32e7eSjoerg         if (!IsAccessSafe(UI, DL.getTypeStoreSize(I->getOperand(0)->getType()),
31906f32e7eSjoerg                           AllocaPtr, AllocaSize))
32006f32e7eSjoerg           return false;
32106f32e7eSjoerg         break;
32206f32e7eSjoerg 
32306f32e7eSjoerg       case Instruction::Ret:
32406f32e7eSjoerg         // Information leak.
32506f32e7eSjoerg         return false;
32606f32e7eSjoerg 
32706f32e7eSjoerg       case Instruction::Call:
32806f32e7eSjoerg       case Instruction::Invoke: {
329*da58b97aSjoerg         const CallBase &CS = *cast<CallBase>(I);
33006f32e7eSjoerg 
33106f32e7eSjoerg         if (I->isLifetimeStartOrEnd())
33206f32e7eSjoerg           continue;
33306f32e7eSjoerg 
33406f32e7eSjoerg         if (const MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I)) {
33506f32e7eSjoerg           if (!IsMemIntrinsicSafe(MI, UI, AllocaPtr, AllocaSize)) {
33606f32e7eSjoerg             LLVM_DEBUG(dbgs()
33706f32e7eSjoerg                        << "[SafeStack] Unsafe alloca: " << *AllocaPtr
33806f32e7eSjoerg                        << "\n            unsafe memintrinsic: " << *I << "\n");
33906f32e7eSjoerg             return false;
34006f32e7eSjoerg           }
34106f32e7eSjoerg           continue;
34206f32e7eSjoerg         }
34306f32e7eSjoerg 
34406f32e7eSjoerg         // LLVM 'nocapture' attribute is only set for arguments whose address
34506f32e7eSjoerg         // is not stored, passed around, or used in any other non-trivial way.
34606f32e7eSjoerg         // We assume that passing a pointer to an object as a 'nocapture
34706f32e7eSjoerg         // readnone' argument is safe.
34806f32e7eSjoerg         // FIXME: a more precise solution would require an interprocedural
34906f32e7eSjoerg         // analysis here, which would look at all uses of an argument inside
35006f32e7eSjoerg         // the function being called.
351*da58b97aSjoerg         auto B = CS.arg_begin(), E = CS.arg_end();
352*da58b97aSjoerg         for (auto A = B; A != E; ++A)
35306f32e7eSjoerg           if (A->get() == V)
35406f32e7eSjoerg             if (!(CS.doesNotCapture(A - B) && (CS.doesNotAccessMemory(A - B) ||
35506f32e7eSjoerg                                                CS.doesNotAccessMemory()))) {
35606f32e7eSjoerg               LLVM_DEBUG(dbgs() << "[SafeStack] Unsafe alloca: " << *AllocaPtr
35706f32e7eSjoerg                                 << "\n            unsafe call: " << *I << "\n");
35806f32e7eSjoerg               return false;
35906f32e7eSjoerg             }
36006f32e7eSjoerg         continue;
36106f32e7eSjoerg       }
36206f32e7eSjoerg 
36306f32e7eSjoerg       default:
36406f32e7eSjoerg         if (Visited.insert(I).second)
36506f32e7eSjoerg           WorkList.push_back(cast<const Instruction>(I));
36606f32e7eSjoerg       }
36706f32e7eSjoerg     }
36806f32e7eSjoerg   }
36906f32e7eSjoerg 
37006f32e7eSjoerg   // All uses of the alloca are safe, we can place it on the safe stack.
37106f32e7eSjoerg   return true;
37206f32e7eSjoerg }
37306f32e7eSjoerg 
getStackGuard(IRBuilder<> & IRB,Function & F)37406f32e7eSjoerg Value *SafeStack::getStackGuard(IRBuilder<> &IRB, Function &F) {
37506f32e7eSjoerg   Value *StackGuardVar = TL.getIRStackGuard(IRB);
37606f32e7eSjoerg   if (!StackGuardVar)
37706f32e7eSjoerg     StackGuardVar =
37806f32e7eSjoerg         F.getParent()->getOrInsertGlobal("__stack_chk_guard", StackPtrTy);
37906f32e7eSjoerg   return IRB.CreateLoad(StackPtrTy, StackGuardVar, "StackGuard");
38006f32e7eSjoerg }
38106f32e7eSjoerg 
findInsts(Function & F,SmallVectorImpl<AllocaInst * > & StaticAllocas,SmallVectorImpl<AllocaInst * > & DynamicAllocas,SmallVectorImpl<Argument * > & ByValArguments,SmallVectorImpl<Instruction * > & Returns,SmallVectorImpl<Instruction * > & StackRestorePoints)38206f32e7eSjoerg void SafeStack::findInsts(Function &F,
38306f32e7eSjoerg                           SmallVectorImpl<AllocaInst *> &StaticAllocas,
38406f32e7eSjoerg                           SmallVectorImpl<AllocaInst *> &DynamicAllocas,
38506f32e7eSjoerg                           SmallVectorImpl<Argument *> &ByValArguments,
386*da58b97aSjoerg                           SmallVectorImpl<Instruction *> &Returns,
38706f32e7eSjoerg                           SmallVectorImpl<Instruction *> &StackRestorePoints) {
38806f32e7eSjoerg   for (Instruction &I : instructions(&F)) {
38906f32e7eSjoerg     if (auto AI = dyn_cast<AllocaInst>(&I)) {
39006f32e7eSjoerg       ++NumAllocas;
39106f32e7eSjoerg 
39206f32e7eSjoerg       uint64_t Size = getStaticAllocaAllocationSize(AI);
39306f32e7eSjoerg       if (IsSafeStackAlloca(AI, Size))
39406f32e7eSjoerg         continue;
39506f32e7eSjoerg 
39606f32e7eSjoerg       if (AI->isStaticAlloca()) {
39706f32e7eSjoerg         ++NumUnsafeStaticAllocas;
39806f32e7eSjoerg         StaticAllocas.push_back(AI);
39906f32e7eSjoerg       } else {
40006f32e7eSjoerg         ++NumUnsafeDynamicAllocas;
40106f32e7eSjoerg         DynamicAllocas.push_back(AI);
40206f32e7eSjoerg       }
40306f32e7eSjoerg     } else if (auto RI = dyn_cast<ReturnInst>(&I)) {
404*da58b97aSjoerg       if (CallInst *CI = I.getParent()->getTerminatingMustTailCall())
405*da58b97aSjoerg         Returns.push_back(CI);
406*da58b97aSjoerg       else
40706f32e7eSjoerg         Returns.push_back(RI);
40806f32e7eSjoerg     } else if (auto CI = dyn_cast<CallInst>(&I)) {
40906f32e7eSjoerg       // setjmps require stack restore.
41006f32e7eSjoerg       if (CI->getCalledFunction() && CI->canReturnTwice())
41106f32e7eSjoerg         StackRestorePoints.push_back(CI);
41206f32e7eSjoerg     } else if (auto LP = dyn_cast<LandingPadInst>(&I)) {
41306f32e7eSjoerg       // Exception landing pads require stack restore.
41406f32e7eSjoerg       StackRestorePoints.push_back(LP);
41506f32e7eSjoerg     } else if (auto II = dyn_cast<IntrinsicInst>(&I)) {
41606f32e7eSjoerg       if (II->getIntrinsicID() == Intrinsic::gcroot)
41706f32e7eSjoerg         report_fatal_error(
41806f32e7eSjoerg             "gcroot intrinsic not compatible with safestack attribute");
41906f32e7eSjoerg     }
42006f32e7eSjoerg   }
42106f32e7eSjoerg   for (Argument &Arg : F.args()) {
42206f32e7eSjoerg     if (!Arg.hasByValAttr())
42306f32e7eSjoerg       continue;
42406f32e7eSjoerg     uint64_t Size =
42506f32e7eSjoerg         DL.getTypeStoreSize(Arg.getType()->getPointerElementType());
42606f32e7eSjoerg     if (IsSafeStackAlloca(&Arg, Size))
42706f32e7eSjoerg       continue;
42806f32e7eSjoerg 
42906f32e7eSjoerg     ++NumUnsafeByValArguments;
43006f32e7eSjoerg     ByValArguments.push_back(&Arg);
43106f32e7eSjoerg   }
43206f32e7eSjoerg }
43306f32e7eSjoerg 
43406f32e7eSjoerg AllocaInst *
createStackRestorePoints(IRBuilder<> & IRB,Function & F,ArrayRef<Instruction * > StackRestorePoints,Value * StaticTop,bool NeedDynamicTop)43506f32e7eSjoerg SafeStack::createStackRestorePoints(IRBuilder<> &IRB, Function &F,
43606f32e7eSjoerg                                     ArrayRef<Instruction *> StackRestorePoints,
43706f32e7eSjoerg                                     Value *StaticTop, bool NeedDynamicTop) {
43806f32e7eSjoerg   assert(StaticTop && "The stack top isn't set.");
43906f32e7eSjoerg 
44006f32e7eSjoerg   if (StackRestorePoints.empty())
44106f32e7eSjoerg     return nullptr;
44206f32e7eSjoerg 
44306f32e7eSjoerg   // We need the current value of the shadow stack pointer to restore
44406f32e7eSjoerg   // after longjmp or exception catching.
44506f32e7eSjoerg 
44606f32e7eSjoerg   // FIXME: On some platforms this could be handled by the longjmp/exception
44706f32e7eSjoerg   // runtime itself.
44806f32e7eSjoerg 
44906f32e7eSjoerg   AllocaInst *DynamicTop = nullptr;
45006f32e7eSjoerg   if (NeedDynamicTop) {
45106f32e7eSjoerg     // If we also have dynamic alloca's, the stack pointer value changes
45206f32e7eSjoerg     // throughout the function. For now we store it in an alloca.
45306f32e7eSjoerg     DynamicTop = IRB.CreateAlloca(StackPtrTy, /*ArraySize=*/nullptr,
45406f32e7eSjoerg                                   "unsafe_stack_dynamic_ptr");
45506f32e7eSjoerg     IRB.CreateStore(StaticTop, DynamicTop);
45606f32e7eSjoerg   }
45706f32e7eSjoerg 
45806f32e7eSjoerg   // Restore current stack pointer after longjmp/exception catch.
45906f32e7eSjoerg   for (Instruction *I : StackRestorePoints) {
46006f32e7eSjoerg     ++NumUnsafeStackRestorePoints;
46106f32e7eSjoerg 
46206f32e7eSjoerg     IRB.SetInsertPoint(I->getNextNode());
46306f32e7eSjoerg     Value *CurrentTop =
46406f32e7eSjoerg         DynamicTop ? IRB.CreateLoad(StackPtrTy, DynamicTop) : StaticTop;
46506f32e7eSjoerg     IRB.CreateStore(CurrentTop, UnsafeStackPtr);
46606f32e7eSjoerg   }
46706f32e7eSjoerg 
46806f32e7eSjoerg   return DynamicTop;
46906f32e7eSjoerg }
47006f32e7eSjoerg 
checkStackGuard(IRBuilder<> & IRB,Function & F,Instruction & RI,AllocaInst * StackGuardSlot,Value * StackGuard)471*da58b97aSjoerg void SafeStack::checkStackGuard(IRBuilder<> &IRB, Function &F, Instruction &RI,
47206f32e7eSjoerg                                 AllocaInst *StackGuardSlot, Value *StackGuard) {
47306f32e7eSjoerg   Value *V = IRB.CreateLoad(StackPtrTy, StackGuardSlot);
47406f32e7eSjoerg   Value *Cmp = IRB.CreateICmpNE(StackGuard, V);
47506f32e7eSjoerg 
47606f32e7eSjoerg   auto SuccessProb = BranchProbabilityInfo::getBranchProbStackProtector(true);
47706f32e7eSjoerg   auto FailureProb = BranchProbabilityInfo::getBranchProbStackProtector(false);
47806f32e7eSjoerg   MDNode *Weights = MDBuilder(F.getContext())
47906f32e7eSjoerg                         .createBranchWeights(SuccessProb.getNumerator(),
48006f32e7eSjoerg                                              FailureProb.getNumerator());
48106f32e7eSjoerg   Instruction *CheckTerm =
482*da58b97aSjoerg       SplitBlockAndInsertIfThen(Cmp, &RI, /* Unreachable */ true, Weights, DTU);
48306f32e7eSjoerg   IRBuilder<> IRBFail(CheckTerm);
48406f32e7eSjoerg   // FIXME: respect -fsanitize-trap / -ftrap-function here?
48506f32e7eSjoerg   FunctionCallee StackChkFail =
48606f32e7eSjoerg       F.getParent()->getOrInsertFunction("__stack_chk_fail", IRB.getVoidTy());
48706f32e7eSjoerg   IRBFail.CreateCall(StackChkFail, {});
48806f32e7eSjoerg }
48906f32e7eSjoerg 
49006f32e7eSjoerg /// We explicitly compute and set the unsafe stack layout for all unsafe
49106f32e7eSjoerg /// static alloca instructions. We save the unsafe "base pointer" in the
49206f32e7eSjoerg /// prologue into a local variable and restore it in the epilogue.
moveStaticAllocasToUnsafeStack(IRBuilder<> & IRB,Function & F,ArrayRef<AllocaInst * > StaticAllocas,ArrayRef<Argument * > ByValArguments,Instruction * BasePointer,AllocaInst * StackGuardSlot)49306f32e7eSjoerg Value *SafeStack::moveStaticAllocasToUnsafeStack(
49406f32e7eSjoerg     IRBuilder<> &IRB, Function &F, ArrayRef<AllocaInst *> StaticAllocas,
495*da58b97aSjoerg     ArrayRef<Argument *> ByValArguments, Instruction *BasePointer,
496*da58b97aSjoerg     AllocaInst *StackGuardSlot) {
49706f32e7eSjoerg   if (StaticAllocas.empty() && ByValArguments.empty())
49806f32e7eSjoerg     return BasePointer;
49906f32e7eSjoerg 
50006f32e7eSjoerg   DIBuilder DIB(*F.getParent());
50106f32e7eSjoerg 
502*da58b97aSjoerg   StackLifetime SSC(F, StaticAllocas, StackLifetime::LivenessType::May);
503*da58b97aSjoerg   static const StackLifetime::LiveRange NoColoringRange(1, true);
504*da58b97aSjoerg   if (ClColoring)
50506f32e7eSjoerg     SSC.run();
506*da58b97aSjoerg 
507*da58b97aSjoerg   for (auto *I : SSC.getMarkers()) {
508*da58b97aSjoerg     auto *Op = dyn_cast<Instruction>(I->getOperand(1));
509*da58b97aSjoerg     const_cast<IntrinsicInst *>(I)->eraseFromParent();
510*da58b97aSjoerg     // Remove the operand bitcast, too, if it has no more uses left.
511*da58b97aSjoerg     if (Op && Op->use_empty())
512*da58b97aSjoerg       Op->eraseFromParent();
513*da58b97aSjoerg   }
51406f32e7eSjoerg 
51506f32e7eSjoerg   // Unsafe stack always grows down.
51606f32e7eSjoerg   StackLayout SSL(StackAlignment);
51706f32e7eSjoerg   if (StackGuardSlot) {
51806f32e7eSjoerg     Type *Ty = StackGuardSlot->getAllocatedType();
51906f32e7eSjoerg     unsigned Align =
52006f32e7eSjoerg         std::max(DL.getPrefTypeAlignment(Ty), StackGuardSlot->getAlignment());
52106f32e7eSjoerg     SSL.addObject(StackGuardSlot, getStaticAllocaAllocationSize(StackGuardSlot),
52206f32e7eSjoerg                   Align, SSC.getFullLiveRange());
52306f32e7eSjoerg   }
52406f32e7eSjoerg 
52506f32e7eSjoerg   for (Argument *Arg : ByValArguments) {
52606f32e7eSjoerg     Type *Ty = Arg->getType()->getPointerElementType();
52706f32e7eSjoerg     uint64_t Size = DL.getTypeStoreSize(Ty);
52806f32e7eSjoerg     if (Size == 0)
52906f32e7eSjoerg       Size = 1; // Don't create zero-sized stack objects.
53006f32e7eSjoerg 
53106f32e7eSjoerg     // Ensure the object is properly aligned.
53206f32e7eSjoerg     unsigned Align = std::max((unsigned)DL.getPrefTypeAlignment(Ty),
53306f32e7eSjoerg                               Arg->getParamAlignment());
53406f32e7eSjoerg     SSL.addObject(Arg, Size, Align, SSC.getFullLiveRange());
53506f32e7eSjoerg   }
53606f32e7eSjoerg 
53706f32e7eSjoerg   for (AllocaInst *AI : StaticAllocas) {
53806f32e7eSjoerg     Type *Ty = AI->getAllocatedType();
53906f32e7eSjoerg     uint64_t Size = getStaticAllocaAllocationSize(AI);
54006f32e7eSjoerg     if (Size == 0)
54106f32e7eSjoerg       Size = 1; // Don't create zero-sized stack objects.
54206f32e7eSjoerg 
54306f32e7eSjoerg     // Ensure the object is properly aligned.
54406f32e7eSjoerg     unsigned Align =
54506f32e7eSjoerg         std::max((unsigned)DL.getPrefTypeAlignment(Ty), AI->getAlignment());
54606f32e7eSjoerg 
547*da58b97aSjoerg     SSL.addObject(AI, Size, Align,
548*da58b97aSjoerg                   ClColoring ? SSC.getLiveRange(AI) : NoColoringRange);
54906f32e7eSjoerg   }
55006f32e7eSjoerg 
55106f32e7eSjoerg   SSL.computeLayout();
55206f32e7eSjoerg   unsigned FrameAlignment = SSL.getFrameAlignment();
55306f32e7eSjoerg 
55406f32e7eSjoerg   // FIXME: tell SSL that we start at a less-then-MaxAlignment aligned location
55506f32e7eSjoerg   // (AlignmentSkew).
55606f32e7eSjoerg   if (FrameAlignment > StackAlignment) {
55706f32e7eSjoerg     // Re-align the base pointer according to the max requested alignment.
55806f32e7eSjoerg     assert(isPowerOf2_32(FrameAlignment));
55906f32e7eSjoerg     IRB.SetInsertPoint(BasePointer->getNextNode());
56006f32e7eSjoerg     BasePointer = cast<Instruction>(IRB.CreateIntToPtr(
56106f32e7eSjoerg         IRB.CreateAnd(IRB.CreatePtrToInt(BasePointer, IntPtrTy),
56206f32e7eSjoerg                       ConstantInt::get(IntPtrTy, ~uint64_t(FrameAlignment - 1))),
56306f32e7eSjoerg         StackPtrTy));
56406f32e7eSjoerg   }
56506f32e7eSjoerg 
56606f32e7eSjoerg   IRB.SetInsertPoint(BasePointer->getNextNode());
56706f32e7eSjoerg 
56806f32e7eSjoerg   if (StackGuardSlot) {
56906f32e7eSjoerg     unsigned Offset = SSL.getObjectOffset(StackGuardSlot);
57006f32e7eSjoerg     Value *Off = IRB.CreateGEP(Int8Ty, BasePointer, // BasePointer is i8*
57106f32e7eSjoerg                                ConstantInt::get(Int32Ty, -Offset));
57206f32e7eSjoerg     Value *NewAI =
57306f32e7eSjoerg         IRB.CreateBitCast(Off, StackGuardSlot->getType(), "StackGuardSlot");
57406f32e7eSjoerg 
57506f32e7eSjoerg     // Replace alloc with the new location.
57606f32e7eSjoerg     StackGuardSlot->replaceAllUsesWith(NewAI);
57706f32e7eSjoerg     StackGuardSlot->eraseFromParent();
57806f32e7eSjoerg   }
57906f32e7eSjoerg 
58006f32e7eSjoerg   for (Argument *Arg : ByValArguments) {
58106f32e7eSjoerg     unsigned Offset = SSL.getObjectOffset(Arg);
582*da58b97aSjoerg     MaybeAlign Align(SSL.getObjectAlignment(Arg));
58306f32e7eSjoerg     Type *Ty = Arg->getType()->getPointerElementType();
58406f32e7eSjoerg 
58506f32e7eSjoerg     uint64_t Size = DL.getTypeStoreSize(Ty);
58606f32e7eSjoerg     if (Size == 0)
58706f32e7eSjoerg       Size = 1; // Don't create zero-sized stack objects.
58806f32e7eSjoerg 
58906f32e7eSjoerg     Value *Off = IRB.CreateGEP(Int8Ty, BasePointer, // BasePointer is i8*
59006f32e7eSjoerg                                ConstantInt::get(Int32Ty, -Offset));
59106f32e7eSjoerg     Value *NewArg = IRB.CreateBitCast(Off, Arg->getType(),
59206f32e7eSjoerg                                      Arg->getName() + ".unsafe-byval");
59306f32e7eSjoerg 
59406f32e7eSjoerg     // Replace alloc with the new location.
595*da58b97aSjoerg     replaceDbgDeclare(Arg, BasePointer, DIB, DIExpression::ApplyOffset,
596*da58b97aSjoerg                       -Offset);
59706f32e7eSjoerg     Arg->replaceAllUsesWith(NewArg);
59806f32e7eSjoerg     IRB.SetInsertPoint(cast<Instruction>(NewArg)->getNextNode());
599*da58b97aSjoerg     IRB.CreateMemCpy(Off, Align, Arg, Arg->getParamAlign(), Size);
60006f32e7eSjoerg   }
60106f32e7eSjoerg 
60206f32e7eSjoerg   // Allocate space for every unsafe static AllocaInst on the unsafe stack.
60306f32e7eSjoerg   for (AllocaInst *AI : StaticAllocas) {
60406f32e7eSjoerg     IRB.SetInsertPoint(AI);
60506f32e7eSjoerg     unsigned Offset = SSL.getObjectOffset(AI);
60606f32e7eSjoerg 
607*da58b97aSjoerg     replaceDbgDeclare(AI, BasePointer, DIB, DIExpression::ApplyOffset, -Offset);
60806f32e7eSjoerg     replaceDbgValueForAlloca(AI, BasePointer, DIB, -Offset);
60906f32e7eSjoerg 
61006f32e7eSjoerg     // Replace uses of the alloca with the new location.
61106f32e7eSjoerg     // Insert address calculation close to each use to work around PR27844.
61206f32e7eSjoerg     std::string Name = std::string(AI->getName()) + ".unsafe";
61306f32e7eSjoerg     while (!AI->use_empty()) {
61406f32e7eSjoerg       Use &U = *AI->use_begin();
61506f32e7eSjoerg       Instruction *User = cast<Instruction>(U.getUser());
61606f32e7eSjoerg 
61706f32e7eSjoerg       Instruction *InsertBefore;
61806f32e7eSjoerg       if (auto *PHI = dyn_cast<PHINode>(User))
61906f32e7eSjoerg         InsertBefore = PHI->getIncomingBlock(U)->getTerminator();
62006f32e7eSjoerg       else
62106f32e7eSjoerg         InsertBefore = User;
62206f32e7eSjoerg 
62306f32e7eSjoerg       IRBuilder<> IRBUser(InsertBefore);
62406f32e7eSjoerg       Value *Off = IRBUser.CreateGEP(Int8Ty, BasePointer, // BasePointer is i8*
62506f32e7eSjoerg                                      ConstantInt::get(Int32Ty, -Offset));
62606f32e7eSjoerg       Value *Replacement = IRBUser.CreateBitCast(Off, AI->getType(), Name);
62706f32e7eSjoerg 
62806f32e7eSjoerg       if (auto *PHI = dyn_cast<PHINode>(User))
62906f32e7eSjoerg         // PHI nodes may have multiple incoming edges from the same BB (why??),
63006f32e7eSjoerg         // all must be updated at once with the same incoming value.
63106f32e7eSjoerg         PHI->setIncomingValueForBlock(PHI->getIncomingBlock(U), Replacement);
63206f32e7eSjoerg       else
63306f32e7eSjoerg         U.set(Replacement);
63406f32e7eSjoerg     }
63506f32e7eSjoerg 
63606f32e7eSjoerg     AI->eraseFromParent();
63706f32e7eSjoerg   }
63806f32e7eSjoerg 
63906f32e7eSjoerg   // Re-align BasePointer so that our callees would see it aligned as
64006f32e7eSjoerg   // expected.
64106f32e7eSjoerg   // FIXME: no need to update BasePointer in leaf functions.
64206f32e7eSjoerg   unsigned FrameSize = alignTo(SSL.getFrameSize(), StackAlignment);
64306f32e7eSjoerg 
64406f32e7eSjoerg   // Update shadow stack pointer in the function epilogue.
64506f32e7eSjoerg   IRB.SetInsertPoint(BasePointer->getNextNode());
64606f32e7eSjoerg 
64706f32e7eSjoerg   Value *StaticTop =
64806f32e7eSjoerg       IRB.CreateGEP(Int8Ty, BasePointer, ConstantInt::get(Int32Ty, -FrameSize),
64906f32e7eSjoerg                     "unsafe_stack_static_top");
65006f32e7eSjoerg   IRB.CreateStore(StaticTop, UnsafeStackPtr);
65106f32e7eSjoerg   return StaticTop;
65206f32e7eSjoerg }
65306f32e7eSjoerg 
moveDynamicAllocasToUnsafeStack(Function & F,Value * UnsafeStackPtr,AllocaInst * DynamicTop,ArrayRef<AllocaInst * > DynamicAllocas)65406f32e7eSjoerg void SafeStack::moveDynamicAllocasToUnsafeStack(
65506f32e7eSjoerg     Function &F, Value *UnsafeStackPtr, AllocaInst *DynamicTop,
65606f32e7eSjoerg     ArrayRef<AllocaInst *> DynamicAllocas) {
65706f32e7eSjoerg   DIBuilder DIB(*F.getParent());
65806f32e7eSjoerg 
65906f32e7eSjoerg   for (AllocaInst *AI : DynamicAllocas) {
66006f32e7eSjoerg     IRBuilder<> IRB(AI);
66106f32e7eSjoerg 
66206f32e7eSjoerg     // Compute the new SP value (after AI).
66306f32e7eSjoerg     Value *ArraySize = AI->getArraySize();
66406f32e7eSjoerg     if (ArraySize->getType() != IntPtrTy)
66506f32e7eSjoerg       ArraySize = IRB.CreateIntCast(ArraySize, IntPtrTy, false);
66606f32e7eSjoerg 
66706f32e7eSjoerg     Type *Ty = AI->getAllocatedType();
66806f32e7eSjoerg     uint64_t TySize = DL.getTypeAllocSize(Ty);
66906f32e7eSjoerg     Value *Size = IRB.CreateMul(ArraySize, ConstantInt::get(IntPtrTy, TySize));
67006f32e7eSjoerg 
67106f32e7eSjoerg     Value *SP = IRB.CreatePtrToInt(IRB.CreateLoad(StackPtrTy, UnsafeStackPtr),
67206f32e7eSjoerg                                    IntPtrTy);
67306f32e7eSjoerg     SP = IRB.CreateSub(SP, Size);
67406f32e7eSjoerg 
67506f32e7eSjoerg     // Align the SP value to satisfy the AllocaInst, type and stack alignments.
67606f32e7eSjoerg     unsigned Align = std::max(
67706f32e7eSjoerg         std::max((unsigned)DL.getPrefTypeAlignment(Ty), AI->getAlignment()),
67806f32e7eSjoerg         (unsigned)StackAlignment);
67906f32e7eSjoerg 
68006f32e7eSjoerg     assert(isPowerOf2_32(Align));
68106f32e7eSjoerg     Value *NewTop = IRB.CreateIntToPtr(
68206f32e7eSjoerg         IRB.CreateAnd(SP, ConstantInt::get(IntPtrTy, ~uint64_t(Align - 1))),
68306f32e7eSjoerg         StackPtrTy);
68406f32e7eSjoerg 
68506f32e7eSjoerg     // Save the stack pointer.
68606f32e7eSjoerg     IRB.CreateStore(NewTop, UnsafeStackPtr);
68706f32e7eSjoerg     if (DynamicTop)
68806f32e7eSjoerg       IRB.CreateStore(NewTop, DynamicTop);
68906f32e7eSjoerg 
69006f32e7eSjoerg     Value *NewAI = IRB.CreatePointerCast(NewTop, AI->getType());
69106f32e7eSjoerg     if (AI->hasName() && isa<Instruction>(NewAI))
69206f32e7eSjoerg       NewAI->takeName(AI);
69306f32e7eSjoerg 
694*da58b97aSjoerg     replaceDbgDeclare(AI, NewAI, DIB, DIExpression::ApplyOffset, 0);
69506f32e7eSjoerg     AI->replaceAllUsesWith(NewAI);
69606f32e7eSjoerg     AI->eraseFromParent();
69706f32e7eSjoerg   }
69806f32e7eSjoerg 
69906f32e7eSjoerg   if (!DynamicAllocas.empty()) {
70006f32e7eSjoerg     // Now go through the instructions again, replacing stacksave/stackrestore.
70106f32e7eSjoerg     for (inst_iterator It = inst_begin(&F), Ie = inst_end(&F); It != Ie;) {
70206f32e7eSjoerg       Instruction *I = &*(It++);
70306f32e7eSjoerg       auto II = dyn_cast<IntrinsicInst>(I);
70406f32e7eSjoerg       if (!II)
70506f32e7eSjoerg         continue;
70606f32e7eSjoerg 
70706f32e7eSjoerg       if (II->getIntrinsicID() == Intrinsic::stacksave) {
70806f32e7eSjoerg         IRBuilder<> IRB(II);
70906f32e7eSjoerg         Instruction *LI = IRB.CreateLoad(StackPtrTy, UnsafeStackPtr);
71006f32e7eSjoerg         LI->takeName(II);
71106f32e7eSjoerg         II->replaceAllUsesWith(LI);
71206f32e7eSjoerg         II->eraseFromParent();
71306f32e7eSjoerg       } else if (II->getIntrinsicID() == Intrinsic::stackrestore) {
71406f32e7eSjoerg         IRBuilder<> IRB(II);
71506f32e7eSjoerg         Instruction *SI = IRB.CreateStore(II->getArgOperand(0), UnsafeStackPtr);
71606f32e7eSjoerg         SI->takeName(II);
71706f32e7eSjoerg         assert(II->use_empty());
71806f32e7eSjoerg         II->eraseFromParent();
71906f32e7eSjoerg       }
72006f32e7eSjoerg     }
72106f32e7eSjoerg   }
72206f32e7eSjoerg }
72306f32e7eSjoerg 
ShouldInlinePointerAddress(CallInst & CI)724*da58b97aSjoerg bool SafeStack::ShouldInlinePointerAddress(CallInst &CI) {
725*da58b97aSjoerg   Function *Callee = CI.getCalledFunction();
726*da58b97aSjoerg   if (CI.hasFnAttr(Attribute::AlwaysInline) &&
727*da58b97aSjoerg       isInlineViable(*Callee).isSuccess())
72806f32e7eSjoerg     return true;
72906f32e7eSjoerg   if (Callee->isInterposable() || Callee->hasFnAttribute(Attribute::NoInline) ||
730*da58b97aSjoerg       CI.isNoInline())
73106f32e7eSjoerg     return false;
73206f32e7eSjoerg   return true;
73306f32e7eSjoerg }
73406f32e7eSjoerg 
TryInlinePointerAddress()73506f32e7eSjoerg void SafeStack::TryInlinePointerAddress() {
736*da58b97aSjoerg   auto *CI = dyn_cast<CallInst>(UnsafeStackPtr);
737*da58b97aSjoerg   if (!CI)
73806f32e7eSjoerg     return;
73906f32e7eSjoerg 
74006f32e7eSjoerg   if(F.hasOptNone())
74106f32e7eSjoerg     return;
74206f32e7eSjoerg 
743*da58b97aSjoerg   Function *Callee = CI->getCalledFunction();
74406f32e7eSjoerg   if (!Callee || Callee->isDeclaration())
74506f32e7eSjoerg     return;
74606f32e7eSjoerg 
747*da58b97aSjoerg   if (!ShouldInlinePointerAddress(*CI))
74806f32e7eSjoerg     return;
74906f32e7eSjoerg 
75006f32e7eSjoerg   InlineFunctionInfo IFI;
751*da58b97aSjoerg   InlineFunction(*CI, IFI);
75206f32e7eSjoerg }
75306f32e7eSjoerg 
run()75406f32e7eSjoerg bool SafeStack::run() {
75506f32e7eSjoerg   assert(F.hasFnAttribute(Attribute::SafeStack) &&
75606f32e7eSjoerg          "Can't run SafeStack on a function without the attribute");
75706f32e7eSjoerg   assert(!F.isDeclaration() && "Can't run SafeStack on a function declaration");
75806f32e7eSjoerg 
75906f32e7eSjoerg   ++NumFunctions;
76006f32e7eSjoerg 
76106f32e7eSjoerg   SmallVector<AllocaInst *, 16> StaticAllocas;
76206f32e7eSjoerg   SmallVector<AllocaInst *, 4> DynamicAllocas;
76306f32e7eSjoerg   SmallVector<Argument *, 4> ByValArguments;
764*da58b97aSjoerg   SmallVector<Instruction *, 4> Returns;
76506f32e7eSjoerg 
76606f32e7eSjoerg   // Collect all points where stack gets unwound and needs to be restored
76706f32e7eSjoerg   // This is only necessary because the runtime (setjmp and unwind code) is
76806f32e7eSjoerg   // not aware of the unsafe stack and won't unwind/restore it properly.
76906f32e7eSjoerg   // To work around this problem without changing the runtime, we insert
77006f32e7eSjoerg   // instrumentation to restore the unsafe stack pointer when necessary.
77106f32e7eSjoerg   SmallVector<Instruction *, 4> StackRestorePoints;
77206f32e7eSjoerg 
77306f32e7eSjoerg   // Find all static and dynamic alloca instructions that must be moved to the
77406f32e7eSjoerg   // unsafe stack, all return instructions and stack restore points.
77506f32e7eSjoerg   findInsts(F, StaticAllocas, DynamicAllocas, ByValArguments, Returns,
77606f32e7eSjoerg             StackRestorePoints);
77706f32e7eSjoerg 
77806f32e7eSjoerg   if (StaticAllocas.empty() && DynamicAllocas.empty() &&
77906f32e7eSjoerg       ByValArguments.empty() && StackRestorePoints.empty())
78006f32e7eSjoerg     return false; // Nothing to do in this function.
78106f32e7eSjoerg 
78206f32e7eSjoerg   if (!StaticAllocas.empty() || !DynamicAllocas.empty() ||
78306f32e7eSjoerg       !ByValArguments.empty())
78406f32e7eSjoerg     ++NumUnsafeStackFunctions; // This function has the unsafe stack.
78506f32e7eSjoerg 
78606f32e7eSjoerg   if (!StackRestorePoints.empty())
78706f32e7eSjoerg     ++NumUnsafeStackRestorePointsFunctions;
78806f32e7eSjoerg 
78906f32e7eSjoerg   IRBuilder<> IRB(&F.front(), F.begin()->getFirstInsertionPt());
79006f32e7eSjoerg   // Calls must always have a debug location, or else inlining breaks. So
79106f32e7eSjoerg   // we explicitly set a artificial debug location here.
79206f32e7eSjoerg   if (DISubprogram *SP = F.getSubprogram())
793*da58b97aSjoerg     IRB.SetCurrentDebugLocation(
794*da58b97aSjoerg         DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP));
79506f32e7eSjoerg   if (SafeStackUsePointerAddress) {
79606f32e7eSjoerg     FunctionCallee Fn = F.getParent()->getOrInsertFunction(
79706f32e7eSjoerg         "__safestack_pointer_address", StackPtrTy->getPointerTo(0));
79806f32e7eSjoerg     UnsafeStackPtr = IRB.CreateCall(Fn);
79906f32e7eSjoerg   } else {
80006f32e7eSjoerg     UnsafeStackPtr = TL.getSafeStackPointerLocation(IRB);
80106f32e7eSjoerg   }
80206f32e7eSjoerg 
80306f32e7eSjoerg   // Load the current stack pointer (we'll also use it as a base pointer).
80406f32e7eSjoerg   // FIXME: use a dedicated register for it ?
80506f32e7eSjoerg   Instruction *BasePointer =
80606f32e7eSjoerg       IRB.CreateLoad(StackPtrTy, UnsafeStackPtr, false, "unsafe_stack_ptr");
80706f32e7eSjoerg   assert(BasePointer->getType() == StackPtrTy);
80806f32e7eSjoerg 
80906f32e7eSjoerg   AllocaInst *StackGuardSlot = nullptr;
81006f32e7eSjoerg   // FIXME: implement weaker forms of stack protector.
81106f32e7eSjoerg   if (F.hasFnAttribute(Attribute::StackProtect) ||
81206f32e7eSjoerg       F.hasFnAttribute(Attribute::StackProtectStrong) ||
81306f32e7eSjoerg       F.hasFnAttribute(Attribute::StackProtectReq)) {
81406f32e7eSjoerg     Value *StackGuard = getStackGuard(IRB, F);
81506f32e7eSjoerg     StackGuardSlot = IRB.CreateAlloca(StackPtrTy, nullptr);
81606f32e7eSjoerg     IRB.CreateStore(StackGuard, StackGuardSlot);
81706f32e7eSjoerg 
818*da58b97aSjoerg     for (Instruction *RI : Returns) {
81906f32e7eSjoerg       IRBuilder<> IRBRet(RI);
82006f32e7eSjoerg       checkStackGuard(IRBRet, F, *RI, StackGuardSlot, StackGuard);
82106f32e7eSjoerg     }
82206f32e7eSjoerg   }
82306f32e7eSjoerg 
82406f32e7eSjoerg   // The top of the unsafe stack after all unsafe static allocas are
82506f32e7eSjoerg   // allocated.
826*da58b97aSjoerg   Value *StaticTop = moveStaticAllocasToUnsafeStack(
827*da58b97aSjoerg       IRB, F, StaticAllocas, ByValArguments, BasePointer, StackGuardSlot);
82806f32e7eSjoerg 
82906f32e7eSjoerg   // Safe stack object that stores the current unsafe stack top. It is updated
83006f32e7eSjoerg   // as unsafe dynamic (non-constant-sized) allocas are allocated and freed.
83106f32e7eSjoerg   // This is only needed if we need to restore stack pointer after longjmp
83206f32e7eSjoerg   // or exceptions, and we have dynamic allocations.
83306f32e7eSjoerg   // FIXME: a better alternative might be to store the unsafe stack pointer
83406f32e7eSjoerg   // before setjmp / invoke instructions.
83506f32e7eSjoerg   AllocaInst *DynamicTop = createStackRestorePoints(
83606f32e7eSjoerg       IRB, F, StackRestorePoints, StaticTop, !DynamicAllocas.empty());
83706f32e7eSjoerg 
83806f32e7eSjoerg   // Handle dynamic allocas.
83906f32e7eSjoerg   moveDynamicAllocasToUnsafeStack(F, UnsafeStackPtr, DynamicTop,
84006f32e7eSjoerg                                   DynamicAllocas);
84106f32e7eSjoerg 
84206f32e7eSjoerg   // Restore the unsafe stack pointer before each return.
843*da58b97aSjoerg   for (Instruction *RI : Returns) {
84406f32e7eSjoerg     IRB.SetInsertPoint(RI);
84506f32e7eSjoerg     IRB.CreateStore(BasePointer, UnsafeStackPtr);
84606f32e7eSjoerg   }
84706f32e7eSjoerg 
84806f32e7eSjoerg   TryInlinePointerAddress();
84906f32e7eSjoerg 
85006f32e7eSjoerg   LLVM_DEBUG(dbgs() << "[SafeStack]     safestack applied\n");
85106f32e7eSjoerg   return true;
85206f32e7eSjoerg }
85306f32e7eSjoerg 
85406f32e7eSjoerg class SafeStackLegacyPass : public FunctionPass {
85506f32e7eSjoerg   const TargetMachine *TM = nullptr;
85606f32e7eSjoerg 
85706f32e7eSjoerg public:
85806f32e7eSjoerg   static char ID; // Pass identification, replacement for typeid..
85906f32e7eSjoerg 
SafeStackLegacyPass()86006f32e7eSjoerg   SafeStackLegacyPass() : FunctionPass(ID) {
86106f32e7eSjoerg     initializeSafeStackLegacyPassPass(*PassRegistry::getPassRegistry());
86206f32e7eSjoerg   }
86306f32e7eSjoerg 
getAnalysisUsage(AnalysisUsage & AU) const86406f32e7eSjoerg   void getAnalysisUsage(AnalysisUsage &AU) const override {
86506f32e7eSjoerg     AU.addRequired<TargetPassConfig>();
86606f32e7eSjoerg     AU.addRequired<TargetLibraryInfoWrapperPass>();
86706f32e7eSjoerg     AU.addRequired<AssumptionCacheTracker>();
868*da58b97aSjoerg     AU.addPreserved<DominatorTreeWrapperPass>();
86906f32e7eSjoerg   }
87006f32e7eSjoerg 
runOnFunction(Function & F)87106f32e7eSjoerg   bool runOnFunction(Function &F) override {
87206f32e7eSjoerg     LLVM_DEBUG(dbgs() << "[SafeStack] Function: " << F.getName() << "\n");
87306f32e7eSjoerg 
87406f32e7eSjoerg     if (!F.hasFnAttribute(Attribute::SafeStack)) {
87506f32e7eSjoerg       LLVM_DEBUG(dbgs() << "[SafeStack]     safestack is not requested"
87606f32e7eSjoerg                            " for this function\n");
87706f32e7eSjoerg       return false;
87806f32e7eSjoerg     }
87906f32e7eSjoerg 
88006f32e7eSjoerg     if (F.isDeclaration()) {
88106f32e7eSjoerg       LLVM_DEBUG(dbgs() << "[SafeStack]     function definition"
88206f32e7eSjoerg                            " is not available\n");
88306f32e7eSjoerg       return false;
88406f32e7eSjoerg     }
88506f32e7eSjoerg 
88606f32e7eSjoerg     TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
88706f32e7eSjoerg     auto *TL = TM->getSubtargetImpl(F)->getTargetLowering();
88806f32e7eSjoerg     if (!TL)
88906f32e7eSjoerg       report_fatal_error("TargetLowering instance is required");
89006f32e7eSjoerg 
89106f32e7eSjoerg     auto *DL = &F.getParent()->getDataLayout();
89206f32e7eSjoerg     auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
89306f32e7eSjoerg     auto &ACT = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
89406f32e7eSjoerg 
89506f32e7eSjoerg     // Compute DT and LI only for functions that have the attribute.
89606f32e7eSjoerg     // This is only useful because the legacy pass manager doesn't let us
89706f32e7eSjoerg     // compute analyzes lazily.
89806f32e7eSjoerg 
899*da58b97aSjoerg     DominatorTree *DT;
900*da58b97aSjoerg     bool ShouldPreserveDominatorTree;
901*da58b97aSjoerg     Optional<DominatorTree> LazilyComputedDomTree;
90206f32e7eSjoerg 
903*da58b97aSjoerg     // Do we already have a DominatorTree avaliable from the previous pass?
904*da58b97aSjoerg     // Note that we should *NOT* require it, to avoid the case where we end up
905*da58b97aSjoerg     // not needing it, but the legacy PM would have computed it for us anyways.
906*da58b97aSjoerg     if (auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>()) {
907*da58b97aSjoerg       DT = &DTWP->getDomTree();
908*da58b97aSjoerg       ShouldPreserveDominatorTree = true;
909*da58b97aSjoerg     } else {
910*da58b97aSjoerg       // Otherwise, we need to compute it.
911*da58b97aSjoerg       LazilyComputedDomTree.emplace(F);
912*da58b97aSjoerg       DT = LazilyComputedDomTree.getPointer();
913*da58b97aSjoerg       ShouldPreserveDominatorTree = false;
914*da58b97aSjoerg     }
915*da58b97aSjoerg 
916*da58b97aSjoerg     // Likewise, lazily compute loop info.
917*da58b97aSjoerg     LoopInfo LI(*DT);
918*da58b97aSjoerg 
919*da58b97aSjoerg     DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
920*da58b97aSjoerg 
921*da58b97aSjoerg     ScalarEvolution SE(F, TLI, ACT, *DT, LI);
922*da58b97aSjoerg 
923*da58b97aSjoerg     return SafeStack(F, *TL, *DL, ShouldPreserveDominatorTree ? &DTU : nullptr,
924*da58b97aSjoerg                      SE)
925*da58b97aSjoerg         .run();
92606f32e7eSjoerg   }
92706f32e7eSjoerg };
92806f32e7eSjoerg 
92906f32e7eSjoerg } // end anonymous namespace
93006f32e7eSjoerg 
93106f32e7eSjoerg char SafeStackLegacyPass::ID = 0;
93206f32e7eSjoerg 
93306f32e7eSjoerg INITIALIZE_PASS_BEGIN(SafeStackLegacyPass, DEBUG_TYPE,
93406f32e7eSjoerg                       "Safe Stack instrumentation pass", false, false)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)93506f32e7eSjoerg INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
936*da58b97aSjoerg INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
93706f32e7eSjoerg INITIALIZE_PASS_END(SafeStackLegacyPass, DEBUG_TYPE,
93806f32e7eSjoerg                     "Safe Stack instrumentation pass", false, false)
93906f32e7eSjoerg 
94006f32e7eSjoerg FunctionPass *llvm::createSafeStackPass() { return new SafeStackLegacyPass(); }
941