This is the mail archive of the
libc-ports@sources.redhat.com
mailing list for the libc-ports project.
[PATCH 07/26] arm: Introduce and use GET_TLS
- From: Richard Henderson <rth at twiddle dot net>
- To: libc-ports at sourceware dot org
- Cc: Joseph Myers <joseph at codesourcery dot com>
- Date: Tue, 26 Feb 2013 19:16:07 -0800
- Subject: [PATCH 07/26] arm: Introduce and use GET_TLS
- References: <1361934986-17018-1-git-send-email-rth@twiddle.net>
Factor out the sequence needed to call kuser_get_tls,
as we can't play subtract into pc games in thumb mode.
---
* sysdeps/unix/sysv/linux/arm/sysdep.h (GET_TLS): New macro.
* sysdeps/unix/arm/sysdep.S (__syscall_error): Use it.
* sysdeps/unix/sysv/linux/arm/clone.S (__clone): Likewise.
* sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S (SAVE_PID): Likewise.
* sysdeps/unix/sysv/linux/arm/nptl/vfork.S (SAVE_PID): Likewise.
* sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S (__aeabi_read_tp):
Add thumb2 alternative.
---
ports/sysdeps/unix/arm/sysdep.S | 4 +---
ports/sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S | 6 ++++++
ports/sysdeps/unix/sysv/linux/arm/clone.S | 4 +---
ports/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S | 4 +---
ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S | 4 +---
ports/sysdeps/unix/sysv/linux/arm/sysdep.h | 15 +++++++++++++++
6 files changed, 25 insertions(+), 12 deletions(-)
diff --git a/ports/sysdeps/unix/arm/sysdep.S b/ports/sysdeps/unix/arm/sysdep.S
index 76137b3..425f4ac 100644
--- a/ports/sysdeps/unix/arm/sysdep.S
+++ b/ports/sysdeps/unix/arm/sysdep.S
@@ -40,9 +40,7 @@ __syscall_error:
cfi_register (lr, ip)
mov r1, r0
- mov r0, #0xffff0fff
- mov lr, pc
- sub pc, r0, #31
+ GET_TLS
ldr r2, 1f
2: ldr r2, [pc, r2]
diff --git a/ports/sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S b/ports/sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S
index c4ddbc6..ecdc322 100644
--- a/ports/sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S
+++ b/ports/sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S
@@ -41,6 +41,12 @@
.hidden __aeabi_read_tp
ENTRY (__aeabi_read_tp)
+#ifdef __thumb2__
+ movw r0, #0x0fe0
+ movt r0, #0xffff
+ bx r0
+#else
mov r0, #0xffff0fff
sub pc, r0, #31
+#endif
END (__aeabi_read_tp)
diff --git a/ports/sysdeps/unix/sysv/linux/arm/clone.S b/ports/sysdeps/unix/sysv/linux/arm/clone.S
index de25db1..8807781 100644
--- a/ports/sysdeps/unix/sysv/linux/arm/clone.S
+++ b/ports/sysdeps/unix/sysv/linux/arm/clone.S
@@ -73,9 +73,7 @@ PSEUDO_END (__clone)
#ifdef RESET_PID
tst ip, #CLONE_THREAD
bne 3f
- mov r0, #0xffff0fff
- mov lr, pc
- sub pc, r0, #31
+ GET_TLS
mov r1, r0
tst ip, #CLONE_VM
movne r0, #-1
diff --git a/ports/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S b/ports/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S
index a38d564..749aaab 100644
--- a/ports/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S
+++ b/ports/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S
@@ -22,9 +22,7 @@
str lr, [sp, #-4]!; /* Save LR. */ \
cfi_adjust_cfa_offset (4); \
cfi_rel_offset (lr, 0); \
- mov r0, #0xffff0fff; /* Point to the high page. */ \
- mov lr, pc; /* Save our return address. */ \
- sub pc, r0, #31; /* Jump to the TLS entry. */ \
+ GET_TLS; \
ldr lr, [sp], #4; /* Restore LR. */ \
cfi_adjust_cfa_offset (-4); \
cfi_restore (lr); \
diff --git a/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S b/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S
index 3fce2d1..1bbe5c6 100644
--- a/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S
+++ b/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S
@@ -22,9 +22,7 @@
str lr, [sp, #-4]!; /* Save LR. */ \
cfi_adjust_cfa_offset (4); \
cfi_rel_offset (lr, 0); \
- mov r0, #0xffff0fff; /* Point to the high page. */ \
- mov lr, pc; /* Save our return address. */ \
- sub pc, r0, #31; /* Jump to the TLS entry. */ \
+ GET_TLS; \
ldr lr, [sp], #4; /* Restore LR. */ \
cfi_adjust_cfa_offset (-4); \
cfi_restore (lr); \
diff --git a/ports/sysdeps/unix/sysv/linux/arm/sysdep.h b/ports/sysdeps/unix/sysv/linux/arm/sysdep.h
index cb237d9..dae9d98 100644
--- a/ports/sysdeps/unix/sysv/linux/arm/sysdep.h
+++ b/ports/sysdeps/unix/sysv/linux/arm/sysdep.h
@@ -45,6 +45,21 @@
#ifdef __ASSEMBLER__
+/* Call the linux kernel kuser_get_tls helper. Returns in R0, clobbers LR.
+ Note that in thumb mode, a constant pool break is often out of range, so
+ we always expand the constant inline. */
+#ifdef __thumb2__
+# define GET_TLS \
+ movw r0, #0x0fe0; \
+ movt r0, #0xffff; \
+ blx r0
+#else
+# define GET_TLS \
+ mov r0, #0xffff0fff; /* Point to the high page. */ \
+ mov lr, pc; /* Save our return address. */ \
+ sub pc, r0, #31 /* Jump to the TLS entry. */
+#endif
+
/* Linux uses a negative return value to indicate syscall errors,
unlike most Unices, which use the condition codes' carry flag.
--
1.8.1.2