about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--mk/cfg/arm-apple-ios.mk35
-rw-r--r--mk/cfg/armv7-apple-ios.mk34
-rw-r--r--mk/cfg/armv7s-apple-ios.mk34
-rw-r--r--mk/cfg/i386-apple-ios.mk32
-rw-r--r--src/rt/arch/armv7/morestack.S70
-rw-r--r--src/rt/arch/armv7/record_sp.S56
-rw-r--r--src/rt/arch/armv7s/morestack.S70
-rw-r--r--src/rt/arch/armv7s/record_sp.S56
8 files changed, 336 insertions, 51 deletions
diff --git a/mk/cfg/arm-apple-ios.mk b/mk/cfg/arm-apple-ios.mk
deleted file mode 100644
index d1f1ee6f3bd..00000000000
--- a/mk/cfg/arm-apple-ios.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-# arm-apple-ios configuration
-CFG_SDK_NAME_arm-apple-ios = iphoneos
-CFG_SDK_ARCHS_arm-apple-ios = armv7
-ifneq ($(findstring darwin,$(CFG_OSTYPE)),)
-CFG_IOS_SDK = $(shell xcrun --show-sdk-path -sdk iphoneos 2>/dev/null)
-CFG_IOS_FLAGS = -target armv7-apple-ios -isysroot $(CFG_IOS_SDK) -mios-version-min=7.0
-CC_arm-apple-ios = $(shell xcrun -find -sdk iphoneos clang)
-CXX_arm-apple-ios = $(shell xcrun -find -sdk iphoneos clang++)
-CPP_arm-apple-ios = $(shell xcrun -find -sdk iphoneos clang++)
-AR_arm-apple-ios = $(shell xcrun -find -sdk iphoneos ar)
-endif
-CFG_LIB_NAME_arm-apple-ios = lib$(1).a
-CFG_LIB_GLOB_arm-apple-ios = lib$(1)-*.a
-CFG_STATIC_LIB_NAME_arm-apple-ios=lib$(1).a
-CFG_LIB_DSYM_GLOB_arm-apple-ios = lib$(1)-*.a.dSYM
-CFG_JEMALLOC_CFLAGS_arm-apple-ios := -arch armv7 -mfpu=vfp3 $(CFG_IOS_FLAGS)
-CFG_GCCISH_CFLAGS_arm-apple-ios := -Wall -Werror -g -fPIC $(CFG_IOS_FLAGS) -mfpu=vfp3 -arch armv7
-CFG_GCCISH_CXXFLAGS_arm-apple-ios := -fno-rtti $(CFG_IOS_FLAGS) -I$(CFG_IOS_SDK)/usr/include/c++/4.2.1
-CFG_GCCISH_LINK_FLAGS_arm-apple-ios := -lpthread -syslibroot $(CFG_IOS_SDK) -Wl,-no_compact_unwind
-CFG_GCCISH_DEF_FLAG_arm-apple-ios := -Wl,-exported_symbols_list,
-CFG_GCCISH_PRE_LIB_FLAGS_arm-apple-ios :=
-CFG_GCCISH_POST_LIB_FLAGS_arm-apple-ios :=
-CFG_DEF_SUFFIX_arm-apple-ios := .darwin.def
-CFG_LLC_FLAGS_arm-apple-ios := -mattr=+vfp3,+v7,+thumb2,+neon -march=arm
-CFG_INSTALL_NAME_arm-apple-ios = -Wl,-install_name,@rpath/$(1)
-CFG_EXE_SUFFIX_arm-apple-ios :=
-CFG_WINDOWSY_arm-apple-ios :=
-CFG_UNIXY_arm-apple-ios := 1
-CFG_PATH_MUNGE_arm-apple-ios := true
-CFG_LDPATH_arm-apple-ios :=
-CFG_RUN_arm-apple-ios = $(2)
-CFG_RUN_TARG_arm-apple-ios = $(call CFG_RUN_arm-apple-ios,,$(2))
-RUSTC_FLAGS_arm-apple-ios := -C relocation_model=pic
-RUSTC_CROSS_FLAGS_arm-apple-ios :=-C relocation_model=pic
-CFG_GNU_TRIPLE_arm-apple-ios := arm-apple-ios
diff --git a/mk/cfg/armv7-apple-ios.mk b/mk/cfg/armv7-apple-ios.mk
new file mode 100644
index 00000000000..23686c41f2b
--- /dev/null
+++ b/mk/cfg/armv7-apple-ios.mk
@@ -0,0 +1,34 @@
+# armv7-apple-ios configuration
+CFG_SDK_NAME_armv7-apple-ios := iphoneos
+CFG_SDK_ARCHS_armv7-apple-ios := armv7
+ifneq ($(findstring darwin,$(CFG_OSTYPE)),)
+CFG_IOS_SDK_armv7-apple-ios := $(shell xcrun --show-sdk-path -sdk iphoneos 2>/dev/null)
+CFG_IOS_SDK_FLAGS_armv7-apple-ios := -target armv7-apple-ios -isysroot $(CFG_IOS_SDK_armv7-apple-ios) -mios-version-min=7.0
+CC_armv7-apple-ios = $(shell xcrun -find -sdk iphoneos clang)
+CXX_armv7-apple-ios = $(shell xcrun -find -sdk iphoneos clang++)
+CPP_armv7-apple-ios = $(shell xcrun -find -sdk iphoneos clang++)
+AR_armv7-apple-ios = $(shell xcrun -find -sdk iphoneos ar)
+endif
+CFG_LIB_NAME_armv7-apple-ios = lib$(1).a
+CFG_LIB_GLOB_armv7-apple-ios = lib$(1)-*.a
+CFG_LIB_SKIP_INSTALL_armv7-apple-ios = 1 #lib$(1)-*.a
+CFG_STATIC_LIB_NAME_armv7-apple-ios=lib$(1).a
+CFG_LIB_DSYM_GLOB_armv7-apple-ios = lib$(1)-*.a.dSYM
+CFG_JEMALLOC_CFLAGS_armv7-apple-ios := -arch armv7 -mfpu=vfp3 $(CFG_IOS_SDK_FLAGS_armv7-apple-ios)
+CFG_GCCISH_CFLAGS_armv7-apple-ios := -Wall -Werror -g -fPIC $(CFG_IOS_SDK_FLAGS_armv7-apple-ios) -mfpu=vfp3 -arch armv7
+CFG_GCCISH_CXXFLAGS_armv7-apple-ios := -fno-rtti $(CFG_IOS_SDK_FLAGS_armv7-apple-ios) -I$(CFG_IOS_SDK_armv7-apple-ios)/usr/include/c++/4.2.1
+CFG_GCCISH_LINK_FLAGS_armv7-apple-ios := -lpthread -syslibroot $(CFG_IOS_SDK_armv7-apple-ios) -Wl,-no_compact_unwind
+CFG_GCCISH_DEF_FLAG_armv7-apple-ios := -Wl,-exported_symbols_list,
+CFG_GCCISH_PRE_LIB_FLAGS_armv7-apple-ios :=
+CFG_GCCISH_POST_LIB_FLAGS_armv7-apple-ios :=
+CFG_DEF_SUFFIX_armv7-apple-ios := .darwin.def
+CFG_LLC_FLAGS_armv7-apple-ios := -mattr=+vfp3,+v7,+neon -march=arm
+CFG_INSTALL_NAME_armv7-apple-ios = -Wl,-install_name,@rpath/$(1)
+CFG_EXE_SUFFIX_armv7-apple-ios :=
+CFG_WINDOWSY_armv7-apple-ios :=
+CFG_UNIXY_armv7-apple-ios := 1
+CFG_PATH_MUNGE_armv7-apple-ios := true
+CFG_LDPATH_armv7-apple-ios :=
+CFG_RUN_armv7-apple-ios = $(2)
+CFG_RUN_TARG_armv7-apple-ios = $(call CFG_RUN_armv7-apple-ios,,$(2))
+CFG_GNU_TRIPLE_armv7-apple-ios := armv7-apple-ios
diff --git a/mk/cfg/armv7s-apple-ios.mk b/mk/cfg/armv7s-apple-ios.mk
new file mode 100644
index 00000000000..ccb7f014159
--- /dev/null
+++ b/mk/cfg/armv7s-apple-ios.mk
@@ -0,0 +1,34 @@
+# armv7s-apple-ios configuration
+CFG_SDK_NAME_armv7s-apple-ios := iphoneos
+CFG_SDK_ARCHS_armv7s-apple-ios := armv7s
+ifneq ($(findstring darwin,$(CFG_OSTYPE)),)
+CFG_IOS_SDK_armv7s-apple-ios := $(shell xcrun --show-sdk-path -sdk iphoneos 2>/dev/null)
+CFG_IOS_SDK_FLAGS_armv7s-apple-ios := -target armv7s-apple-ios -isysroot $(CFG_IOS_SDK_armv7s-apple-ios) -mios-version-min=7.0
+CC_armv7s-apple-ios = $(shell xcrun -find -sdk iphoneos clang)
+CXX_armv7s-apple-ios = $(shell xcrun -find -sdk iphoneos clang++)
+CPP_armv7s-apple-ios = $(shell xcrun -find -sdk iphoneos clang++)
+AR_armv7s-apple-ios = $(shell xcrun -find -sdk iphoneos ar)
+endif
+CFG_LIB_NAME_armv7s-apple-ios = lib$(1).a
+CFG_LIB_GLOB_armv7s-apple-ios = lib$(1)-*.a
+CFG_LIB_SKIP_INSTALL_armv7s-apple-ios = 1 #lib$(1)-*.a
+CFG_STATIC_LIB_NAME_armv7s-apple-ios=lib$(1).a
+CFG_LIB_DSYM_GLOB_armv7s-apple-ios = lib$(1)-*.a.dSYM
+CFG_JEMALLOC_CFLAGS_armv7s-apple-ios := -arch armv7s -mfpu=vfp4 $(CFG_IOS_SDK_FLAGS_armv7s-apple-ios)
+CFG_GCCISH_CFLAGS_armv7s-apple-ios := -Wall -Werror -g -fPIC $(CFG_IOS_SDK_FLAGS_armv7s-apple-ios) -mfpu=vfp4 -arch armv7s
+CFG_GCCISH_CXXFLAGS_armv7s-apple-ios := -fno-rtti $(CFG_IOS_SDK_FLAGS_armv7s-apple-ios) -I$(CFG_IOS_SDK_armv7s-apple-ios)/usr/include/c++/4.2.1
+CFG_GCCISH_LINK_FLAGS_armv7s-apple-ios := -lpthread -syslibroot $(CFG_IOS_SDK_armv7s-apple-ios) -Wl,-no_compact_unwind
+CFG_GCCISH_DEF_FLAG_armv7s-apple-ios := -Wl,-exported_symbols_list,
+CFG_GCCISH_PRE_LIB_FLAGS_armv7s-apple-ios :=
+CFG_GCCISH_POST_LIB_FLAGS_armv7s-apple-ios :=
+CFG_DEF_SUFFIX_armv7s-apple-ios := .darwin.def
+CFG_LLC_FLAGS_armv7s-apple-ios := -mattr=+vfp4,+v7,+neon
+CFG_INSTALL_NAME_armv7s-apple-ios = -Wl,-install_name,@rpath/$(1)
+CFG_EXE_SUFFIX_armv7s-apple-ios :=
+CFG_WINDOWSY_armv7s-apple-ios :=
+CFG_UNIXY_armv7s-apple-ios := 1
+CFG_PATH_MUNGE_armv7s-apple-ios := true
+CFG_LDPATH_armv7s-apple-ios :=
+CFG_RUN_armv7s-apple-ios = $(2)
+CFG_RUN_TARG_armv7s-apple-ios = $(call CFG_RUN_armv7s-apple-ios,,$(2))
+CFG_GNU_TRIPLE_armv7s-apple-ios := armv7s-apple-ios
diff --git a/mk/cfg/i386-apple-ios.mk b/mk/cfg/i386-apple-ios.mk
index 63eb590c6e4..5007c0617c5 100644
--- a/mk/cfg/i386-apple-ios.mk
+++ b/mk/cfg/i386-apple-ios.mk
@@ -1,9 +1,9 @@
 # i386-apple-ios configuration
-CFG_SDK_NAME_i386-apple-ios = iphonesimulator
-CFG_SDK_ARCHS_i386-apple-ios = i386
+CFG_SDK_NAME_i386-apple-ios := iphonesimulator
+CFG_SDK_ARCHS_i386-apple-ios := i386
 ifneq ($(findstring darwin,$(CFG_OSTYPE)),)
-CFG_IOSSIM_SDK = $(shell xcrun --show-sdk-path -sdk iphonesimulator 2>/dev/null)
-CFG_IOSSIM_FLAGS = -target i386-apple-ios -isysroot $(CFG_IOSSIM_SDK) -mios-simulator-version-min=7.0
+CFG_IOSSIM_SDK_i386-apple-ios := $(shell xcrun --show-sdk-path -sdk iphonesimulator 2>/dev/null)
+CFG_IOSSIM_FLAGS_i386-apple-ios := -m32 -target i386-apple-ios -isysroot $(CFG_IOSSIM_SDK_i386-apple-ios) -mios-simulator-version-min=7.0
 CC_i386-apple-ios = $(shell xcrun -find -sdk iphonesimulator clang)
 CXX_i386-apple-ios = $(shell xcrun -find -sdk iphonesimulator clang++)
 CPP_i386-apple-ios = $(shell xcrun -find -sdk iphonesimulator clang++)
@@ -13,21 +13,21 @@ CFG_LIB_NAME_i386-apple-ios = lib$(1).a
 CFG_LIB_GLOB_i386-apple-ios = lib$(1)-*.dylib
 CFG_STATIC_LIB_NAME_i386-apple-ios=lib$(1).a
 CFG_LIB_DSYM_GLOB_i386-apple-ios = lib$(1)-*.dylib.dSYM
-CFG_GCCISH_CFLAGS_i386-apple-ios = -Wall -Werror -g -fPIC -m32 $(CFG_IOSSIM_FLAGS)
-CFG_GCCISH_CXXFLAGS_i386-apple-ios = -fno-rtti $(CFG_IOSSIM_FLAGS) -I$(CFG_IOSSIM_SDK)/usr/include/c++/4.2.1
-CFG_GCCISH_LINK_FLAGS_i386-apple-ios = -lpthread -Wl,-no_compact_unwind -m32 -Wl,-syslibroot $(CFG_IOSSIM_SDK)
-CFG_GCCISH_DEF_FLAG_i386-apple-ios = -Wl,-exported_symbols_list,
-CFG_GCCISH_PRE_LIB_FLAGS_i386-apple-ios =
-CFG_GCCISH_POST_LIB_FLAGS_i386-apple-ios =
-CFG_DEF_SUFFIX_i386-apple-ios = .darwin.def
+CFG_GCCISH_CFLAGS_i386-apple-ios := -Wall -Werror -g -fPIC -m32 $(CFG_IOSSIM_FLAGS_i386-apple-ios)
+CFG_GCCISH_CXXFLAGS_i386-apple-ios := -fno-rtti $(CFG_IOSSIM_FLAGS_i386-apple-ios) -I$(CFG_IOSSIM_SDK_i386-apple-ios)/usr/include/c++/4.2.1
+CFG_GCCISH_LINK_FLAGS_i386-apple-ios := -lpthread -m32 -Wl,-no_compact_unwind -m32 -Wl,-syslibroot $(CFG_IOSSIM_SDK_i386-apple-ios)
+CFG_GCCISH_DEF_FLAG_i386-apple-ios := -Wl,-exported_symbols_list,
+CFG_GCCISH_PRE_LIB_FLAGS_i386-apple-ios :=
+CFG_GCCISH_POST_LIB_FLAGS_i386-apple-ios :=
+CFG_DEF_SUFFIX_i386-apple-ios := .darwin.def
 CFG_LLC_FLAGS_i386-apple-ios =
 CFG_INSTALL_NAME_i386-apple-ios = -Wl,-install_name,@rpath/$(1)
-CFG_EXE_SUFFIX_i386-apple-ios =
-CFG_WINDOWSY_i386-apple-ios =
-CFG_UNIXY_i386-apple-ios = 1
-CFG_PATH_MUNGE_i386-apple-ios = true
+CFG_EXE_SUFFIX_i386-apple-ios :=
+CFG_WINDOWSY_i386-apple-ios :=
+CFG_UNIXY_i386-apple-ios := 1
+CFG_PATH_MUNGE_i386-apple-ios = :true
 CFG_LDPATH_i386-apple-ios =
 CFG_RUN_i386-apple-ios = $(2)
 CFG_RUN_TARG_i386-apple-ios = $(call CFG_RUN_i386-apple-ios,,$(2))
-CFG_JEMALLOC_CFLAGS_i386-apple-ios = $(CFG_IOSSIM_FLAGS) -target i386-apple-ios -Wl,-syslibroot $(CFG_IOSSIM_SDK) -Wl,-no_compact_unwind
+CFG_JEMALLOC_CFLAGS_i386-apple-ios = $(CFG_IOSSIM_FLAGS_i386-apple-ios) -target i386-apple-ios #-Wl,-syslibroot $(CFG_IOSSIM_SDK_i386-apple-ios) -Wl,-no_compact_unwind
 CFG_GNU_TRIPLE_i386-apple-ios := i386-apple-ios
diff --git a/src/rt/arch/armv7/morestack.S b/src/rt/arch/armv7/morestack.S
new file mode 100644
index 00000000000..0b9012cc2a8
--- /dev/null
+++ b/src/rt/arch/armv7/morestack.S
@@ -0,0 +1,70 @@
+// Mark stack as non-executable
+#if defined(__linux__) && defined(__ELF__)
+.section	.note.GNU-stack, "", %progbits
+#endif
+
+/* See i386/morestack.S for the lengthy, general explanation. */
+
+.text
+.code 32
+.arm
+#if defined(__APPLE__)
+.align 2
+#else
+.align
+#endif
+
+#if defined(__APPLE__)
+#define MORESTACK ___morestack
+#define STACK_EXHAUSTED _rust_stack_exhausted
+#else
+#define MORESTACK __morestack
+#define STACK_EXHAUSTED rust_stack_exhausted
+#endif
+
+.global STACK_EXHAUSTED
+.global MORESTACK
+
+// Unfortunately LLVM yet doesn't support emitting correct debug
+// DWARF information for non-ELF targets so to make it compile
+// on iOS all that directives are simply commented out
+#if defined(__APPLE__)
+#define UNWIND @
+#else
+#define UNWIND
+#endif
+
+#if defined(__APPLE__)
+.private_extern MORESTACK
+#else
+.hidden MORESTACK
+#endif
+
+#if !defined(__APPLE__)
+   .type MORESTACK,%function
+#endif
+
+// r4 and r5 are scratch registers for __morestack due to llvm
+// ARMFrameLowering::adjustForSegmentedStacks() implementation.
+MORESTACK:
+    UNWIND .fnstart
+
+    // Save frame pointer and return address
+    UNWIND .save {r4, r5}
+    UNWIND .save {lr}
+    UNWIND .save {r6, fp, lr}
+    push {r6, fp, lr}
+
+    UNWIND .movsp r6
+    mov r6, sp
+    UNWIND .setfp fp, sp, #4
+    add fp, sp, #4
+
+    // Save argument registers of the original function
+    push {r0, r1, r2, r3, lr}
+
+    // Create new stack
+    bl STACK_EXHAUSTED@plt
+
+    // the above function ensures that it never returns
+    UNWIND  .fnend
diff --git a/src/rt/arch/armv7/record_sp.S b/src/rt/arch/armv7/record_sp.S
new file mode 100644
index 00000000000..d0e9b81b95a
--- /dev/null
+++ b/src/rt/arch/armv7/record_sp.S
@@ -0,0 +1,56 @@
+// Do not compile anything here for iOS because split stacks
+// are disabled at all and do not need any runtime support.
+//
+// See also comments in librustrt/stack.rs about why it was
+// disabled and how it could be implemented in case of need.
+#if !defined(__APPLE__)
+// Mark stack as non-executable
+#if defined(__linux__) && defined(__ELF__)
+.section	.note.GNU-stack, "", %progbits
+#endif
+
+.text
+.code 32
+.arm
+.align
+
+#define RECORD_SP_LIMIT record_sp_limit
+#define GET_SP_LIMIT    get_sp_limit
+
+.globl 	RECORD_SP_LIMIT
+.globl	GET_SP_LIMIT
+
+RECORD_SP_LIMIT:
+	// First, try to read TLS address from coprocessor
+	mrc p15, #0, r3, c13, c0, #3
+	cmp r3, #0
+	// Otherwise, try to read from magic address 0xFFFF0FF0
+	mvneq r3, #0xF000
+	ldreq r3, [r3, #-15]
+
+#if __ANDROID__
+	add r3, r3, #252
+#elif __linux__
+	add r3, r3, #4
+#endif // ANDROID
+
+	str r0, [r3]
+	mov pc, lr
+
+GET_SP_LIMIT:
+	// First, try to read TLS address from coprocessor
+	mrc p15, #0, r3, c13, c0, #3
+	cmp r3, #0
+	// Otherwise, try to read from magic address 0xFFFF0FF0
+	mvneq r3, #0xF000
+	ldreq r3, [r3, #-15]
+
+#if __ANDROID__
+	add r3, r3, #252
+#elif __linux__
+	add r3, r3, #4
+#endif  // __ANDROID__
+
+	ldr r0, [r3]
+	mov pc, lr
+#endif
diff --git a/src/rt/arch/armv7s/morestack.S b/src/rt/arch/armv7s/morestack.S
new file mode 100644
index 00000000000..0b9012cc2a8
--- /dev/null
+++ b/src/rt/arch/armv7s/morestack.S
@@ -0,0 +1,70 @@
+// Mark stack as non-executable
+#if defined(__linux__) && defined(__ELF__)
+.section	.note.GNU-stack, "", %progbits
+#endif
+
+/* See i386/morestack.S for the lengthy, general explanation. */
+
+.text
+.code 32
+.arm
+#if defined(__APPLE__)
+.align 2
+#else
+.align
+#endif
+
+#if defined(__APPLE__)
+#define MORESTACK ___morestack
+#define STACK_EXHAUSTED _rust_stack_exhausted
+#else
+#define MORESTACK __morestack
+#define STACK_EXHAUSTED rust_stack_exhausted
+#endif
+
+.global STACK_EXHAUSTED
+.global MORESTACK
+
+// Unfortunately LLVM yet doesn't support emitting correct debug
+// DWARF information for non-ELF targets so to make it compile
+// on iOS all that directives are simply commented out
+#if defined(__APPLE__)
+#define UNWIND @
+#else
+#define UNWIND
+#endif
+
+#if defined(__APPLE__)
+.private_extern MORESTACK
+#else
+.hidden MORESTACK
+#endif
+
+#if !defined(__APPLE__)
+   .type MORESTACK,%function
+#endif
+
+// r4 and r5 are scratch registers for __morestack due to llvm
+// ARMFrameLowering::adjustForSegmentedStacks() implementation.
+MORESTACK:
+    UNWIND .fnstart
+
+    // Save frame pointer and return address
+    UNWIND .save {r4, r5}
+    UNWIND .save {lr}
+    UNWIND .save {r6, fp, lr}
+    push {r6, fp, lr}
+
+    UNWIND .movsp r6
+    mov r6, sp
+    UNWIND .setfp fp, sp, #4
+    add fp, sp, #4
+
+    // Save argument registers of the original function
+    push {r0, r1, r2, r3, lr}
+
+    // Create new stack
+    bl STACK_EXHAUSTED@plt
+
+    // the above function ensures that it never returns
+    UNWIND  .fnend
diff --git a/src/rt/arch/armv7s/record_sp.S b/src/rt/arch/armv7s/record_sp.S
new file mode 100644
index 00000000000..d0e9b81b95a
--- /dev/null
+++ b/src/rt/arch/armv7s/record_sp.S
@@ -0,0 +1,56 @@
+// Do not compile anything here for iOS because split stacks
+// are disabled at all and do not need any runtime support.
+//
+// See also comments in librustrt/stack.rs about why it was
+// disabled and how it could be implemented in case of need.
+#if !defined(__APPLE__)
+// Mark stack as non-executable
+#if defined(__linux__) && defined(__ELF__)
+.section	.note.GNU-stack, "", %progbits
+#endif
+
+.text
+.code 32
+.arm
+.align
+
+#define RECORD_SP_LIMIT record_sp_limit
+#define GET_SP_LIMIT    get_sp_limit
+
+.globl 	RECORD_SP_LIMIT
+.globl	GET_SP_LIMIT
+
+RECORD_SP_LIMIT:
+	// First, try to read TLS address from coprocessor
+	mrc p15, #0, r3, c13, c0, #3
+	cmp r3, #0
+	// Otherwise, try to read from magic address 0xFFFF0FF0
+	mvneq r3, #0xF000
+	ldreq r3, [r3, #-15]
+
+#if __ANDROID__
+	add r3, r3, #252
+#elif __linux__
+	add r3, r3, #4
+#endif // ANDROID
+
+	str r0, [r3]
+	mov pc, lr
+
+GET_SP_LIMIT:
+	// First, try to read TLS address from coprocessor
+	mrc p15, #0, r3, c13, c0, #3
+	cmp r3, #0
+	// Otherwise, try to read from magic address 0xFFFF0FF0
+	mvneq r3, #0xF000
+	ldreq r3, [r3, #-15]
+
+#if __ANDROID__
+	add r3, r3, #252
+#elif __linux__
+	add r3, r3, #4
+#endif  // __ANDROID__
+
+	ldr r0, [r3]
+	mov pc, lr
+#endif