diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2015-10-15 20:50:16 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2015-10-15 20:50:16 +0000 |
commit | 142947e9f0b6f619a1613654d93c5bc56322585a (patch) | |
tree | 63006b4c30d1df5f943f86b6a32dbc59fa8302b9 /llvm/lib/CodeGen/TargetLoweringBase.cpp | |
parent | 945bc50f218290b92adc81129f2b67f6a6dd0f56 (diff) | |
download | bcm5719-llvm-142947e9f0b6f619a1613654d93c5bc56322585a.tar.gz bcm5719-llvm-142947e9f0b6f619a1613654d93c5bc56322585a.zip |
[safestack] Fast access to the unsafe stack pointer on AArch64/Android.
Android libc provides a fixed TLS slot for the unsafe stack pointer,
and this change implements direct access to that slot on AArch64 via
__builtin_thread_pointer() + offset.
This change also moves more code into TargetLowering and its
target-specific subclasses to get rid of target-specific codegen
in SafeStackPass.
This change does not touch the ARM backend because ARM lowers
builting_thread_pointer as aeabi_read_tp, which is not available
on Android.
llvm-svn: 250456
Diffstat (limited to 'llvm/lib/CodeGen/TargetLoweringBase.cpp')
-rw-r--r-- | llvm/lib/CodeGen/TargetLoweringBase.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp index 7250fdc9385..6de59b93331 100644 --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -1662,6 +1662,40 @@ TargetLoweringBase::getTypeLegalizationCost(const DataLayout &DL, } } +Value *TargetLoweringBase::getSafeStackPointerLocation(IRBuilder<> &IRB) const { + Module *M = IRB.GetInsertBlock()->getParent()->getParent(); + Type *StackPtrTy = Type::getInt8PtrTy(M->getContext()); + if (TM.getTargetTriple().getEnvironment() == llvm::Triple::Android) { + // Android provides a libc function to retrieve the address of the current + // thread's unsafe stack pointer. + Value *Fn = M->getOrInsertFunction("__safestack_pointer_address", + StackPtrTy->getPointerTo(0), nullptr); + return IRB.CreateCall(Fn); + } else { + // Otherwise, assume the target links with compiler-rt, which provides a + // thread-local variable with a magic name. + const char *UnsafeStackPtrVar = "__safestack_unsafe_stack_ptr"; + auto UnsafeStackPtr = + dyn_cast_or_null<GlobalVariable>(M->getNamedValue(UnsafeStackPtrVar)); + + 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( + *M, StackPtrTy, false, GlobalValue::ExternalLinkage, 0, + UnsafeStackPtrVar, nullptr, GlobalValue::InitialExecTLSModel); + } 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"); + } + return UnsafeStackPtr; + } +} + //===----------------------------------------------------------------------===// // Loop Strength Reduction hooks //===----------------------------------------------------------------------===// |