summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/TargetLoweringBase.cpp
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2015-10-15 20:50:16 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2015-10-15 20:50:16 +0000
commit142947e9f0b6f619a1613654d93c5bc56322585a (patch)
tree63006b4c30d1df5f943f86b6a32dbc59fa8302b9 /llvm/lib/CodeGen/TargetLoweringBase.cpp
parent945bc50f218290b92adc81129f2b67f6a6dd0f56 (diff)
downloadbcm5719-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.cpp34
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
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud