forked from OSchip/llvm-project
Revert "[safestack] Fast access to the unsafe stack pointer on AArch64/Android."
Breaks the hexagon buildbot. llvm-svn: 250461
This commit is contained in:
parent
8f865a41fb
commit
9addbc9fc1
|
@ -995,9 +995,13 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
/// If the target has a standard location for the unsafe stack pointer,
|
||||
/// returns the address of that location. Otherwise, returns nullptr.
|
||||
virtual Value *getSafeStackPointerLocation(IRBuilder<> &IRB) const;
|
||||
/// Return true if the target stores SafeStack pointer at a fixed offset in
|
||||
/// some non-standard address space, and populates the address space and
|
||||
/// offset as appropriate.
|
||||
virtual bool getSafeStackPointerLocation(unsigned & /*AddressSpace*/,
|
||||
unsigned & /*Offset*/) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Returns true if a cast between SrcAS and DestAS is a noop.
|
||||
virtual bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const {
|
||||
|
|
|
@ -1662,40 +1662,6 @@ 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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -9921,19 +9921,3 @@ bool AArch64TargetLowering::shouldNormalizeToSelectSequence(LLVMContext &,
|
|||
EVT) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
Value *AArch64TargetLowering::getSafeStackPointerLocation(IRBuilder<> &IRB) const {
|
||||
if (!Subtarget->isTargetAndroid())
|
||||
return TargetLowering::getSafeStackPointerLocation(IRB);
|
||||
|
||||
// Android provides a fixed TLS slot for the SafeStack pointer. See the
|
||||
// definition of TLS_SLOT_SAFESTACK in
|
||||
// https://android.googlesource.com/platform/bionic/+/master/libc/private/bionic_tls.h
|
||||
const unsigned TlsOffset = 0x48;
|
||||
Module *M = IRB.GetInsertBlock()->getParent()->getParent();
|
||||
Function *ThreadPointerFunc =
|
||||
Intrinsic::getDeclaration(M, Intrinsic::aarch64_thread_pointer);
|
||||
return IRB.CreatePointerCast(
|
||||
IRB.CreateConstGEP1_32(IRB.CreateCall(ThreadPointerFunc), TlsOffset),
|
||||
Type::getInt8PtrTy(IRB.getContext())->getPointerTo(0));
|
||||
}
|
||||
|
|
|
@ -362,10 +362,6 @@ public:
|
|||
TargetLoweringBase::LegalizeTypeAction
|
||||
getPreferredVectorAction(EVT VT) const override;
|
||||
|
||||
/// If the target has a standard location for the unsafe stack pointer,
|
||||
/// returns the address of that location. Otherwise, returns nullptr.
|
||||
Value *getSafeStackPointerLocation(IRBuilder<> &IRB) const override;
|
||||
|
||||
private:
|
||||
bool isExtFreeImpl(const Instruction *Ext) const override;
|
||||
|
||||
|
|
|
@ -2086,14 +2086,14 @@ bool X86TargetLowering::getStackCookieLocation(unsigned &AddressSpace,
|
|||
return true;
|
||||
}
|
||||
|
||||
Value *X86TargetLowering::getSafeStackPointerLocation(IRBuilder<> &IRB) const {
|
||||
/// Android provides a fixed TLS slot for the SafeStack pointer.
|
||||
/// See the definition of TLS_SLOT_SAFESTACK in
|
||||
/// https://android.googlesource.com/platform/bionic/+/master/libc/private/bionic_tls.h
|
||||
bool X86TargetLowering::getSafeStackPointerLocation(unsigned &AddressSpace,
|
||||
unsigned &Offset) const {
|
||||
if (!Subtarget->isTargetAndroid())
|
||||
return TargetLowering::getSafeStackPointerLocation(IRB);
|
||||
return false;
|
||||
|
||||
// Android provides a fixed TLS slot for the SafeStack pointer. See the
|
||||
// definition of TLS_SLOT_SAFESTACK in
|
||||
// https://android.googlesource.com/platform/bionic/+/master/libc/private/bionic_tls.h
|
||||
unsigned AddressSpace, Offset;
|
||||
if (Subtarget->is64Bit()) {
|
||||
// %fs:0x48, unless we're using a Kernel code model, in which case it's %gs:
|
||||
Offset = 0x48;
|
||||
|
@ -2106,10 +2106,7 @@ Value *X86TargetLowering::getSafeStackPointerLocation(IRBuilder<> &IRB) const {
|
|||
Offset = 0x24;
|
||||
AddressSpace = 256;
|
||||
}
|
||||
|
||||
return ConstantExpr::getIntToPtr(
|
||||
ConstantInt::get(Type::getInt32Ty(IRB.getContext()), Offset),
|
||||
Type::getInt8PtrTy(IRB.getContext())->getPointerTo(AddressSpace));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool X86TargetLowering::isNoopAddrSpaceCast(unsigned SrcAS,
|
||||
|
|
|
@ -901,7 +901,8 @@ namespace llvm {
|
|||
/// Return true if the target stores SafeStack pointer at a fixed offset in
|
||||
/// some non-standard address space, and populates the address space and
|
||||
/// offset as appropriate.
|
||||
Value *getSafeStackPointerLocation(IRBuilder<> &IRB) const override;
|
||||
bool getSafeStackPointerLocation(unsigned &AddressSpace,
|
||||
unsigned &Offset) const override;
|
||||
|
||||
SDValue BuildFILD(SDValue Op, EVT SrcVT, SDValue Chain, SDValue StackSlot,
|
||||
SelectionDAG &DAG) const;
|
||||
|
|
|
@ -46,6 +46,9 @@ using namespace llvm;
|
|||
|
||||
#define DEBUG_TYPE "safestack"
|
||||
|
||||
static const char *const kUnsafeStackPtrVar = "__safestack_unsafe_stack_ptr";
|
||||
static const char *const kUnsafeStackPtrAddrFn = "__safestack_pointer_address";
|
||||
|
||||
namespace llvm {
|
||||
|
||||
STATISTIC(NumFunctions, "Total number of functions");
|
||||
|
@ -179,6 +182,10 @@ class SafeStack : public FunctionPass {
|
|||
/// might expect to appear on the stack on most common targets.
|
||||
enum { StackAlignment = 16 };
|
||||
|
||||
/// \brief Build a constant representing a pointer to the unsafe stack
|
||||
/// pointer.
|
||||
Value *getOrCreateUnsafeStackPtr(IRBuilder<> &IRB, Function &F);
|
||||
|
||||
/// \brief Find all static allocas, dynamic allocas, return instructions and
|
||||
/// stack restore points (exception unwind blocks and setjmp calls) in the
|
||||
/// given function and append them to the respective vectors.
|
||||
|
@ -240,6 +247,54 @@ public:
|
|||
bool runOnFunction(Function &F) override;
|
||||
}; // class SafeStack
|
||||
|
||||
Value *SafeStack::getOrCreateUnsafeStackPtr(IRBuilder<> &IRB, Function &F) {
|
||||
Module &M = *F.getParent();
|
||||
Triple TargetTriple(M.getTargetTriple());
|
||||
|
||||
unsigned Offset;
|
||||
unsigned AddressSpace;
|
||||
// Check if the target keeps the unsafe stack pointer at a fixed offset.
|
||||
if (TLI && TLI->getSafeStackPointerLocation(AddressSpace, Offset)) {
|
||||
Constant *OffsetVal =
|
||||
ConstantInt::get(Type::getInt32Ty(F.getContext()), Offset);
|
||||
return ConstantExpr::getIntToPtr(OffsetVal,
|
||||
StackPtrTy->getPointerTo(AddressSpace));
|
||||
}
|
||||
|
||||
// Android provides a libc function that returns the stack pointer address.
|
||||
if (TargetTriple.isAndroid()) {
|
||||
Value *Fn = M.getOrInsertFunction(kUnsafeStackPtrAddrFn,
|
||||
StackPtrTy->getPointerTo(0), nullptr);
|
||||
return IRB.CreateCall(Fn);
|
||||
} else {
|
||||
// Otherwise, declare a thread-local variable with a magic name.
|
||||
auto UnsafeStackPtr =
|
||||
dyn_cast_or_null<GlobalVariable>(M.getNamedValue(kUnsafeStackPtrVar));
|
||||
|
||||
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(
|
||||
/*Module=*/M, /*Type=*/StackPtrTy,
|
||||
/*isConstant=*/false, /*Linkage=*/GlobalValue::ExternalLinkage,
|
||||
/*Initializer=*/nullptr, /*Name=*/kUnsafeStackPtrVar,
|
||||
/*InsertBefore=*/nullptr,
|
||||
/*ThreadLocalMode=*/GlobalValue::InitialExecTLSModel);
|
||||
} else {
|
||||
// The variable exists, check its type and attributes.
|
||||
if (UnsafeStackPtr->getValueType() != StackPtrTy) {
|
||||
report_fatal_error(Twine(kUnsafeStackPtrVar) + " must have void* type");
|
||||
}
|
||||
|
||||
if (!UnsafeStackPtr->isThreadLocal()) {
|
||||
report_fatal_error(Twine(kUnsafeStackPtrVar) + " must be thread-local");
|
||||
}
|
||||
}
|
||||
return UnsafeStackPtr;
|
||||
}
|
||||
}
|
||||
|
||||
void SafeStack::findInsts(Function &F,
|
||||
SmallVectorImpl<AllocaInst *> &StaticAllocas,
|
||||
SmallVectorImpl<AllocaInst *> &DynamicAllocas,
|
||||
|
@ -542,7 +597,7 @@ bool SafeStack::runOnFunction(Function &F) {
|
|||
++NumUnsafeStackRestorePointsFunctions;
|
||||
|
||||
IRBuilder<> IRB(&F.front(), F.begin()->getFirstInsertionPt());
|
||||
UnsafeStackPtr = TLI->getSafeStackPointerLocation(IRB);
|
||||
UnsafeStackPtr = getOrCreateUnsafeStackPtr(IRB, F);
|
||||
|
||||
// The top of the unsafe stack after all unsafe static allocas are allocated.
|
||||
Value *StaticTop = moveStaticAllocasToUnsafeStack(IRB, F, StaticAllocas, Returns);
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
|
||||
define void @foo() nounwind uwtable safestack {
|
||||
entry:
|
||||
; CHECK: %[[TP:.*]] = call i8* @llvm.aarch64.thread.pointer()
|
||||
; CHECK: %[[SPA0:.*]] = getelementptr i8, i8* %[[TP]], i32 72
|
||||
; CHECK: %[[SPA:.*]] = bitcast i8* %[[SPA0]] to i8**
|
||||
; CHECK: %[[SPA:.*]] = call i8** @__safestack_pointer_address()
|
||||
; CHECK: %[[USP:.*]] = load i8*, i8** %[[SPA]]
|
||||
; CHECK: %[[USST:.*]] = getelementptr i8, i8* %[[USP]], i32 -16
|
||||
; CHECK: store i8* %[[USST]], i8** %[[SPA]]
|
||||
|
|
Loading…
Reference in New Issue