mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-12 05:56:28 +00:00
[Fuchsia] Use thread-pointer ABI slots for stack-protector and safe-stack
The Fuchsia ABI defines slots from the thread pointer where the stack-guard value for stack-protector, and the unsafe stack pointer for safe-stack, are stored. This parallels the Android ABI support. Patch by Roland McGrath Differential Revision: https://reviews.llvm.org/D30237 llvm-svn: 296081
This commit is contained in:
parent
ae591c71b4
commit
ea0c98b8f9
@ -10470,9 +10470,9 @@ void AArch64TargetLowering::ReplaceNodeResults(
|
||||
}
|
||||
|
||||
bool AArch64TargetLowering::useLoadStackGuardNode() const {
|
||||
if (!Subtarget->isTargetAndroid())
|
||||
return true;
|
||||
return TargetLowering::useLoadStackGuardNode();
|
||||
if (Subtarget->isTargetAndroid() || Subtarget->isTargetFuchsia())
|
||||
return TargetLowering::useLoadStackGuardNode();
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned AArch64TargetLowering::combineRepeatedFPDivisors() const {
|
||||
@ -10610,36 +10610,43 @@ bool AArch64TargetLowering::shouldNormalizeToSelectSequence(LLVMContext &,
|
||||
return false;
|
||||
}
|
||||
|
||||
Value *AArch64TargetLowering::getIRStackGuard(IRBuilder<> &IRB) const {
|
||||
if (!Subtarget->isTargetAndroid())
|
||||
return TargetLowering::getIRStackGuard(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;
|
||||
static Value *UseTlsOffset(IRBuilder<> &IRB, unsigned Offset) {
|
||||
Module *M = IRB.GetInsertBlock()->getParent()->getParent();
|
||||
Function *ThreadPointerFunc =
|
||||
Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
|
||||
return IRB.CreatePointerCast(
|
||||
IRB.CreateConstGEP1_32(IRB.CreateCall(ThreadPointerFunc), TlsOffset),
|
||||
IRB.CreateConstGEP1_32(IRB.CreateCall(ThreadPointerFunc), Offset),
|
||||
Type::getInt8PtrTy(IRB.getContext())->getPointerTo(0));
|
||||
}
|
||||
|
||||
Value *AArch64TargetLowering::getSafeStackPointerLocation(IRBuilder<> &IRB) const {
|
||||
if (!Subtarget->isTargetAndroid())
|
||||
return TargetLowering::getSafeStackPointerLocation(IRB);
|
||||
Value *AArch64TargetLowering::getIRStackGuard(IRBuilder<> &IRB) const {
|
||||
// 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
|
||||
if (Subtarget->isTargetAndroid())
|
||||
return UseTlsOffset(IRB, 0x28);
|
||||
|
||||
// Fuchsia is similar.
|
||||
// <magenta/tls.h> defines MX_TLS_STACK_GUARD_OFFSET with this value.
|
||||
if (Subtarget->isTargetFuchsia())
|
||||
return UseTlsOffset(IRB, -0x10);
|
||||
|
||||
return TargetLowering::getIRStackGuard(IRB);
|
||||
}
|
||||
|
||||
Value *AArch64TargetLowering::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
|
||||
const unsigned TlsOffset = 0x48;
|
||||
Module *M = IRB.GetInsertBlock()->getParent()->getParent();
|
||||
Function *ThreadPointerFunc =
|
||||
Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
|
||||
return IRB.CreatePointerCast(
|
||||
IRB.CreateConstGEP1_32(IRB.CreateCall(ThreadPointerFunc), TlsOffset),
|
||||
Type::getInt8PtrTy(IRB.getContext())->getPointerTo(0));
|
||||
if (Subtarget->isTargetAndroid())
|
||||
return UseTlsOffset(IRB, 0x48);
|
||||
|
||||
// Fuchsia is similar.
|
||||
// <magenta/tls.h> defines MX_TLS_UNSAFE_SP_OFFSET with this value.
|
||||
if (Subtarget->isTargetFuchsia())
|
||||
return UseTlsOffset(IRB, -0x8);
|
||||
|
||||
return TargetLowering::getSafeStackPointerLocation(IRB);
|
||||
}
|
||||
|
||||
bool AArch64TargetLowering::isMaskAndCmp0FoldingBeneficial(
|
||||
|
@ -236,6 +236,7 @@ public:
|
||||
bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
|
||||
bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
|
||||
bool isTargetAndroid() const { return TargetTriple.isAndroid(); }
|
||||
bool isTargetFuchsia() const { return TargetTriple.isOSFuchsia(); }
|
||||
|
||||
bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
|
||||
bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
|
||||
|
@ -719,7 +719,8 @@ bool X86DAGToDAGISel::matchLoadInAddress(LoadSDNode *N, X86ISelAddressMode &AM){
|
||||
// For more information see http://people.redhat.com/drepper/tls.pdf
|
||||
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Address))
|
||||
if (C->getSExtValue() == 0 && AM.Segment.getNode() == nullptr &&
|
||||
(Subtarget->isTargetGlibc() || Subtarget->isTargetAndroid()))
|
||||
(Subtarget->isTargetGlibc() || Subtarget->isTargetAndroid() ||
|
||||
Subtarget->isTargetFuchsia()))
|
||||
switch (N->getPointerInfo().getAddrSpace()) {
|
||||
case 256:
|
||||
AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
|
||||
|
@ -2006,26 +2006,36 @@ unsigned X86TargetLowering::getAddressSpace() const {
|
||||
}
|
||||
|
||||
static bool hasStackGuardSlotTLS(const Triple &TargetTriple) {
|
||||
return TargetTriple.isOSGlibc() ||
|
||||
return TargetTriple.isOSGlibc() || TargetTriple.isOSFuchsia() ||
|
||||
(TargetTriple.isAndroid() && !TargetTriple.isAndroidVersionLT(17));
|
||||
}
|
||||
|
||||
Value *X86TargetLowering::getIRStackGuard(IRBuilder<> &IRB) const {
|
||||
// glibc and bionic have a special slot for the stack guard in tcbhead_t, use
|
||||
// it instead of the usual global variable (see
|
||||
// sysdeps/{i386,x86_64}/nptl/tls.h)
|
||||
if (!hasStackGuardSlotTLS(Subtarget.getTargetTriple()))
|
||||
return TargetLowering::getIRStackGuard(IRB);
|
||||
|
||||
// %fs:0x28, unless we're using a Kernel code model, in which case it's %gs:
|
||||
// %gs:0x14 on i386
|
||||
unsigned Offset = (Subtarget.is64Bit()) ? 0x28 : 0x14;
|
||||
unsigned AddressSpace = getAddressSpace();
|
||||
static Constant* SegmentOffset(IRBuilder<> &IRB,
|
||||
unsigned Offset, unsigned AddressSpace) {
|
||||
return ConstantExpr::getIntToPtr(
|
||||
ConstantInt::get(Type::getInt32Ty(IRB.getContext()), Offset),
|
||||
Type::getInt8PtrTy(IRB.getContext())->getPointerTo(AddressSpace));
|
||||
}
|
||||
|
||||
Value *X86TargetLowering::getIRStackGuard(IRBuilder<> &IRB) const {
|
||||
// glibc, bionic, and Fuchsia have a special slot for the stack guard in
|
||||
// tcbhead_t; use it instead of the usual global variable (see
|
||||
// sysdeps/{i386,x86_64}/nptl/tls.h)
|
||||
if (hasStackGuardSlotTLS(Subtarget.getTargetTriple())) {
|
||||
if (Subtarget.isTargetFuchsia()) {
|
||||
// <magenta/tls.h> defines MX_TLS_STACK_GUARD_OFFSET with this value.
|
||||
return SegmentOffset(IRB, 0x10, 257);
|
||||
} else {
|
||||
// %fs:0x28, unless we're using a Kernel code model, in which case
|
||||
// it's %gs:0x28. gs:0x14 on i386.
|
||||
unsigned Offset = (Subtarget.is64Bit()) ? 0x28 : 0x14;
|
||||
return SegmentOffset(IRB, Offset, getAddressSpace());
|
||||
}
|
||||
}
|
||||
|
||||
return TargetLowering::getIRStackGuard(IRB);
|
||||
}
|
||||
|
||||
void X86TargetLowering::insertSSPDeclarations(Module &M) const {
|
||||
// MSVC CRT provides functionalities for stack protection.
|
||||
if (Subtarget.getTargetTriple().isOSMSVCRT()) {
|
||||
@ -2042,7 +2052,7 @@ void X86TargetLowering::insertSSPDeclarations(Module &M) const {
|
||||
SecurityCheckCookie->addAttribute(1, Attribute::AttrKind::InReg);
|
||||
return;
|
||||
}
|
||||
// glibc and bionic have a special slot for the stack guard.
|
||||
// glibc, bionic, and Fuchsia have a special slot for the stack guard.
|
||||
if (hasStackGuardSlotTLS(Subtarget.getTargetTriple()))
|
||||
return;
|
||||
TargetLowering::insertSSPDeclarations(M);
|
||||
@ -2066,21 +2076,23 @@ Value *X86TargetLowering::getSafeStackPointerLocation(IRBuilder<> &IRB) const {
|
||||
if (Subtarget.getTargetTriple().isOSContiki())
|
||||
return getDefaultSafeStackPointerLocation(IRB, false);
|
||||
|
||||
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
|
||||
unsigned AddressSpace, Offset;
|
||||
if (Subtarget.isTargetAndroid()) {
|
||||
// %fs:0x48, unless we're using a Kernel code model, in which case it's %gs:
|
||||
// %gs:0x24 on i386
|
||||
unsigned Offset = (Subtarget.is64Bit()) ? 0x48 : 0x24;
|
||||
return SegmentOffset(IRB, Offset, getAddressSpace());
|
||||
}
|
||||
|
||||
// %fs:0x48, unless we're using a Kernel code model, in which case it's %gs:
|
||||
// %gs:0x24 on i386
|
||||
Offset = (Subtarget.is64Bit()) ? 0x48 : 0x24;
|
||||
AddressSpace = getAddressSpace();
|
||||
return ConstantExpr::getIntToPtr(
|
||||
ConstantInt::get(Type::getInt32Ty(IRB.getContext()), Offset),
|
||||
Type::getInt8PtrTy(IRB.getContext())->getPointerTo(AddressSpace));
|
||||
// Fuchsia is similar.
|
||||
if (Subtarget.isTargetFuchsia()) {
|
||||
// <magenta/tls.h> defines MX_TLS_UNSAFE_SP_OFFSET with this value.
|
||||
return SegmentOffset(IRB, 0x18, 257);
|
||||
}
|
||||
|
||||
return TargetLowering::getSafeStackPointerLocation(IRB);
|
||||
}
|
||||
|
||||
bool X86TargetLowering::isNoopAddrSpaceCast(unsigned SrcAS,
|
||||
|
@ -518,6 +518,7 @@ public:
|
||||
bool isTargetNaCl32() const { return isTargetNaCl() && !is64Bit(); }
|
||||
bool isTargetNaCl64() const { return isTargetNaCl() && is64Bit(); }
|
||||
bool isTargetMCU() const { return TargetTriple.isOSIAMCU(); }
|
||||
bool isTargetFuchsia() const { return TargetTriple.isOSFuchsia(); }
|
||||
|
||||
bool isTargetWindowsMSVC() const {
|
||||
return TargetTriple.isWindowsMSVCEnvironment();
|
||||
|
@ -1,5 +1,6 @@
|
||||
; Test target-specific stack cookie location.
|
||||
; RUN: llc -mtriple=aarch64-linux-android < %s -o - | FileCheck --check-prefix=ANDROID-AARCH64 %s
|
||||
; RUN: llc -mtriple=aarch64-fuchsia < %s -o - | FileCheck --check-prefix=FUCHSIA-AARCH64 %s
|
||||
|
||||
define void @_Z1fv() sspreq {
|
||||
entry:
|
||||
@ -17,3 +18,10 @@ declare void @_Z7CapturePi(i32*)
|
||||
; ANDROID-AARCH64: ldr [[C:.*]], {{\[}}[[A]], #40]
|
||||
; ANDROID-AARCH64: ldr [[D:.*]], [sp,
|
||||
; ANDROID-AARCH64: cmp [[C]], [[D]]
|
||||
|
||||
; FUCHSIA-AARCH64: mrs [[A:.*]], TPIDR_EL0
|
||||
; FUCHSIA-AARCH64: ldur [[B:.*]], {{\[}}[[A]], #-16]
|
||||
; FUCHSIA-AARCH64: str [[B]], [sp,
|
||||
; FUCHSIA-AARCH64: ldur [[C:.*]], {{\[}}[[A]], #-16]
|
||||
; FUCHSIA-AARCH64: ldr [[D:.*]], [sp,
|
||||
; FUCHSIA-AARCH64: cmp [[C]], [[D]]
|
||||
|
@ -2,6 +2,7 @@
|
||||
; 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=ANDROID-I386 %s
|
||||
; RUN: llc -mtriple=x86_64-linux-android < %s -o - | FileCheck --check-prefix=ANDROID-X64 %s
|
||||
; RUN: llc -mtriple=x86_64-fuchsia < %s -o - | FileCheck --check-prefix=FUCHSIA-X64 %s
|
||||
|
||||
define void @_Z1fv() safestack {
|
||||
entry:
|
||||
@ -30,3 +31,7 @@ declare void @_Z7CapturePi(i32*)
|
||||
; ANDROID-X64: movq %fs:72, %[[A:.*]]
|
||||
; ANDROID-X64: leaq -16(%[[A]]), %[[B:.*]]
|
||||
; ANDROID-X64: movq %[[B]], %fs:72
|
||||
|
||||
; FUCHSIA-X64: movq %fs:24, %[[A:.*]]
|
||||
; FUCHSIA-X64: leaq -16(%[[A]]), %[[B:.*]]
|
||||
; FUCHSIA-X64: movq %[[B]], %fs:24
|
||||
|
@ -1,6 +1,7 @@
|
||||
; Test codegen pipeline for SafeStack + StackProtector combination.
|
||||
; 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=x86_64-fuchsia < %s -o - | FileCheck --check-prefix=FUCHSIA-X64 %s
|
||||
|
||||
define void @_Z1fv() safestack sspreq {
|
||||
entry:
|
||||
@ -25,3 +26,9 @@ declare void @_Z7CapturePi(i32*)
|
||||
; LINUX-I386-DAG: leal -16(%[[B]]), %[[C:.*]]
|
||||
; LINUX-I386-DAG: movl %[[C]], %gs:(%[[A]])
|
||||
; LINUX-I386-DAG: movl %[[COOKIE]], -4(%[[B]])
|
||||
|
||||
; FUCHSIA-X64-DAG: movq %fs:24, %[[B:.*]]
|
||||
; FUCHSIA-X64-DAG: movq %fs:16, %[[COOKIE:.*]]
|
||||
; FUCHSIA-X64-DAG: leaq -16(%[[B]]), %[[C:.*]]
|
||||
; FUCHSIA-X64-DAG: movq %[[C]], %fs:24
|
||||
; FUCHSIA-X64-DAG: movq %[[COOKIE]], -8(%[[B]])
|
||||
|
@ -1,5 +1,5 @@
|
||||
; RUN: opt -safe-stack -S -mtriple=aarch64-linux-android < %s -o - | FileCheck --check-prefix=TLS %s
|
||||
|
||||
; RUN: opt -safe-stack -S -mtriple=aarch64-linux-android < %s -o - | FileCheck --check-prefixes=TLS,ANDROID %s
|
||||
; RUN: opt -safe-stack -S -mtriple=aarch64-unknown-fuchsia < %s -o - | FileCheck --check-prefixes=TLS,FUCHSIA %s
|
||||
|
||||
define void @foo() nounwind uwtable safestack sspreq {
|
||||
entry:
|
||||
@ -7,7 +7,8 @@ entry:
|
||||
; TLS: call i8* @llvm.thread.pointer()
|
||||
|
||||
; TLS: %[[TP2:.*]] = call i8* @llvm.thread.pointer()
|
||||
; TLS: %[[B:.*]] = getelementptr i8, i8* %[[TP2]], i32 40
|
||||
; ANDROID: %[[B:.*]] = getelementptr i8, i8* %[[TP2]], i32 40
|
||||
; FUCHSIA: %[[B:.*]] = getelementptr i8, i8* %[[TP2]], i32 -16
|
||||
; TLS: %[[C:.*]] = bitcast i8* %[[B]] to i8**
|
||||
; TLS: %[[StackGuard:.*]] = load i8*, i8** %[[C]]
|
||||
; TLS: store i8* %[[StackGuard]], i8** %[[StackGuardSlot:.*]]
|
||||
|
@ -6,10 +6,13 @@
|
||||
|
||||
; RUN: opt -safe-stack -S -mtriple=x86_64-linux-android < %s -o - | FileCheck --check-prefixes=COMMON,TLS64 %s
|
||||
|
||||
; RUN: opt -safe-stack -S -mtriple=x86_64-unknown-fuchsia < %s -o - | FileCheck --check-prefixes=COMMON,FUCHSIA64 %s
|
||||
|
||||
define void @foo() safestack sspreq {
|
||||
entry:
|
||||
; TLS32: %[[StackGuard:.*]] = load i8*, i8* addrspace(256)* inttoptr (i32 20 to i8* addrspace(256)*)
|
||||
; TLS64: %[[StackGuard:.*]] = load i8*, i8* addrspace(257)* inttoptr (i32 40 to i8* addrspace(257)*)
|
||||
; FUCHSIA64: %[[StackGuard:.*]] = load i8*, i8* addrspace(257)* inttoptr (i32 16 to i8* addrspace(257)*)
|
||||
; GLOBAL32: %[[StackGuard:.*]] = load i8*, i8** @__stack_chk_guard
|
||||
; COMMON: store i8* %[[StackGuard]], i8** %[[StackGuardSlot:.*]]
|
||||
%a = alloca i8, align 1
|
||||
|
Loading…
Reference in New Issue
Block a user