Fix Clang-tidy modernize-use-nullptr warnings in source directories and generated...
[oota-llvm.git] / lib / Transforms / Instrumentation / SafeStack.cpp
index fdf96cc130a47b5cb89f0ee3c525717d74df2a1a..1b28caffd4a886527fcb439c0f64fb549658d8c5 100644 (file)
@@ -19,6 +19,7 @@
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/CodeGen/Passes.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
@@ -36,6 +37,8 @@
 #include "llvm/Support/Format.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_os_ostream.h"
+#include "llvm/Target/TargetLowering.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
 #include "llvm/Transforms/Utils/Local.h"
 #include "llvm/Transforms/Utils/ModuleUtils.h"
 
@@ -43,6 +46,9 @@ using namespace llvm;
 
 #define DEBUG_TYPE "safestack"
 
+static const char *const kUnsafeStackPtrVar = "__safestack_unsafe_stack_ptr";
+static const char *const kUnsafeStackPtrAddrFn = "__safestack_pointer_address";
+
 namespace llvm {
 
 STATISTIC(NumFunctions, "Total number of functions");
@@ -157,6 +163,8 @@ bool IsSafeStackAlloca(const AllocaInst *AI) {
 /// (as determined statically), and the unsafe stack, which contains all
 /// local variables that are accessed in unsafe ways.
 class SafeStack : public FunctionPass {
+  const TargetMachine *TM;
+  const TargetLoweringBase *TLI;
   const DataLayout *DL;
 
   Type *StackPtrTy;
@@ -164,7 +172,7 @@ class SafeStack : public FunctionPass {
   Type *Int32Ty;
   Type *Int8Ty;
 
-  Constant *UnsafeStackPtr = nullptr;
+  Value *UnsafeStackPtr = nullptr;
 
   /// Unsafe stack alignment. Each stack frame must ensure that the stack is
   /// aligned to this value. We need to re-align the unsafe stack if the
@@ -176,7 +184,7 @@ class SafeStack : public FunctionPass {
 
   /// \brief Build a constant representing a pointer to the unsafe stack
   /// pointer.
-  Constant *getOrCreateUnsafeStackPtr(Module &M);
+  Value *getOrCreateUnsafeStackPtr(IRBuilder<> &IRB, Function &F);
 
   /// \brief Find all static allocas, dynamic allocas, return instructions and
   /// stack restore points (exception unwind blocks and setjmp calls) in the
@@ -192,7 +200,7 @@ class SafeStack : public FunctionPass {
   ///
   /// \returns A pointer to the top of the unsafe stack after all unsafe static
   /// allocas are allocated.
-  Value *moveStaticAllocasToUnsafeStack(Function &F,
+  Value *moveStaticAllocasToUnsafeStack(IRBuilder<> &IRB, Function &F,
                                         ArrayRef<AllocaInst *> StaticAllocas,
                                         ArrayRef<ReturnInst *> Returns);
 
@@ -202,7 +210,7 @@ class SafeStack : public FunctionPass {
   /// \returns A local variable in which to maintain the dynamic top of the
   /// unsafe stack if needed.
   AllocaInst *
-  createStackRestorePoints(Function &F,
+  createStackRestorePoints(IRBuilder<> &IRB, Function &F,
                            ArrayRef<Instruction *> StackRestorePoints,
                            Value *StaticTop, bool NeedDynamicTop);
 
@@ -215,9 +223,11 @@ class SafeStack : public FunctionPass {
 
 public:
   static char ID; // Pass identification, replacement for typeid.
-  SafeStack() : FunctionPass(ID), DL(nullptr) {
+  SafeStack(const TargetMachine *TM)
+      : FunctionPass(ID), TM(TM), TLI(nullptr), DL(nullptr) {
     initializeSafeStackPass(*PassRegistry::getPassRegistry());
   }
+  SafeStack() : SafeStack(nullptr) {}
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.addRequired<AAResultsWrapperPass>();
@@ -237,35 +247,52 @@ public:
   bool runOnFunction(Function &F) override;
 }; // class SafeStack
 
-Constant *SafeStack::getOrCreateUnsafeStackPtr(Module &M) {
-  // The unsafe stack pointer is stored in a global variable with a magic name.
-  const char *kUnsafeStackPtrVar = "__safestack_unsafe_stack_ptr";
-
-  auto UnsafeStackPtr =
-      dyn_cast_or_null<GlobalVariable>(M.getNamedValue(kUnsafeStackPtrVar));
-
-  if (!UnsafeStackPtr) {
-    // The global variable is not defined yet, define it ourselves.
-    // We use the initial-exec TLS model because we do not support the variable
-    // living anywhere other than in the main executable.
-    UnsafeStackPtr = new GlobalVariable(
-        /*Module=*/M, /*Type=*/StackPtrTy,
-        /*isConstant=*/false, /*Linkage=*/GlobalValue::ExternalLinkage,
-        /*Initializer=*/0, /*Name=*/kUnsafeStackPtrVar,
-        /*InsertBefore=*/nullptr,
-        /*ThreadLocalMode=*/GlobalValue::InitialExecTLSModel);
+Value *SafeStack::getOrCreateUnsafeStackPtr(IRBuilder<> &IRB, Function &F) {
+  Module &M = *F.getParent();
+  Triple TargetTriple(M.getTargetTriple());
+
+  unsigned Offset;
+  unsigned AddressSpace;
+  // Check if the target keeps the unsafe stack pointer at a fixed offset.
+  if (TLI && TLI->getSafeStackPointerLocation(AddressSpace, Offset)) {
+    Constant *OffsetVal =
+        ConstantInt::get(Type::getInt32Ty(F.getContext()), Offset);
+    return ConstantExpr::getIntToPtr(OffsetVal,
+                                     StackPtrTy->getPointerTo(AddressSpace));
+  }
+
+  // Android provides a libc function that returns the stack pointer address.
+  if (TargetTriple.getEnvironment() == llvm::Triple::Android) {
+    Value *Fn = M.getOrInsertFunction(kUnsafeStackPtrAddrFn,
+                                      StackPtrTy->getPointerTo(0), nullptr);
+    return IRB.CreateCall(Fn);
   } else {
-    // The variable exists, check its type and attributes.
-    if (UnsafeStackPtr->getValueType() != StackPtrTy) {
-      report_fatal_error(Twine(kUnsafeStackPtrVar) + " must have void* type");
-    }
+    // Otherwise, declare a thread-local variable with a magic name.
+    auto UnsafeStackPtr =
+        dyn_cast_or_null<GlobalVariable>(M.getNamedValue(kUnsafeStackPtrVar));
+
+    if (!UnsafeStackPtr) {
+      // The global variable is not defined yet, define it ourselves.
+      // We use the initial-exec TLS model because we do not support the
+      // variable living anywhere other than in the main executable.
+      UnsafeStackPtr = new GlobalVariable(
+          /*Module=*/M, /*Type=*/StackPtrTy,
+          /*isConstant=*/false, /*Linkage=*/GlobalValue::ExternalLinkage,
+          /*Initializer=*/nullptr, /*Name=*/kUnsafeStackPtrVar,
+          /*InsertBefore=*/nullptr,
+          /*ThreadLocalMode=*/GlobalValue::InitialExecTLSModel);
+    } else {
+      // The variable exists, check its type and attributes.
+      if (UnsafeStackPtr->getValueType() != StackPtrTy) {
+        report_fatal_error(Twine(kUnsafeStackPtrVar) + " must have void* type");
+      }
 
-    if (!UnsafeStackPtr->isThreadLocal()) {
-      report_fatal_error(Twine(kUnsafeStackPtrVar) + " must be thread-local");
+      if (!UnsafeStackPtr->isThreadLocal()) {
+        report_fatal_error(Twine(kUnsafeStackPtrVar) + " must be thread-local");
+      }
     }
+    return UnsafeStackPtr;
   }
-
-  return UnsafeStackPtr;
 }
 
 void SafeStack::findInsts(Function &F,
@@ -305,16 +332,12 @@ void SafeStack::findInsts(Function &F,
 }
 
 AllocaInst *
-SafeStack::createStackRestorePoints(Function &F,
+SafeStack::createStackRestorePoints(IRBuilder<> &IRB, Function &F,
                                     ArrayRef<Instruction *> StackRestorePoints,
                                     Value *StaticTop, bool NeedDynamicTop) {
   if (StackRestorePoints.empty())
     return nullptr;
 
-  IRBuilder<> IRB(StaticTop
-                      ? cast<Instruction>(StaticTop)->getNextNode()
-                      : (Instruction *)F.getEntryBlock().getFirstInsertionPt());
-
   // We need the current value of the shadow stack pointer to restore
   // after longjmp or exception catching.
 
@@ -349,13 +372,12 @@ SafeStack::createStackRestorePoints(Function &F,
 }
 
 Value *
-SafeStack::moveStaticAllocasToUnsafeStack(Function &F,
+SafeStack::moveStaticAllocasToUnsafeStack(IRBuilder<> &IRB, Function &F,
                                           ArrayRef<AllocaInst *> StaticAllocas,
                                           ArrayRef<ReturnInst *> Returns) {
   if (StaticAllocas.empty())
     return nullptr;
 
-  IRBuilder<> IRB(F.getEntryBlock().getFirstInsertionPt());
   DIBuilder DIB(*F.getParent());
 
   // We explicitly compute and set the unsafe stack layout for all unsafe
@@ -421,7 +443,7 @@ SafeStack::moveStaticAllocasToUnsafeStack(Function &F,
       cast<Instruction>(NewAI)->takeName(AI);
 
     // Replace alloc with the new location.
-    replaceDbgDeclareForAlloca(AI, NewAI, DIB, /*Deref=*/true);
+    replaceDbgDeclareForAlloca(AI, BasePointer, DIB, /*Deref=*/true, -StaticOffset);
     AI->replaceAllUsesWith(NewAI);
     AI->eraseFromParent();
   }
@@ -511,8 +533,6 @@ void SafeStack::moveDynamicAllocasToUnsafeStack(
 }
 
 bool SafeStack::runOnFunction(Function &F) {
-  auto AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
-
   DEBUG(dbgs() << "[SafeStack] Function: " << F.getName() << "\n");
 
   if (!F.hasFnAttribute(Attribute::SafeStack)) {
@@ -527,6 +547,10 @@ bool SafeStack::runOnFunction(Function &F) {
     return false;
   }
 
+  auto AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
+
+  TLI = TM ? TM->getSubtargetImpl(F)->getTargetLowering() : nullptr;
+
   {
     // Make sure the regular stack protector won't run on this function
     // (safestack attribute takes precedence).
@@ -572,11 +596,11 @@ bool SafeStack::runOnFunction(Function &F) {
   if (!StackRestorePoints.empty())
     ++NumUnsafeStackRestorePointsFunctions;
 
-  if (!UnsafeStackPtr)
-    UnsafeStackPtr = getOrCreateUnsafeStackPtr(*F.getParent());
+  IRBuilder<> IRB(F.begin()->getFirstInsertionPt());
+  UnsafeStackPtr = getOrCreateUnsafeStackPtr(IRB, F);
 
   // The top of the unsafe stack after all unsafe static allocas are allocated.
-  Value *StaticTop = moveStaticAllocasToUnsafeStack(F, StaticAllocas, Returns);
+  Value *StaticTop = moveStaticAllocasToUnsafeStack(IRB, F, StaticAllocas, Returns);
 
   // Safe stack object that stores the current unsafe stack top. It is updated
   // as unsafe dynamic (non-constant-sized) allocas are allocated and freed.
@@ -585,7 +609,7 @@ bool SafeStack::runOnFunction(Function &F) {
   // FIXME: a better alternative might be to store the unsafe stack pointer
   // before setjmp / invoke instructions.
   AllocaInst *DynamicTop = createStackRestorePoints(
-      F, StackRestorePoints, StaticTop, !DynamicAllocas.empty());
+      IRB, F, StackRestorePoints, StaticTop, !DynamicAllocas.empty());
 
   // Handle dynamic allocas.
   moveDynamicAllocasToUnsafeStack(F, UnsafeStackPtr, DynamicTop,
@@ -595,12 +619,14 @@ bool SafeStack::runOnFunction(Function &F) {
   return true;
 }
 
-} // end anonymous namespace
+} // anonymous namespace
 
 char SafeStack::ID = 0;
-INITIALIZE_PASS_BEGIN(SafeStack, "safe-stack",
-                      "Safe Stack instrumentation pass", false, false)
-INITIALIZE_PASS_END(SafeStack, "safe-stack", "Safe Stack instrumentation pass",
-                    false, false)
+INITIALIZE_TM_PASS_BEGIN(SafeStack, "safe-stack",
+                         "Safe Stack instrumentation pass", false, false)
+INITIALIZE_TM_PASS_END(SafeStack, "safe-stack",
+                       "Safe Stack instrumentation pass", false, false)
 
-FunctionPass *llvm::createSafeStackPass() { return new SafeStack(); }
+FunctionPass *llvm::createSafeStackPass(const llvm::TargetMachine *TM) {
+  return new SafeStack(TM);
+}