diff options
| author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2015-12-22 00:13:11 +0000 |
|---|---|---|
| committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2015-12-22 00:13:11 +0000 |
| commit | 8827f2db855054b64a0944b39f8376ac317daf1f (patch) | |
| tree | 730c8b30b5e70262a21a03aa0f4712358f373796 /llvm/lib/Transforms | |
| parent | 5fe0455563a1f15ca5dfdedebd7a4e5b4f4ee610 (diff) | |
| download | bcm5719-llvm-8827f2db855054b64a0944b39f8376ac317daf1f.tar.gz bcm5719-llvm-8827f2db855054b64a0944b39f8376ac317daf1f.zip | |
[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
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Instrumentation/SafeStack.cpp | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/SafeStack.cpp b/llvm/lib/Transforms/Instrumentation/SafeStack.cpp index 4441663fc6d..abed465f102 100644 --- a/llvm/lib/Transforms/Instrumentation/SafeStack.cpp +++ b/llvm/lib/Transforms/Instrumentation/SafeStack.cpp @@ -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; } |

