diff options
| author | David L Kreitzer <david.l.kreitzer@intel.com> | 2016-10-14 17:56:00 +0000 | 
|---|---|---|
| committer | David L Kreitzer <david.l.kreitzer@intel.com> | 2016-10-14 17:56:00 +0000 | 
| commit | d5c6755d83b34e663b6fbe497b52bcc73b55199a (patch) | |
| tree | 21b9853a1f2b81e2bab1d32aef4524069cbfc665 /llvm | |
| parent | 1deab387170a0877485e9aca7461acac79b33be3 (diff) | |
| download | bcm5719-llvm-d5c6755d83b34e663b6fbe497b52bcc73b55199a.tar.gz bcm5719-llvm-d5c6755d83b34e663b6fbe497b52bcc73b55199a.zip  | |
[safestack] Use non-thread-local unsafe stack pointer for Contiki OS
Patch by Michael LeMay
Differential revision: http://reviews.llvm.org/D19852
llvm-svn: 284254
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/Target/TargetLowering.h | 8 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SafeStack.cpp | 50 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/TargetLoweringBase.cpp | 34 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 3 | ||||
| -rw-r--r-- | llvm/test/Transforms/SafeStack/X86/array.ll | 3 | 
5 files changed, 44 insertions, 54 deletions
diff --git a/llvm/include/llvm/Target/TargetLowering.h b/llvm/include/llvm/Target/TargetLowering.h index 741c2f7c21e..f1f982baba4 100644 --- a/llvm/include/llvm/Target/TargetLowering.h +++ b/llvm/include/llvm/Target/TargetLowering.h @@ -1114,8 +1114,12 @@ public:    /// Should be used only when getIRStackGuard returns nullptr.    virtual Value *getSSPStackGuardCheck(const Module &M) const; -  /// If the target has a standard location for the unsafe stack pointer, -  /// returns the address of that location. Otherwise, returns nullptr. +protected: +  Value *getDefaultSafeStackPointerLocation(IRBuilder<> &IRB, +                                            bool UseTLS) const; + +public: +  /// Returns the target-specific address of the unsafe stack pointer.    virtual Value *getSafeStackPointerLocation(IRBuilder<> &IRB) const;    /// Returns true if a cast between SrcAS and DestAS is a noop. diff --git a/llvm/lib/CodeGen/SafeStack.cpp b/llvm/lib/CodeGen/SafeStack.cpp index ed3fa8cd6ad..43f7b301a08 100644 --- a/llvm/lib/CodeGen/SafeStack.cpp +++ b/llvm/lib/CodeGen/SafeStack.cpp @@ -52,16 +52,6 @@ using namespace llvm::safestack;  #define DEBUG_TYPE "safestack" -enum UnsafeStackPtrStorageVal { ThreadLocalUSP, SingleThreadUSP }; - -static cl::opt<UnsafeStackPtrStorageVal> USPStorage("safe-stack-usp-storage", -    cl::Hidden, cl::init(ThreadLocalUSP), -    cl::desc("Type of storage for the unsafe stack pointer"), -    cl::values(clEnumValN(ThreadLocalUSP, "thread-local", -                          "Thread-local storage"), -               clEnumValN(SingleThreadUSP, "single-thread", -                          "Non-thread-local storage"))); -  namespace llvm {  STATISTIC(NumFunctions, "Total number of functions"); @@ -123,9 +113,6 @@ class SafeStack : public FunctionPass {    /// might expect to appear on the stack on most common targets.    enum { StackAlignment = 16 }; -  /// \brief Build a value representing a pointer to the unsafe stack pointer. -  Value *getOrCreateUnsafeStackPtr(IRBuilder<> &IRB, Function &F); -    /// \brief Return the value of the stack canary.    Value *getStackGuard(IRBuilder<> &IRB, Function &F); @@ -355,41 +342,6 @@ bool SafeStack::IsSafeStackAlloca(const Value *AllocaPtr, uint64_t AllocaSize) {    return true;  } -Value *SafeStack::getOrCreateUnsafeStackPtr(IRBuilder<> &IRB, Function &F) { -  // Check if there is a target-specific location for the unsafe stack pointer. -  if (Value *V = TL->getSafeStackPointerLocation(IRB)) -    return V; - -  // Otherwise, assume the target links with compiler-rt, which provides a -  // thread-local variable with a magic name. -  Module &M = *F.getParent(); -  const char *UnsafeStackPtrVar = "__safestack_unsafe_stack_ptr"; -  auto UnsafeStackPtr = -      dyn_cast_or_null<GlobalVariable>(M.getNamedValue(UnsafeStackPtrVar)); - -  bool UseTLS = USPStorage == ThreadLocalUSP; - -  if (!UnsafeStackPtr) { -    auto TLSModel = UseTLS ? -        GlobalValue::InitialExecTLSModel : -        GlobalValue::NotThreadLocal; -    // 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( -        M, StackPtrTy, false, GlobalValue::ExternalLinkage, nullptr, -        UnsafeStackPtrVar, nullptr, TLSModel); -  } else { -    // The variable exists, check its type and attributes. -    if (UnsafeStackPtr->getValueType() != StackPtrTy) -      report_fatal_error(Twine(UnsafeStackPtrVar) + " must have void* type"); -    if (UseTLS != UnsafeStackPtr->isThreadLocal()) -      report_fatal_error(Twine(UnsafeStackPtrVar) + " must " + -                         (UseTLS ? "" : "not ") + "be thread-local"); -  } -  return UnsafeStackPtr; -} -  Value *SafeStack::getStackGuard(IRBuilder<> &IRB, Function &F) {    Value *StackGuardVar = TL->getIRStackGuard(IRB);    if (!StackGuardVar) @@ -784,7 +736,7 @@ bool SafeStack::runOnFunction(Function &F) {      ++NumUnsafeStackRestorePointsFunctions;    IRBuilder<> IRB(&F.front(), F.begin()->getFirstInsertionPt()); -  UnsafeStackPtr = getOrCreateUnsafeStackPtr(IRB, F); +  UnsafeStackPtr = TL->getSafeStackPointerLocation(IRB);    // Load the current stack pointer (we'll also use it as a base pointer).    // FIXME: use a dedicated register for it ? diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp index 187aa95d769..f62e74ad398 100644 --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -1767,9 +1767,41 @@ TargetLoweringBase::getTypeLegalizationCost(const DataLayout &DL,    }  } +Value *TargetLoweringBase::getDefaultSafeStackPointerLocation(IRBuilder<> &IRB, +                                                              bool UseTLS) const { +  // compiler-rt provides a variable with a magic name.  Targets that do not +  // link with compiler-rt may also provide such a variable. +  Module *M = IRB.GetInsertBlock()->getParent()->getParent(); +  const char *UnsafeStackPtrVar = "__safestack_unsafe_stack_ptr"; +  auto UnsafeStackPtr = +      dyn_cast_or_null<GlobalVariable>(M->getNamedValue(UnsafeStackPtrVar)); + +  Type *StackPtrTy = Type::getInt8PtrTy(M->getContext()); + +  if (!UnsafeStackPtr) { +    auto TLSModel = UseTLS ? +        GlobalValue::InitialExecTLSModel : +        GlobalValue::NotThreadLocal; +    // 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( +        *M, StackPtrTy, false, GlobalValue::ExternalLinkage, nullptr, +        UnsafeStackPtrVar, nullptr, TLSModel); +  } else { +    // The variable exists, check its type and attributes. +    if (UnsafeStackPtr->getValueType() != StackPtrTy) +      report_fatal_error(Twine(UnsafeStackPtrVar) + " must have void* type"); +    if (UseTLS != UnsafeStackPtr->isThreadLocal()) +      report_fatal_error(Twine(UnsafeStackPtrVar) + " must " + +                         (UseTLS ? "" : "not ") + "be thread-local"); +  } +  return UnsafeStackPtr; +} +  Value *TargetLoweringBase::getSafeStackPointerLocation(IRBuilder<> &IRB) const {    if (!TM.getTargetTriple().isAndroid()) -    return nullptr; +    return getDefaultSafeStackPointerLocation(IRB, true);    // Android provides a libc function to retrieve the address of the current    // thread's unsafe stack pointer. diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index db68237eecb..7119504ec28 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -2045,6 +2045,9 @@ Value *X86TargetLowering::getSSPStackGuardCheck(const Module &M) const {  }  Value *X86TargetLowering::getSafeStackPointerLocation(IRBuilder<> &IRB) const { +  if (Subtarget.getTargetTriple().isOSContiki()) +    return getDefaultSafeStackPointerLocation(IRB, false); +    if (!Subtarget.isTargetAndroid())      return TargetLowering::getSafeStackPointerLocation(IRB); diff --git a/llvm/test/Transforms/SafeStack/X86/array.ll b/llvm/test/Transforms/SafeStack/X86/array.ll index 7dcf7fa50d9..b6993523223 100644 --- a/llvm/test/Transforms/SafeStack/X86/array.ll +++ b/llvm/test/Transforms/SafeStack/X86/array.ll @@ -1,7 +1,6 @@  ; RUN: opt -safe-stack -S -mtriple=i386-pc-linux-gnu < %s -o - | FileCheck %s -; RUN: opt -safe-stack -safe-stack-usp-storage=single-thread -S -mtriple=i386-pc-linux-gnu < %s -o - | FileCheck -check-prefix=SINGLE-THREAD %s +; RUN: opt -safe-stack -S -mtriple=i386-pc-contiki-unknown < %s -o - | FileCheck -check-prefix=SINGLE-THREAD %s  ; RUN: opt -safe-stack -S -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck %s -; RUN: opt -safe-stack -safe-stack-usp-storage=single-thread -S -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck -check-prefix=SINGLE-THREAD %s  ; array [4 x i8]  ; Requires protector.  | 

