mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[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
This commit is contained in:
parent
259a7b3aba
commit
d68b19752a
@ -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.
|
||||
|
@ -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 ?
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user