16948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar//===-- SafeStack.cpp - Safe Stack Insertion ------------------------------===// 26948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// 36948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// The LLVM Compiler Infrastructure 46948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// 56948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source 66948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// License. See LICENSE.TXT for details. 76948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// 86948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar//===----------------------------------------------------------------------===// 96948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// 106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// This pass splits the stack into the safe stack (kept as-is for LLVM backend) 116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// and the unsafe stack (explicitly allocated and managed through the runtime 126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// support library). 136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// 146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// http://clang.llvm.org/docs/SafeStack.html 156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// 166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar//===----------------------------------------------------------------------===// 176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/Transforms/Instrumentation.h" 196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/ADT/Statistic.h" 206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/ADT/Triple.h" 21cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/Analysis/ScalarEvolution.h" 22cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/Analysis/ScalarEvolutionExpressions.h" 23cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/CodeGen/Passes.h" 246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/IR/Constants.h" 256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/IR/DataLayout.h" 266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/IR/DerivedTypes.h" 276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/IR/DIBuilder.h" 286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/IR/Function.h" 296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/IR/InstIterator.h" 306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/IR/Instructions.h" 316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/IR/IntrinsicInst.h" 326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/IR/Intrinsics.h" 336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/IR/IRBuilder.h" 346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/IR/Module.h" 356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/Pass.h" 366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/Support/CommandLine.h" 376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/Support/Debug.h" 386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/Support/Format.h" 396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/Support/MathExtras.h" 406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/Support/raw_os_ostream.h" 41cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/Target/TargetLowering.h" 42cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/Target/TargetSubtargetInfo.h" 436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/Transforms/Utils/Local.h" 446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/Transforms/Utils/ModuleUtils.h" 456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarusing namespace llvm; 476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#define DEBUG_TYPE "safestack" 496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 50cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarenum UnsafeStackPtrStorageVal { ThreadLocalUSP, SingleThreadUSP }; 51cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 52cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstatic cl::opt<UnsafeStackPtrStorageVal> USPStorage("safe-stack-usp-storage", 53cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar cl::Hidden, cl::init(ThreadLocalUSP), 54cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar cl::desc("Type of storage for the unsafe stack pointer"), 55cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar cl::values(clEnumValN(ThreadLocalUSP, "thread-local", 56cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar "Thread-local storage"), 57cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar clEnumValN(SingleThreadUSP, "single-thread", 58cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar "Non-thread-local storage"), 59cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar clEnumValEnd)); 60cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarnamespace llvm { 626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarSTATISTIC(NumFunctions, "Total number of functions"); 646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarSTATISTIC(NumUnsafeStackFunctions, "Number of functions with unsafe stack"); 656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarSTATISTIC(NumUnsafeStackRestorePointsFunctions, 666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "Number of functions that use setjmp or exceptions"); 676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarSTATISTIC(NumAllocas, "Total number of allocas"); 696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarSTATISTIC(NumUnsafeStaticAllocas, "Number of unsafe static allocas"); 706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarSTATISTIC(NumUnsafeDynamicAllocas, "Number of unsafe dynamic allocas"); 71cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarSTATISTIC(NumUnsafeByValArguments, "Number of unsafe byval arguments"); 726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarSTATISTIC(NumUnsafeStackRestorePoints, "Number of setjmps and landingpads"); 736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} // namespace llvm 756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarnamespace { 776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 78cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// Rewrite an SCEV expression for a memory access address to an expression that 79cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// represents offset from the given alloca. 80cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// 81cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// The implementation simply replaces all mentions of the alloca with zero. 82cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarclass AllocaOffsetRewriter : public SCEVRewriteVisitor<AllocaOffsetRewriter> { 83cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar const Value *AllocaPtr; 846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 85cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarpublic: 86cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar AllocaOffsetRewriter(ScalarEvolution &SE, const Value *AllocaPtr) 87cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar : SCEVRewriteVisitor(SE), AllocaPtr(AllocaPtr) {} 886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 89cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar const SCEV *visitUnknown(const SCEVUnknown *Expr) { 90cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (Expr->getValue() == AllocaPtr) 91cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return SE.getZero(Expr->getType()); 92cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return Expr; 936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 94cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}; 956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 96cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// The SafeStack pass splits the stack of each function into the safe 97cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// stack, which is only accessed through memory safe dereferences (as 98cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// determined statically), and the unsafe stack, which contains all 99cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// local variables that are accessed in ways that we can't prove to 100cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// be safe. 1016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarclass SafeStack : public FunctionPass { 102cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar const TargetMachine *TM; 103cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar const TargetLoweringBase *TL; 1046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const DataLayout *DL; 105cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ScalarEvolution *SE; 1066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Type *StackPtrTy; 1086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Type *IntPtrTy; 1096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Type *Int32Ty; 1106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Type *Int8Ty; 1116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 112cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Value *UnsafeStackPtr = nullptr; 1136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// Unsafe stack alignment. Each stack frame must ensure that the stack is 1156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// aligned to this value. We need to re-align the unsafe stack if the 1166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// alignment of any object on the stack exceeds this value. 1176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// 1186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// 16 seems like a reasonable upper bound on the alignment of objects that we 1196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// might expect to appear on the stack on most common targets. 1206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar enum { StackAlignment = 16 }; 1216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 122cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar /// \brief Build a value representing a pointer to the unsafe stack pointer. 123cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Value *getOrCreateUnsafeStackPtr(IRBuilder<> &IRB, Function &F); 1246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// \brief Find all static allocas, dynamic allocas, return instructions and 1266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// stack restore points (exception unwind blocks and setjmp calls) in the 1276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// given function and append them to the respective vectors. 1286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void findInsts(Function &F, SmallVectorImpl<AllocaInst *> &StaticAllocas, 1296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SmallVectorImpl<AllocaInst *> &DynamicAllocas, 130cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SmallVectorImpl<Argument *> &ByValArguments, 1316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SmallVectorImpl<ReturnInst *> &Returns, 1326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SmallVectorImpl<Instruction *> &StackRestorePoints); 1336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 134cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar /// \brief Calculate the allocation size of a given alloca. Returns 0 if the 135cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar /// size can not be statically determined. 136cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t getStaticAllocaAllocationSize(const AllocaInst* AI); 137cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 1386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// \brief Allocate space for all static allocas in \p StaticAllocas, 1396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// replace allocas with pointers into the unsafe stack and generate code to 1406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// restore the stack pointer before all return instructions in \p Returns. 1416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// 1426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// \returns A pointer to the top of the unsafe stack after all unsafe static 1436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// allocas are allocated. 144cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Value *moveStaticAllocasToUnsafeStack(IRBuilder<> &IRB, Function &F, 1456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ArrayRef<AllocaInst *> StaticAllocas, 146cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ArrayRef<Argument *> ByValArguments, 1476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ArrayRef<ReturnInst *> Returns); 1486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// \brief Generate code to restore the stack after all stack restore points 1506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// in \p StackRestorePoints. 1516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// 1526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// \returns A local variable in which to maintain the dynamic top of the 1536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// unsafe stack if needed. 1546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AllocaInst * 155cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar createStackRestorePoints(IRBuilder<> &IRB, Function &F, 1566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ArrayRef<Instruction *> StackRestorePoints, 1576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Value *StaticTop, bool NeedDynamicTop); 1586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// \brief Replace all allocas in \p DynamicAllocas with code to allocate 1606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// space dynamically on the unsafe stack and store the dynamic unsafe stack 1616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// top to \p DynamicTop if non-null. 1626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void moveDynamicAllocasToUnsafeStack(Function &F, Value *UnsafeStackPtr, 1636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AllocaInst *DynamicTop, 1646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ArrayRef<AllocaInst *> DynamicAllocas); 1656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 166cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar bool IsSafeStackAlloca(const Value *AllocaPtr, uint64_t AllocaSize); 167cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 168cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar bool IsMemIntrinsicSafe(const MemIntrinsic *MI, const Use &U, 169cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar const Value *AllocaPtr, uint64_t AllocaSize); 170cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar bool IsAccessSafe(Value *Addr, uint64_t Size, const Value *AllocaPtr, 171cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t AllocaSize); 172cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 1736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarpublic: 1746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar static char ID; // Pass identification, replacement for typeid. 175cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SafeStack(const TargetMachine *TM) 176cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar : FunctionPass(ID), TM(TM), TL(nullptr), DL(nullptr) { 1776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar initializeSafeStackPass(*PassRegistry::getPassRegistry()); 1786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 179cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SafeStack() : SafeStack(nullptr) {} 1806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 181cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar void getAnalysisUsage(AnalysisUsage &AU) const override { 182cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar AU.addRequired<ScalarEvolutionWrapperPass>(); 1836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 1846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 185cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar bool doInitialization(Module &M) override { 1866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DL = &M.getDataLayout(); 1876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar StackPtrTy = Type::getInt8PtrTy(M.getContext()); 1896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IntPtrTy = DL->getIntPtrType(M.getContext()); 1906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Int32Ty = Type::getInt32Ty(M.getContext()); 1916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Int8Ty = Type::getInt8Ty(M.getContext()); 1926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 1946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 1956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 196cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar bool runOnFunction(Function &F) override; 1976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}; // class SafeStack 1986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 199cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainaruint64_t SafeStack::getStaticAllocaAllocationSize(const AllocaInst* AI) { 200cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t Size = DL->getTypeAllocSize(AI->getAllocatedType()); 201cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (AI->isArrayAllocation()) { 202cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar auto C = dyn_cast<ConstantInt>(AI->getArraySize()); 203cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!C) 204cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return 0; 205cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Size *= C->getZExtValue(); 206cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 207cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return Size; 208cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar} 209cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 210cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarbool SafeStack::IsAccessSafe(Value *Addr, uint64_t AccessSize, 211cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar const Value *AllocaPtr, uint64_t AllocaSize) { 212cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar AllocaOffsetRewriter Rewriter(*SE, AllocaPtr); 213cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar const SCEV *Expr = Rewriter.visit(SE->getSCEV(Addr)); 214cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 215cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t BitWidth = SE->getTypeSizeInBits(Expr->getType()); 216cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ConstantRange AccessStartRange = SE->getUnsignedRange(Expr); 217cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ConstantRange SizeRange = 218cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ConstantRange(APInt(BitWidth, 0), APInt(BitWidth, AccessSize)); 219cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ConstantRange AccessRange = AccessStartRange.add(SizeRange); 220cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ConstantRange AllocaRange = 221cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ConstantRange(APInt(BitWidth, 0), APInt(BitWidth, AllocaSize)); 222cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar bool Safe = AllocaRange.contains(AccessRange); 223cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 224cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar DEBUG(dbgs() << "[SafeStack] " 225cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar << (isa<AllocaInst>(AllocaPtr) ? "Alloca " : "ByValArgument ") 226cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar << *AllocaPtr << "\n" 227cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar << " Access " << *Addr << "\n" 228cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar << " SCEV " << *Expr 229cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar << " U: " << SE->getUnsignedRange(Expr) 230cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar << ", S: " << SE->getSignedRange(Expr) << "\n" 231cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar << " Range " << AccessRange << "\n" 232cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar << " AllocaRange " << AllocaRange << "\n" 233cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar << " " << (Safe ? "safe" : "unsafe") << "\n"); 234cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 235cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return Safe; 236cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar} 237cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 238cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarbool SafeStack::IsMemIntrinsicSafe(const MemIntrinsic *MI, const Use &U, 239cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar const Value *AllocaPtr, 240cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t AllocaSize) { 241cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // All MemIntrinsics have destination address in Arg0 and size in Arg2. 242cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (MI->getRawDest() != U) return true; 243cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar const auto *Len = dyn_cast<ConstantInt>(MI->getLength()); 244cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // Non-constant size => unsafe. FIXME: try SCEV getRange. 245cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!Len) return false; 246cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return IsAccessSafe(U, Len->getZExtValue(), AllocaPtr, AllocaSize); 247cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar} 248cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 249cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// Check whether a given allocation must be put on the safe 250cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// stack or not. The function analyzes all uses of AI and checks whether it is 251cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// only accessed in a memory safe way (as decided statically). 252cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarbool SafeStack::IsSafeStackAlloca(const Value *AllocaPtr, uint64_t AllocaSize) { 253cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // Go through all uses of this alloca and check whether all accesses to the 254cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // allocated object are statically known to be memory safe and, hence, the 255cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // object can be placed on the safe stack. 256cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SmallPtrSet<const Value *, 16> Visited; 257cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SmallVector<const Value *, 8> WorkList; 258cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar WorkList.push_back(AllocaPtr); 259cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 260cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // A DFS search through all uses of the alloca in bitcasts/PHI/GEPs/etc. 261cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar while (!WorkList.empty()) { 262cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar const Value *V = WorkList.pop_back_val(); 263cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar for (const Use &UI : V->uses()) { 264cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar auto I = cast<const Instruction>(UI.getUser()); 265cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar assert(V == UI.get()); 266cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 267cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar switch (I->getOpcode()) { 268cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar case Instruction::Load: { 269cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!IsAccessSafe(UI, DL->getTypeStoreSize(I->getType()), AllocaPtr, 270cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar AllocaSize)) 271cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return false; 272cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar break; 273cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 274cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar case Instruction::VAArg: 275cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // "va-arg" from a pointer is safe. 276cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar break; 277cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar case Instruction::Store: { 278cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (V == I->getOperand(0)) { 279cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // Stored the pointer - conservatively assume it may be unsafe. 280cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar DEBUG(dbgs() << "[SafeStack] Unsafe alloca: " << *AllocaPtr 281cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar << "\n store of address: " << *I << "\n"); 282cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return false; 283cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 284cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 285cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!IsAccessSafe(UI, DL->getTypeStoreSize(I->getOperand(0)->getType()), 286cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar AllocaPtr, AllocaSize)) 287cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return false; 288cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar break; 289cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 290cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar case Instruction::Ret: { 291cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // Information leak. 292cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return false; 293cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 294cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 295cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar case Instruction::Call: 296cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar case Instruction::Invoke: { 297cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ImmutableCallSite CS(I); 298cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 299cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) { 300cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (II->getIntrinsicID() == Intrinsic::lifetime_start || 301cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar II->getIntrinsicID() == Intrinsic::lifetime_end) 302cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar continue; 303cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 304cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 305cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (const MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I)) { 306cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!IsMemIntrinsicSafe(MI, UI, AllocaPtr, AllocaSize)) { 307cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar DEBUG(dbgs() << "[SafeStack] Unsafe alloca: " << *AllocaPtr 308cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar << "\n unsafe memintrinsic: " << *I 309cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar << "\n"); 310cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return false; 311cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 312cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar continue; 313cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 314cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 315cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // LLVM 'nocapture' attribute is only set for arguments whose address 316cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // is not stored, passed around, or used in any other non-trivial way. 317cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // We assume that passing a pointer to an object as a 'nocapture 318cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // readnone' argument is safe. 319cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // FIXME: a more precise solution would require an interprocedural 320cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // analysis here, which would look at all uses of an argument inside 321cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // the function being called. 322cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ImmutableCallSite::arg_iterator B = CS.arg_begin(), E = CS.arg_end(); 323cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar for (ImmutableCallSite::arg_iterator A = B; A != E; ++A) 324cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (A->get() == V) 325cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!(CS.doesNotCapture(A - B) && (CS.doesNotAccessMemory(A - B) || 326cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar CS.doesNotAccessMemory()))) { 327cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar DEBUG(dbgs() << "[SafeStack] Unsafe alloca: " << *AllocaPtr 328cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar << "\n unsafe call: " << *I << "\n"); 329cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return false; 330cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 331cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar continue; 332cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 333cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 334cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar default: 335cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (Visited.insert(I).second) 336cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar WorkList.push_back(cast<const Instruction>(I)); 337cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 338cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 339cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 340cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 341cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // All uses of the alloca are safe, we can place it on the safe stack. 342cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return true; 343cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar} 344cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 345cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarValue *SafeStack::getOrCreateUnsafeStackPtr(IRBuilder<> &IRB, Function &F) { 346cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // Check if there is a target-specific location for the unsafe stack pointer. 347cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (TL) 348cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (Value *V = TL->getSafeStackPointerLocation(IRB)) 349cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return V; 3506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 351cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // Otherwise, assume the target links with compiler-rt, which provides a 352cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // thread-local variable with a magic name. 353cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Module &M = *F.getParent(); 354cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar const char *UnsafeStackPtrVar = "__safestack_unsafe_stack_ptr"; 3556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar auto UnsafeStackPtr = 356cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar dyn_cast_or_null<GlobalVariable>(M.getNamedValue(UnsafeStackPtrVar)); 357cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 358cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar bool UseTLS = USPStorage == ThreadLocalUSP; 3596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 3606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!UnsafeStackPtr) { 361cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar auto TLSModel = UseTLS ? 362cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar GlobalValue::InitialExecTLSModel : 363cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar GlobalValue::NotThreadLocal; 3646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // The global variable is not defined yet, define it ourselves. 365cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // We use the initial-exec TLS model because we do not support the 366cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // variable living anywhere other than in the main executable. 3676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar UnsafeStackPtr = new GlobalVariable( 368cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar M, StackPtrTy, false, GlobalValue::ExternalLinkage, nullptr, 369cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar UnsafeStackPtrVar, nullptr, TLSModel); 3706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } else { 3716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // The variable exists, check its type and attributes. 372cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (UnsafeStackPtr->getValueType() != StackPtrTy) 373cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar report_fatal_error(Twine(UnsafeStackPtrVar) + " must have void* type"); 374cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (UseTLS != UnsafeStackPtr->isThreadLocal()) 375cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar report_fatal_error(Twine(UnsafeStackPtrVar) + " must " + 376cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar (UseTLS ? "" : "not ") + "be thread-local"); 3776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 3786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return UnsafeStackPtr; 3796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 3806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 3816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid SafeStack::findInsts(Function &F, 3826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SmallVectorImpl<AllocaInst *> &StaticAllocas, 3836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SmallVectorImpl<AllocaInst *> &DynamicAllocas, 384cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SmallVectorImpl<Argument *> &ByValArguments, 3856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SmallVectorImpl<ReturnInst *> &Returns, 3866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SmallVectorImpl<Instruction *> &StackRestorePoints) { 387cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar for (Instruction &I : instructions(&F)) { 3886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (auto AI = dyn_cast<AllocaInst>(&I)) { 3896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ++NumAllocas; 3906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 391cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t Size = getStaticAllocaAllocationSize(AI); 392cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (IsSafeStackAlloca(AI, Size)) 3936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar continue; 3946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 3956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (AI->isStaticAlloca()) { 3966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ++NumUnsafeStaticAllocas; 3976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar StaticAllocas.push_back(AI); 3986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } else { 3996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ++NumUnsafeDynamicAllocas; 4006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DynamicAllocas.push_back(AI); 4016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 4026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } else if (auto RI = dyn_cast<ReturnInst>(&I)) { 4036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Returns.push_back(RI); 4046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } else if (auto CI = dyn_cast<CallInst>(&I)) { 4056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // setjmps require stack restore. 4066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (CI->getCalledFunction() && CI->canReturnTwice()) 4076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar StackRestorePoints.push_back(CI); 4086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } else if (auto LP = dyn_cast<LandingPadInst>(&I)) { 4096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Exception landing pads require stack restore. 4106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar StackRestorePoints.push_back(LP); 4116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } else if (auto II = dyn_cast<IntrinsicInst>(&I)) { 4126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (II->getIntrinsicID() == Intrinsic::gcroot) 4136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar llvm::report_fatal_error( 4146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "gcroot intrinsic not compatible with safestack attribute"); 4156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 4166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 417cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar for (Argument &Arg : F.args()) { 418cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!Arg.hasByValAttr()) 419cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar continue; 420cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t Size = 421cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar DL->getTypeStoreSize(Arg.getType()->getPointerElementType()); 422cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (IsSafeStackAlloca(&Arg, Size)) 423cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar continue; 424cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 425cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ++NumUnsafeByValArguments; 426cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ByValArguments.push_back(&Arg); 427cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 4286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 4296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarAllocaInst * 431cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarSafeStack::createStackRestorePoints(IRBuilder<> &IRB, Function &F, 4326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ArrayRef<Instruction *> StackRestorePoints, 4336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Value *StaticTop, bool NeedDynamicTop) { 4346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (StackRestorePoints.empty()) 4356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return nullptr; 4366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // We need the current value of the shadow stack pointer to restore 4386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // after longjmp or exception catching. 4396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // FIXME: On some platforms this could be handled by the longjmp/exception 4416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // runtime itself. 4426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AllocaInst *DynamicTop = nullptr; 4446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (NeedDynamicTop) 4456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // If we also have dynamic alloca's, the stack pointer value changes 4466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // throughout the function. For now we store it in an alloca. 4476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DynamicTop = IRB.CreateAlloca(StackPtrTy, /*ArraySize=*/nullptr, 4486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "unsafe_stack_dynamic_ptr"); 4496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!StaticTop) 4516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // We need the original unsafe stack pointer value, even if there are 4526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // no unsafe static allocas. 4536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar StaticTop = IRB.CreateLoad(UnsafeStackPtr, false, "unsafe_stack_ptr"); 4546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (NeedDynamicTop) 4566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateStore(StaticTop, DynamicTop); 4576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Restore current stack pointer after longjmp/exception catch. 4596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (Instruction *I : StackRestorePoints) { 4606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ++NumUnsafeStackRestorePoints; 4616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 462cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar IRB.SetInsertPoint(I->getNextNode()); 4636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Value *CurrentTop = DynamicTop ? IRB.CreateLoad(DynamicTop) : StaticTop; 4646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateStore(CurrentTop, UnsafeStackPtr); 4656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 4666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return DynamicTop; 4686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 4696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 470cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarValue *SafeStack::moveStaticAllocasToUnsafeStack( 471cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar IRBuilder<> &IRB, Function &F, ArrayRef<AllocaInst *> StaticAllocas, 472cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ArrayRef<Argument *> ByValArguments, ArrayRef<ReturnInst *> Returns) { 473cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (StaticAllocas.empty() && ByValArguments.empty()) 4746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return nullptr; 4756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DIBuilder DIB(*F.getParent()); 4776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // We explicitly compute and set the unsafe stack layout for all unsafe 4796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // static alloca instructions. We save the unsafe "base pointer" in the 4806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // prologue into a local variable and restore it in the epilogue. 4816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Load the current stack pointer (we'll also use it as a base pointer). 4836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // FIXME: use a dedicated register for it ? 4846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Instruction *BasePointer = 4856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateLoad(UnsafeStackPtr, false, "unsafe_stack_ptr"); 4866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert(BasePointer->getType() == StackPtrTy); 4876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (ReturnInst *RI : Returns) { 4896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.SetInsertPoint(RI); 4906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateStore(BasePointer, UnsafeStackPtr); 4916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 4926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Compute maximum alignment among static objects on the unsafe stack. 4946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned MaxAlignment = 0; 495cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar for (Argument *Arg : ByValArguments) { 496cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Type *Ty = Arg->getType()->getPointerElementType(); 497cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar unsigned Align = std::max((unsigned)DL->getPrefTypeAlignment(Ty), 498cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Arg->getParamAlignment()); 499cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (Align > MaxAlignment) 500cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar MaxAlignment = Align; 501cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 5026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (AllocaInst *AI : StaticAllocas) { 5036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Type *Ty = AI->getAllocatedType(); 5046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned Align = 5056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar std::max((unsigned)DL->getPrefTypeAlignment(Ty), AI->getAlignment()); 5066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Align > MaxAlignment) 5076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MaxAlignment = Align; 5086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 5096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 5106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (MaxAlignment > StackAlignment) { 5116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Re-align the base pointer according to the max requested alignment. 5126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert(isPowerOf2_32(MaxAlignment)); 513cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar IRB.SetInsertPoint(BasePointer->getNextNode()); 5146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar BasePointer = cast<Instruction>(IRB.CreateIntToPtr( 5156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateAnd(IRB.CreatePtrToInt(BasePointer, IntPtrTy), 5166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ConstantInt::get(IntPtrTy, ~uint64_t(MaxAlignment - 1))), 5176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar StackPtrTy)); 5186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 5196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 5206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar int64_t StaticOffset = 0; // Current stack top. 521cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar IRB.SetInsertPoint(BasePointer->getNextNode()); 522cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 523cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar for (Argument *Arg : ByValArguments) { 524cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Type *Ty = Arg->getType()->getPointerElementType(); 525cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 526cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t Size = DL->getTypeStoreSize(Ty); 527cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (Size == 0) 528cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Size = 1; // Don't create zero-sized stack objects. 529cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 530cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // Ensure the object is properly aligned. 531cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar unsigned Align = std::max((unsigned)DL->getPrefTypeAlignment(Ty), 532cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Arg->getParamAlignment()); 533cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 534cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // Add alignment. 535cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // NOTE: we ensure that BasePointer itself is aligned to >= Align. 536cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar StaticOffset += Size; 537cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar StaticOffset = RoundUpToAlignment(StaticOffset, Align); 538cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 539cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Value *Off = IRB.CreateGEP(BasePointer, // BasePointer is i8* 540cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ConstantInt::get(Int32Ty, -StaticOffset)); 541cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Value *NewArg = IRB.CreateBitCast(Off, Arg->getType(), 542cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Arg->getName() + ".unsafe-byval"); 543cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 544cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // Replace alloc with the new location. 545cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar replaceDbgDeclare(Arg, BasePointer, BasePointer->getNextNode(), DIB, 546cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar /*Deref=*/true, -StaticOffset); 547cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Arg->replaceAllUsesWith(NewArg); 548cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar IRB.SetInsertPoint(cast<Instruction>(NewArg)->getNextNode()); 549cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar IRB.CreateMemCpy(Off, Arg, Size, Arg->getParamAlignment()); 550cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 551cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 552cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // Allocate space for every unsafe static AllocaInst on the unsafe stack. 5536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (AllocaInst *AI : StaticAllocas) { 5546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.SetInsertPoint(AI); 5556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 5566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Type *Ty = AI->getAllocatedType(); 557cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t Size = getStaticAllocaAllocationSize(AI); 5586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Size == 0) 5596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Size = 1; // Don't create zero-sized stack objects. 5606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 5616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Ensure the object is properly aligned. 5626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned Align = 5636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar std::max((unsigned)DL->getPrefTypeAlignment(Ty), AI->getAlignment()); 5646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 5656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Add alignment. 5666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // NOTE: we ensure that BasePointer itself is aligned to >= Align. 5676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar StaticOffset += Size; 5686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar StaticOffset = RoundUpToAlignment(StaticOffset, Align); 5696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 5706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Value *Off = IRB.CreateGEP(BasePointer, // BasePointer is i8* 5716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ConstantInt::get(Int32Ty, -StaticOffset)); 5726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Value *NewAI = IRB.CreateBitCast(Off, AI->getType(), AI->getName()); 5736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (AI->hasName() && isa<Instruction>(NewAI)) 5746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar cast<Instruction>(NewAI)->takeName(AI); 5756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 5766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Replace alloc with the new location. 577cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar replaceDbgDeclareForAlloca(AI, BasePointer, DIB, /*Deref=*/true, -StaticOffset); 5786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AI->replaceAllUsesWith(NewAI); 5796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AI->eraseFromParent(); 5806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 5816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 5826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Re-align BasePointer so that our callees would see it aligned as 5836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // expected. 5846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // FIXME: no need to update BasePointer in leaf functions. 5856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar StaticOffset = RoundUpToAlignment(StaticOffset, StackAlignment); 5866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 5876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Update shadow stack pointer in the function epilogue. 588cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar IRB.SetInsertPoint(BasePointer->getNextNode()); 5896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 5906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Value *StaticTop = 5916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateGEP(BasePointer, ConstantInt::get(Int32Ty, -StaticOffset), 5926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar "unsafe_stack_static_top"); 5936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateStore(StaticTop, UnsafeStackPtr); 5946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return StaticTop; 5956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 5966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 5976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid SafeStack::moveDynamicAllocasToUnsafeStack( 5986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Function &F, Value *UnsafeStackPtr, AllocaInst *DynamicTop, 5996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ArrayRef<AllocaInst *> DynamicAllocas) { 6006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DIBuilder DIB(*F.getParent()); 6016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (AllocaInst *AI : DynamicAllocas) { 6036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRBuilder<> IRB(AI); 6046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Compute the new SP value (after AI). 6066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Value *ArraySize = AI->getArraySize(); 6076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (ArraySize->getType() != IntPtrTy) 6086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ArraySize = IRB.CreateIntCast(ArraySize, IntPtrTy, false); 6096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Type *Ty = AI->getAllocatedType(); 6116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint64_t TySize = DL->getTypeAllocSize(Ty); 6126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Value *Size = IRB.CreateMul(ArraySize, ConstantInt::get(IntPtrTy, TySize)); 6136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Value *SP = IRB.CreatePtrToInt(IRB.CreateLoad(UnsafeStackPtr), IntPtrTy); 6156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SP = IRB.CreateSub(SP, Size); 6166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Align the SP value to satisfy the AllocaInst, type and stack alignments. 6186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned Align = std::max( 6196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar std::max((unsigned)DL->getPrefTypeAlignment(Ty), AI->getAlignment()), 6206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar (unsigned)StackAlignment); 6216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert(isPowerOf2_32(Align)); 6236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Value *NewTop = IRB.CreateIntToPtr( 6246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateAnd(SP, ConstantInt::get(IntPtrTy, ~uint64_t(Align - 1))), 6256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar StackPtrTy); 6266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Save the stack pointer. 6286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateStore(NewTop, UnsafeStackPtr); 6296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (DynamicTop) 6306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRB.CreateStore(NewTop, DynamicTop); 6316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 632cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Value *NewAI = IRB.CreatePointerCast(NewTop, AI->getType()); 6336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (AI->hasName() && isa<Instruction>(NewAI)) 6346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar NewAI->takeName(AI); 6356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar replaceDbgDeclareForAlloca(AI, NewAI, DIB, /*Deref=*/true); 6376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AI->replaceAllUsesWith(NewAI); 6386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AI->eraseFromParent(); 6396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 6406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!DynamicAllocas.empty()) { 6426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Now go through the instructions again, replacing stacksave/stackrestore. 6436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (inst_iterator It = inst_begin(&F), Ie = inst_end(&F); It != Ie;) { 6446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Instruction *I = &*(It++); 6456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar auto II = dyn_cast<IntrinsicInst>(I); 6466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!II) 6476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar continue; 6486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (II->getIntrinsicID() == Intrinsic::stacksave) { 6506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRBuilder<> IRB(II); 6516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Instruction *LI = IRB.CreateLoad(UnsafeStackPtr); 6526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar LI->takeName(II); 6536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar II->replaceAllUsesWith(LI); 6546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar II->eraseFromParent(); 6556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } else if (II->getIntrinsicID() == Intrinsic::stackrestore) { 6566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IRBuilder<> IRB(II); 6576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Instruction *SI = IRB.CreateStore(II->getArgOperand(0), UnsafeStackPtr); 6586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SI->takeName(II); 6596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert(II->use_empty()); 6606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar II->eraseFromParent(); 6616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 6626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 6636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 6646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 6656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarbool SafeStack::runOnFunction(Function &F) { 6676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG(dbgs() << "[SafeStack] Function: " << F.getName() << "\n"); 6686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!F.hasFnAttribute(Attribute::SafeStack)) { 6706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG(dbgs() << "[SafeStack] safestack is not requested" 6716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar " for this function\n"); 6726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 6736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 6746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (F.isDeclaration()) { 6766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG(dbgs() << "[SafeStack] function definition" 6776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar " is not available\n"); 6786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 6796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 6806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 681cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar TL = TM ? TM->getSubtargetImpl(F)->getTargetLowering() : nullptr; 682cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE(); 683cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 6846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar { 6856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Make sure the regular stack protector won't run on this function 6866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // (safestack attribute takes precedence). 6876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AttrBuilder B; 6886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar B.addAttribute(Attribute::StackProtect) 6896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addAttribute(Attribute::StackProtectReq) 6906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar .addAttribute(Attribute::StackProtectStrong); 6916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar F.removeAttributes( 6926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AttributeSet::FunctionIndex, 6936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AttributeSet::get(F.getContext(), AttributeSet::FunctionIndex, B)); 6946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 6956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ++NumFunctions; 6976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SmallVector<AllocaInst *, 16> StaticAllocas; 6996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SmallVector<AllocaInst *, 4> DynamicAllocas; 700cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SmallVector<Argument *, 4> ByValArguments; 7016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SmallVector<ReturnInst *, 4> Returns; 7026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 7036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Collect all points where stack gets unwound and needs to be restored 7046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // This is only necessary because the runtime (setjmp and unwind code) is 7056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // not aware of the unsafe stack and won't unwind/restore it prorerly. 7066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // To work around this problem without changing the runtime, we insert 7076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // instrumentation to restore the unsafe stack pointer when necessary. 7086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SmallVector<Instruction *, 4> StackRestorePoints; 7096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 7106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Find all static and dynamic alloca instructions that must be moved to the 7116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // unsafe stack, all return instructions and stack restore points. 712cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar findInsts(F, StaticAllocas, DynamicAllocas, ByValArguments, Returns, 713cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar StackRestorePoints); 7146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 7156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (StaticAllocas.empty() && DynamicAllocas.empty() && 716cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ByValArguments.empty() && StackRestorePoints.empty()) 7176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; // Nothing to do in this function. 7186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 719cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (!StaticAllocas.empty() || !DynamicAllocas.empty() || 720cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar !ByValArguments.empty()) 7216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ++NumUnsafeStackFunctions; // This function has the unsafe stack. 7226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 7236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!StackRestorePoints.empty()) 7246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ++NumUnsafeStackRestorePointsFunctions; 7256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 726cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar IRBuilder<> IRB(&F.front(), F.begin()->getFirstInsertionPt()); 727cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar UnsafeStackPtr = getOrCreateUnsafeStackPtr(IRB, F); 728cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 7296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // The top of the unsafe stack after all unsafe static allocas are allocated. 730cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Value *StaticTop = moveStaticAllocasToUnsafeStack(IRB, F, StaticAllocas, 731cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar ByValArguments, Returns); 7326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 7336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Safe stack object that stores the current unsafe stack top. It is updated 7346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // as unsafe dynamic (non-constant-sized) allocas are allocated and freed. 7356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // This is only needed if we need to restore stack pointer after longjmp 7366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // or exceptions, and we have dynamic allocations. 7376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // FIXME: a better alternative might be to store the unsafe stack pointer 7386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // before setjmp / invoke instructions. 7396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AllocaInst *DynamicTop = createStackRestorePoints( 740cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar IRB, F, StackRestorePoints, StaticTop, !DynamicAllocas.empty()); 7416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 7426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Handle dynamic allocas. 7436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar moveDynamicAllocasToUnsafeStack(F, UnsafeStackPtr, DynamicTop, 7446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DynamicAllocas); 7456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 7466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DEBUG(dbgs() << "[SafeStack] safestack applied\n"); 7476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return true; 7486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 7496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 750cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar} // anonymous namespace 7516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 7526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarchar SafeStack::ID = 0; 753cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarINITIALIZE_TM_PASS_BEGIN(SafeStack, "safe-stack", 754cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar "Safe Stack instrumentation pass", false, false) 755cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarINITIALIZE_TM_PASS_END(SafeStack, "safe-stack", 756cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar "Safe Stack instrumentation pass", false, false) 7576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 758cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarFunctionPass *llvm::createSafeStackPass(const llvm::TargetMachine *TM) { 759cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return new SafeStack(TM); 760cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar} 761