From: Richard Henderson <rth@twiddle.net>
To: libc-ports@sourceware.org
Cc: joseph@codesourcery.com
Subject: [PATCH v2 03/14] arm: Introduce and use GET_TLS
Date: Fri, 01 Mar 2013 17:36:00 -0000 [thread overview]
Message-ID: <1362159320-5934-4-git-send-email-rth@twiddle.net> (raw)
In-Reply-To: <1362159320-5934-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. Prepare for hard-tp,
pulling the save of LR into the macro.
---
* sysdeps/arm/sysdep.h (GET_TLS): New macro.
* sysdeps/arm/dl-tlsdesc.S (_dl_tlsdesc_undefweak): Use it.
(_dl_tlsdesc_dynamic): Likewise.
* sysdeps/unix/arm/sysdep.S (__syscall_error): Likewise.
* sysdeps/unix/sysv/linux/arm/sysdep.h (GET_TLS): New macro.
* 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/nptl/sysdep-cancel.h (SINGLE_THREAD_P):
Likewise.
* sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S (__aeabi_read_tp):
Add thumb2 alternative.
---
ports/sysdeps/arm/dl-tlsdesc.S | 13 ++--------
ports/sysdeps/arm/sysdep.h | 19 ++++++++++++++
ports/sysdeps/unix/arm/sysdep.S | 12 +++------
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 | 10 +-------
.../unix/sysv/linux/arm/nptl/sysdep-cancel.h | 2 +-
ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S | 10 +-------
ports/sysdeps/unix/sysv/linux/arm/sysdep.h | 30 ++++++++++++++++++++++
9 files changed, 64 insertions(+), 42 deletions(-)
diff --git a/ports/sysdeps/arm/dl-tlsdesc.S b/ports/sysdeps/arm/dl-tlsdesc.S
index 7b4c8df..1c3bccf 100644
--- a/ports/sysdeps/arm/dl-tlsdesc.S
+++ b/ports/sysdeps/arm/dl-tlsdesc.S
@@ -50,18 +50,9 @@ _dl_tlsdesc_return:
.fnstart
.align 2
_dl_tlsdesc_undefweak:
- @ Are we allowed a misaligned stack pointer calling read_tp?
- .save {lr}
- stmdb sp!, {lr}
- cfi_adjust_cfa_offset (4)
- cfi_rel_offset (lr,0)
- bl __aeabi_read_tp
+ GET_TLS(r1)
rsb r0, r0, #0
- ldmia sp!, {lr}
- cfi_adjust_cfa_offset (-4)
- cfi_restore (lr)
BX (lr)
-
cfi_endproc
.fnend
.size _dl_tlsdesc_undefweak, .-_dl_tlsdesc_undefweak
@@ -106,7 +97,7 @@ _dl_tlsdesc_dynamic:
cfi_rel_offset (r4,8)
cfi_rel_offset (lr,12)
ldr r1, [r0] /* td */
- bl __aeabi_read_tp
+ GET_TLS(lr)
mov r4, r0 /* r4 = tp */
ldr r0, [r0]
ldr r2, [r1, #8] /* gen_count */
diff --git a/ports/sysdeps/arm/sysdep.h b/ports/sysdeps/arm/sysdep.h
index 9230131..c525d5b 100644
--- a/ports/sysdeps/arm/sysdep.h
+++ b/ports/sysdeps/arm/sysdep.h
@@ -150,6 +150,25 @@
# define NEGOFF_OFF1(R, OFF) [R, $OFF]
# define NEGOFF_OFF2(R, OFFA, OFFB) [R, $OFFA]
# endif
+
+/* Helper to get the TLS base pointer. The interface is that TMP is a
+ register that may be used to hold the LR, if necessary. TMP may be
+ LR itself to indicate that LR need not be saved. The base pointer
+ is returned in R0. Only R0 and TMP are modified.
+
+ At this generic level we have no tricks to pull. Call the ABI routine. */
+# define GET_TLS(TMP) \
+ push { r1, r2, r3, lr }; \
+ cfi_remember_state; \
+ cfi_adjust_cfa_offset (16); \
+ cfi_rel_offset (r1, 0); \
+ cfi_rel_offset (r2, 4); \
+ cfi_rel_offset (r3, 8); \
+ cfi_rel_offset (lr, 12); \
+ bl __aeabi_read_tp; \
+ pop { r1, r2, r3, lr }; \
+ cfi_restore_state
+
#endif /* __ASSEMBLER__ */
/* This number is the offset from the pc at the current location. */
diff --git a/ports/sysdeps/unix/arm/sysdep.S b/ports/sysdeps/unix/arm/sysdep.S
index d44ee48..b07cba9 100644
--- a/ports/sysdeps/unix/arm/sysdep.S
+++ b/ports/sysdeps/unix/arm/sysdep.S
@@ -37,14 +37,8 @@ __syscall_error:
#endif
#ifndef IS_IN_rtld
- mov ip, lr
- cfi_register (lr, ip)
- mov r1, r0
-
- mov r0, #0xffff0fff
- mov lr, pc
- sub pc, r0, #31
-
+ mov r1, r0
+ GET_TLS(r2)
ldr r2, 1f
#ifdef __thumb__
2: add r2, r2, pc
@@ -54,7 +48,7 @@ __syscall_error:
#endif
str r1, [r0, r2]
mvn r0, #0
- DO_RET(ip)
+ DO_RET(lr)
1: .word errno(gottpoff) + (. - 2b - PC_OFS)
#elif RTLD_PRIVATE_ERRNO
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 a5f9b4d..1bc5eab 100644
--- a/ports/sysdeps/unix/sysv/linux/arm/clone.S
+++ b/ports/sysdeps/unix/sysv/linux/arm/clone.S
@@ -74,9 +74,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(lr)
mov r1, r0
tst ip, #CLONE_VM
ldr r7, =SYS_ify(getpid)
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 ff88510..c731cd7 100644
--- a/ports/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S
+++ b/ports/sysdeps/unix/sysv/linux/arm/nptl/pt-vfork.S
@@ -19,15 +19,7 @@
/* Save the PID value. */
#define SAVE_PID \
- 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. */ \
- ldr lr, [sp], #4; /* Restore LR. */ \
- cfi_adjust_cfa_offset (-4); \
- cfi_restore (lr); \
+ GET_TLS(r2); \
NEGOFF_ADJ_BASE2(r2, r0, PID_OFFSET); /* Save the TLS addr in r2. */ \
ldr r3, NEGOFF_OFF1(r2, PID_OFFSET); /* Load the saved PID. */ \
rsb r0, r3, #0; /* Negate it. */ \
diff --git a/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h b/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h
index 47d4c70..d5e666b 100644
--- a/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h
+++ b/ports/sysdeps/unix/sysv/linux/arm/nptl/sysdep-cancel.h
@@ -216,7 +216,7 @@ extern int __local_multiple_threads attribute_hidden;
stmfd sp!, {r0, lr}; \
cfi_adjust_cfa_offset (8); \
cfi_rel_offset (lr, 4); \
- bl __aeabi_read_tp; \
+ GET_TLS(lr); \
NEGOFF_ADJ_BASE(r0, MULTIPLE_THREADS_OFFSET); \
ldr ip, NEGOFF_OFF1(r0, MULTIPLE_THREADS_OFFSET); \
ldmfd sp!, {r0, lr}; \
diff --git a/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S b/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S
index c4be1e2..accecf2 100644
--- a/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S
+++ b/ports/sysdeps/unix/sysv/linux/arm/nptl/vfork.S
@@ -19,15 +19,7 @@
/* Save the PID value. */
#define SAVE_PID \
- 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. */ \
- ldr lr, [sp], #4; /* Restore LR. */ \
- cfi_adjust_cfa_offset (-4); \
- cfi_restore (lr); \
+ GET_TLS(r2); \
NEGOFF_ADJ_BASE2(r2, r0, PID_OFFSET); /* Save the TLS addr in r2. */ \
ldr r3, NEGOFF_OFF1(r2, PID_OFFSET); /* Load the saved PID. */ \
rsbs r0, r3, #0; /* Negate it. */ \
diff --git a/ports/sysdeps/unix/sysv/linux/arm/sysdep.h b/ports/sysdeps/unix/sysv/linux/arm/sysdep.h
index 89208a9..01d8123 100644
--- a/ports/sysdeps/unix/sysv/linux/arm/sysdep.h
+++ b/ports/sysdeps/unix/sysv/linux/arm/sysdep.h
@@ -45,6 +45,36 @@
#ifdef __ASSEMBLER__
+/* Internal macro calling the linux kernel kuser_get_tls helper.
+ 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_BODY \
+ movw r0, #0x0fe0; \
+ movt r0, #0xffff; \
+ blx r0
+#else
+# define GET_TLS_BODY \
+ 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
+
+/* Helper to get the TLS base pointer. Save LR in TMP, return in R0,
+ and no other registers clobbered. TMP may be LR itself to indicate
+ that no save is necessary. */
+#undef GET_TLS
+#define GET_TLS(TMP) \
+ .ifnc TMP, lr; \
+ mov TMP, lr; \
+ cfi_register (lr, TMP); \
+ GET_TLS_BODY; \
+ mov lr, TMP; \
+ cfi_restore (lr); \
+ .else; \
+ GET_TLS_BODY; \
+ .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
next prev parent reply other threads:[~2013-03-01 17:36 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-01 17:36 [PATCH v2 00/14] ARM improvements Richard Henderson
2013-03-01 17:36 ` [PATCH v2 09/14] arm: Tidy architecture selection Richard Henderson
2013-03-01 17:55 ` Roland McGrath
2013-03-05 2:01 ` Joseph S. Myers
2013-03-01 17:36 ` [PATCH v2 05/14] arm: Use push/pop mnemonics Richard Henderson
2013-03-01 17:36 ` [PATCH v2 14/14] arm: Add optimized add_n and sub_n Richard Henderson
2013-03-01 17:59 ` Roland McGrath
2013-03-06 0:53 ` Joseph S. Myers
2013-03-01 17:36 ` [PATCH v2 13/14] arm: Add optimized submul_1 Richard Henderson
2013-03-01 17:58 ` Roland McGrath
2013-03-06 1:14 ` Joseph S. Myers
2013-03-01 17:36 ` [PATCH v2 11/14] arm: Add optimized ffs for armv6t2 Richard Henderson
2013-03-05 2:08 ` Joseph S. Myers
2013-03-06 15:52 ` Richard Henderson
2013-03-01 17:36 ` [PATCH v2 06/14] arm: Delete LOADREGS macro Richard Henderson
2013-03-01 17:36 ` [PATCH v2 08/14] arm: Unless arm4t, pop return address directly into pc Richard Henderson
2013-03-01 17:36 ` [PATCH v2 10/14] arm: Implement hard-tp for GET_TLS Richard Henderson
2013-03-01 17:55 ` Roland McGrath
2013-03-05 2:01 ` Joseph S. Myers
2013-03-01 17:36 ` Richard Henderson [this message]
2013-03-01 17:57 ` [PATCH v2 03/14] arm: Introduce and use GET_TLS Roland McGrath
2013-03-05 1:45 ` Joseph S. Myers
2013-03-01 17:36 ` [PATCH v2 04/14] arm: Enable thumb2 mode in assembly files Richard Henderson
2013-03-01 17:36 ` [PATCH v2 01/14] arm: Introduce and use LDST_PCREL Richard Henderson
2013-03-04 17:47 ` Joseph S. Myers
2013-03-01 17:36 ` [PATCH v2 12/14] arm: Add optimized addmul_1 Richard Henderson
2013-03-01 17:58 ` Roland McGrath
2013-03-01 18:00 ` Roland McGrath
2013-03-06 1:18 ` Joseph S. Myers
2013-10-25 22:13 ` Roland McGrath
2013-03-06 1:11 ` Joseph S. Myers
2013-03-01 17:36 ` [PATCH v2 02/14] arm: Introduce and use NEGOFF series of macros Richard Henderson
2013-03-01 17:57 ` Roland McGrath
2013-03-05 1:42 ` Joseph S. Myers
2013-03-01 17:36 ` [PATCH v2 07/14] arm: Commonize BX conditionals Richard Henderson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1362159320-5934-4-git-send-email-rth@twiddle.net \
--to=rth@twiddle.net \
--cc=joseph@codesourcery.com \
--cc=libc-ports@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).