forked from OSchip/llvm-project
[safestack] Add option for non-TLS unsafe stack pointer.
This patch adds an option, -safe-stack-no-tls, for using normal storage instead of thread-local storage for the unsafe stack pointer. This can be useful when SafeStack is applied to an operating system kernel. http://reviews.llvm.org/D15673 Patch by Michael LeMay. llvm-svn: 256221
This commit is contained in:
parent
5fe0455563
commit
8827f2db85
|
@ -47,6 +47,17 @@ using namespace llvm;
|
|||
|
||||
#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"),
|
||||
clEnumValEnd));
|
||||
|
||||
namespace llvm {
|
||||
|
||||
STATISTIC(NumFunctions, "Total number of functions");
|
||||
|
@ -344,19 +355,25 @@ Value *SafeStack::getOrCreateUnsafeStackPtr(IRBuilder<> &IRB, Function &F) {
|
|||
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, GlobalValue::InitialExecTLSModel);
|
||||
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 (!UnsafeStackPtr->isThreadLocal())
|
||||
report_fatal_error(Twine(UnsafeStackPtrVar) + " must be thread-local");
|
||||
if (UseTLS != UnsafeStackPtr->isThreadLocal())
|
||||
report_fatal_error(Twine(UnsafeStackPtrVar) + " must " +
|
||||
(UseTLS ? "" : "not ") + "be thread-local");
|
||||
}
|
||||
return UnsafeStackPtr;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
; 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=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.
|
||||
|
||||
; CHECK: @__safestack_unsafe_stack_ptr = external thread_local(initialexec) global i8*
|
||||
; SINGLE-THREAD: @__safestack_unsafe_stack_ptr = external global i8*
|
||||
|
||||
define void @foo(i8* %a) nounwind uwtable safestack {
|
||||
entry:
|
||||
; CHECK: %[[USP:.*]] = load i8*, i8** @__safestack_unsafe_stack_ptr
|
||||
|
|
Loading…
Reference in New Issue