mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-02 00:16:25 +00:00
Faster stack-protector for Android/AArch64.
Bionic has a defined thread-local location for the stack protector cookie. Emit a direct load instead of going through __stack_chk_guard. llvm-svn: 265481
This commit is contained in:
parent
d8f96bea63
commit
c80f414fe8
@ -1011,12 +1011,10 @@ public:
|
||||
return PrefLoopAlignment;
|
||||
}
|
||||
|
||||
/// Return true if the target stores stack protector cookies at a fixed offset
|
||||
/// in some non-standard address space, and populates the address space and
|
||||
/// offset as appropriate.
|
||||
virtual bool getStackCookieLocation(unsigned &/*AddressSpace*/,
|
||||
unsigned &/*Offset*/) const {
|
||||
return false;
|
||||
/// If the target has a standard location for the stack protector cookie,
|
||||
/// returns the address of that location. Otherwise, returns nullptr.
|
||||
virtual Value *getStackCookieLocation(IRBuilder<> &IRB) const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// If the target has a standard location for the unsafe stack pointer,
|
||||
|
@ -333,24 +333,20 @@ static bool CreatePrologue(Function *F, Module *M, ReturnInst *RI,
|
||||
AllocaInst *&AI, Value *&StackGuardVar) {
|
||||
bool SupportsSelectionDAGSP = false;
|
||||
PointerType *PtrTy = Type::getInt8PtrTy(RI->getContext());
|
||||
unsigned AddressSpace, Offset;
|
||||
if (TLI->getStackCookieLocation(AddressSpace, Offset)) {
|
||||
Constant *OffsetVal =
|
||||
ConstantInt::get(Type::getInt32Ty(RI->getContext()), Offset);
|
||||
IRBuilder<> B(&F->getEntryBlock().front());
|
||||
|
||||
StackGuardVar =
|
||||
ConstantExpr::getIntToPtr(OffsetVal, PointerType::get(PtrTy,
|
||||
AddressSpace));
|
||||
} else if (TT.isOSOpenBSD()) {
|
||||
StackGuardVar = M->getOrInsertGlobal("__guard_local", PtrTy);
|
||||
cast<GlobalValue>(StackGuardVar)
|
||||
->setVisibility(GlobalValue::HiddenVisibility);
|
||||
} else {
|
||||
SupportsSelectionDAGSP = true;
|
||||
StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy);
|
||||
StackGuardVar = TLI->getStackCookieLocation(B);
|
||||
if (!StackGuardVar) {
|
||||
if (TT.isOSOpenBSD()) {
|
||||
StackGuardVar = M->getOrInsertGlobal("__guard_local", PtrTy);
|
||||
cast<GlobalValue>(StackGuardVar)
|
||||
->setVisibility(GlobalValue::HiddenVisibility);
|
||||
} else {
|
||||
SupportsSelectionDAGSP = true;
|
||||
StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy);
|
||||
}
|
||||
}
|
||||
|
||||
IRBuilder<> B(&F->getEntryBlock().front());
|
||||
AI = B.CreateAlloca(PtrTy, nullptr, "StackGuardSlot");
|
||||
LoadInst *LI = B.CreateLoad(StackGuardVar, "StackGuard");
|
||||
B.CreateCall(Intrinsic::getDeclaration(M, Intrinsic::stackprotector),
|
||||
|
@ -10212,6 +10212,22 @@ bool AArch64TargetLowering::shouldNormalizeToSelectSequence(LLVMContext &,
|
||||
return false;
|
||||
}
|
||||
|
||||
Value *AArch64TargetLowering::getStackCookieLocation(IRBuilder<> &IRB) const {
|
||||
if (!Subtarget->isTargetAndroid())
|
||||
return TargetLowering::getStackCookieLocation(IRB);
|
||||
|
||||
// Android provides a fixed TLS slot for the stack cookie. See the definition
|
||||
// of TLS_SLOT_STACK_GUARD in
|
||||
// https://android.googlesource.com/platform/bionic/+/master/libc/private/bionic_tls.h
|
||||
const unsigned TlsOffset = 0x28;
|
||||
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));
|
||||
}
|
||||
|
||||
Value *AArch64TargetLowering::getSafeStackPointerLocation(IRBuilder<> &IRB) const {
|
||||
if (!Subtarget->isTargetAndroid())
|
||||
return TargetLowering::getSafeStackPointerLocation(IRB);
|
||||
|
@ -358,6 +358,10 @@ public:
|
||||
TargetLoweringBase::LegalizeTypeAction
|
||||
getPreferredVectorAction(EVT VT) const override;
|
||||
|
||||
/// If the target has a standard location for the stack protector cookie,
|
||||
/// returns the address of that location. Otherwise, returns nullptr.
|
||||
Value *getStackCookieLocation(IRBuilder<> &IRB) 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;
|
||||
|
@ -2193,16 +2193,17 @@ unsigned X86TargetLowering::getAddressSpace() const {
|
||||
return 256;
|
||||
}
|
||||
|
||||
bool X86TargetLowering::getStackCookieLocation(unsigned &AddressSpace,
|
||||
unsigned &Offset) const {
|
||||
Value *X86TargetLowering::getStackCookieLocation(IRBuilder<> &IRB) const {
|
||||
if (!Subtarget.isTargetLinux())
|
||||
return false;
|
||||
return TargetLowering::getStackCookieLocation(IRB);
|
||||
|
||||
// %fs:0x28, unless we're using a Kernel code model, in which case it's %gs:
|
||||
// %gs:0x14 on i386
|
||||
Offset = (Subtarget.is64Bit()) ? 0x28 : 0x14;
|
||||
AddressSpace = getAddressSpace();
|
||||
return true;
|
||||
unsigned Offset = (Subtarget.is64Bit()) ? 0x28 : 0x14;
|
||||
unsigned AddressSpace = getAddressSpace();
|
||||
return ConstantExpr::getIntToPtr(
|
||||
ConstantInt::get(Type::getInt32Ty(IRB.getContext()), Offset),
|
||||
Type::getInt8PtrTy(IRB.getContext())->getPointerTo(AddressSpace));
|
||||
}
|
||||
|
||||
Value *X86TargetLowering::getSafeStackPointerLocation(IRBuilder<> &IRB) const {
|
||||
|
@ -960,11 +960,9 @@ namespace llvm {
|
||||
FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
|
||||
const TargetLibraryInfo *libInfo) const override;
|
||||
|
||||
/// Return true if the target stores stack protector cookies at a fixed
|
||||
/// offset in some non-standard address space, and populates the address
|
||||
/// space and offset as appropriate.
|
||||
bool getStackCookieLocation(unsigned &AddressSpace,
|
||||
unsigned &Offset) const override;
|
||||
/// If the target has a standard location for the stack protector cookie,
|
||||
/// returns the address of that location. Otherwise, returns nullptr.
|
||||
Value *getStackCookieLocation(IRBuilder<> &IRB) const override;
|
||||
|
||||
/// Return true if the target stores SafeStack pointer at a fixed offset in
|
||||
/// some non-standard address space, and populates the address space and
|
||||
|
19
test/CodeGen/AArch64/stack-protector-target.ll
Normal file
19
test/CodeGen/AArch64/stack-protector-target.ll
Normal file
@ -0,0 +1,19 @@
|
||||
; Test target-specific stack cookie location.
|
||||
; RUN: llc -mtriple=aarch64-linux-android < %s -o - | FileCheck --check-prefix=ANDROID-AARCH64 %s
|
||||
|
||||
define void @_Z1fv() sspreq {
|
||||
entry:
|
||||
%x = alloca i32, align 4
|
||||
%0 = bitcast i32* %x to i8*
|
||||
call void @_Z7CapturePi(i32* nonnull %x)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @_Z7CapturePi(i32*)
|
||||
|
||||
; ANDROID-AARCH64: mrs [[A:.*]], TPIDR_EL0
|
||||
; ANDROID-AARCH64: ldr [[B:.*]], {{\[}}[[A]], #40]
|
||||
; ANDROID-AARCH64: str [[B]], [sp,
|
||||
; ANDROID-AARCH64: ldr [[C:.*]], {{\[}}[[A]], #40]
|
||||
; ANDROID-AARCH64: ldr [[D:.*]], [sp,
|
||||
; ANDROID-AARCH64: cmp [[C]], [[D]]
|
25
test/CodeGen/X86/stack-protector-target.ll
Normal file
25
test/CodeGen/X86/stack-protector-target.ll
Normal file
@ -0,0 +1,25 @@
|
||||
; Test target-specific stack cookie location.
|
||||
; RUN: llc -mtriple=i386-linux < %s -o - | FileCheck --check-prefix=LINUX-I386 %s
|
||||
; RUN: llc -mtriple=x86_64-linux < %s -o - | FileCheck --check-prefix=LINUX-X64 %s
|
||||
; RUN: llc -mtriple=i386-linux-android < %s -o - | FileCheck --check-prefix=LINUX-I386 %s
|
||||
; RUN: llc -mtriple=x86_64-linux-android < %s -o - | FileCheck --check-prefix=LINUX-X64 %s
|
||||
|
||||
define void @_Z1fv() sspreq {
|
||||
entry:
|
||||
%x = alloca i32, align 4
|
||||
%0 = bitcast i32* %x to i8*
|
||||
call void @_Z7CapturePi(i32* nonnull %x)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @_Z7CapturePi(i32*)
|
||||
|
||||
; LINUX-X64: movq %fs:40, %[[B:.*]]
|
||||
; LINUX-X64: movq %[[B]], 16(%rsp)
|
||||
; LINUX-X64: movq %fs:40, %[[C:.*]]
|
||||
; LINUX-X64: cmpq 16(%rsp), %[[C]]
|
||||
|
||||
; LINUX-I386: movl %gs:20, %[[B:.*]]
|
||||
; LINUX-I386: movl %[[B]], 8(%esp)
|
||||
; LINUX-I386: movl %gs:20, %[[C:.*]]
|
||||
; LINUX-I386: cmpl 8(%esp), %[[C]]
|
Loading…
Reference in New Issue
Block a user