This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH roland/arm] ARM: Rewrite sysdeps/arm/tls-macros.h
- From: Roland McGrath <roland at hack dot frob dot com>
- To: "GNU C. Library" <libc-alpha at sourceware dot org>
- Date: Thu, 5 Mar 2015 15:40:28 -0800 (PST)
- Subject: [PATCH roland/arm] ARM: Rewrite sysdeps/arm/tls-macros.h
- Authentication-results: sourceware.org; auth=none
I've rewritten the ARM tls-macros.h so that there is less repeated
boilerplate assembly and a bit less overall done in assembly that can
be in C, and so it's friendly to systems that do not allow random
literal pool words in the code segment (like NaCl). The file is
basically wholly replaced but diff finds some useless context, so it's
a bit easier to read the new file than to read the patch.
I've tested armv7l-linux-gnueabihf both with the compiler's default
-mthumb and with explicit -marm; there are no regressions. I've also
tested the ARM_PCREL_MOVW_OK case in the out-of-tree arm-nacl port.
OK?
Thanks,
Roland
* sysdeps/arm/tls-macros.h: Include <sysdep.h>.
(GET_SPECIAL_RELOC, GET_SPECIAL_PCREL): New macros to encapsulate
all the necessary asm magic in one place.
(TLS_LE, TLS_IE, TLS_LD, TLS_GD): Rewritten as C expressions
using those.
--- a/sysdeps/arm/tls-macros.h
+++ b/sysdeps/arm/tls-macros.h
@@ -1,78 +1,72 @@
+#include <sysdep.h> /* For ARCH_HAS_T2. */
+
#ifdef __thumb2__
-#define ARM_PC_OFFSET "4"
+# define ARM_PC_OFFSET "4"
#else
-#define ARM_PC_OFFSET "8"
+# define ARM_PC_OFFSET "8"
#endif
-#define TLS_LE(x) \
- ({ int *__result; \
- void *tp = __builtin_thread_pointer (); \
- asm ("ldr %0, 1f; " \
- "add %0, %1, %0; " \
- "b 2f; " \
- ".align 2; " \
- "1: .word " #x "(tpoff); " \
- "2: " \
- : "=&r" (__result) : "r" (tp)); \
- __result; })
-
-#ifdef __thumb2__
-#define TLS_IE(x) \
- ({ int *__result; \
- void *tp = __builtin_thread_pointer (); \
- asm ("ldr %0, 1f; " \
- "3: add %0, pc, %0;" \
- "ldr %0, [%0];" \
- "add %0, %1, %0; " \
- "b 2f; " \
- ".align 2; " \
- "1: .word " #x "(gottpoff) + (. - 3b - 4); " \
- "2: " \
- : "=&r" (__result) : "r" (tp)); \
- __result; })
+/* Returns the address of data containing ".word SYMBOL(RELOC)". */
+#if defined (ARCH_HAS_T2) && !defined (PIC)
+# define GET_SPECIAL_RELOC(symbol, reloc) \
+ ({ \
+ int *__##symbol##_rodata; \
+ asm ("movw %0, #:lower16:1f\n" \
+ "movt %0, #:upper16:1f\n" \
+ ".pushsection .rodata.cst4, \"aM\", %%progbits, 4\n" \
+ ".balign 4\n" \
+ "1: .word " #symbol "(" #reloc ")\n" \
+ ".popsection" \
+ : "=r" (__##symbol##_rodata)); \
+ __##symbol##_rodata; \
+ })
+#elif defined (ARCH_HAS_T2) && defined (PIC) && ARM_PCREL_MOVW_OK
+# define GET_SPECIAL_RELOC(symbol, reloc) \
+ ({ \
+ int *__##symbol##_rodata; \
+ asm ("movw %0, #:lower16:1f - 2f - " ARM_PC_OFFSET "\n" \
+ "movt %0, #:upper16:1f - 2f - " ARM_PC_OFFSET "\n" \
+ ".pushsection .rodata.cst4, \"aM\", %%progbits, 4\n" \
+ ".balign 4\n" \
+ "1: .word " #symbol "(" #reloc ")\n" \
+ ".popsection\n" \
+ "2: add %0, %0, pc" \
+ : "=r" (__##symbol##_rodata)); \
+ __##symbol##_rodata; \
+ })
#else
-#define TLS_IE(x) \
- ({ int *__result; \
- void *tp = __builtin_thread_pointer (); \
- asm ("ldr %0, 1f; " \
- "3: ldr %0, [pc, %0];" \
- "add %0, %1, %0; " \
- "b 2f; " \
- ".align 2; " \
- "1: .word " #x "(gottpoff) + (. - 3b - 8); " \
- "2: " \
- : "=&r" (__result) : "r" (tp)); \
- __result; })
+# define GET_SPECIAL_RELOC(symbol, reloc) \
+ ({ \
+ int *__##symbol##_rodata; \
+ asm ("adr %0, 1f\n" \
+ "b 2f\n" \
+ ".balign 4\n" \
+ "1: .word " #symbol "(" #reloc ")\n" \
+ "2:" \
+ : "=r" (__##symbol##_rodata)); \
+ __##symbol##_rodata; \
+ })
#endif
-#define TLS_LD(x) \
- ({ char *__result; \
- int __offset; \
- extern void *__tls_get_addr (void *); \
- asm ("ldr %0, 2f; " \
- "1: add %0, pc, %0; " \
- "b 3f; " \
- ".align 2; " \
- "2: .word " #x "(tlsldm) + (. - 1b - "ARM_PC_OFFSET"); " \
- "3: " \
- : "=r" (__result)); \
- __result = (char *)__tls_get_addr (__result); \
- asm ("ldr %0, 1f; " \
- "b 2f; " \
- ".align 2; " \
- "1: .word " #x "(tlsldo); " \
- "2: " \
- : "=r" (__offset)); \
- (int *) (__result + __offset); })
+/* Returns the pointer value (SYMBOL(RELOC) + pc - PC_OFS). */
+#define GET_SPECIAL_PCREL(symbol, reloc) \
+ ({ \
+ int *__##symbol##_rodata = GET_SPECIAL_RELOC (symbol, reloc); \
+ (void *) ((int) __##symbol##_rodata + *__##symbol##_rodata); \
+ })
+
+#define TLS_LE(x) \
+ (__builtin_thread_pointer () + *GET_SPECIAL_RELOC (x, tpoff))
+
+#define TLS_IE(x) \
+ ((int *) (__builtin_thread_pointer () \
+ + *(int *) GET_SPECIAL_PCREL (x, gottpoff)))
+
+extern void *__tls_get_addr (void *);
+
+#define TLS_LD(x) \
+ ((int *) (__tls_get_addr (GET_SPECIAL_PCREL (x, tlsldm)) \
+ + *GET_SPECIAL_RELOC (x, tlsldo)))
-#define TLS_GD(x) \
- ({ int *__result; \
- extern void *__tls_get_addr (void *); \
- asm ("ldr %0, 2f; " \
- "1: add %0, pc, %0; " \
- "b 3f; " \
- ".align 2; " \
- "2: .word " #x "(tlsgd) + (. - 1b - "ARM_PC_OFFSET"); " \
- "3: " \
- : "=r" (__result)); \
- (int *)__tls_get_addr (__result); })
+#define TLS_GD(x) \
+ ((int *) __tls_get_addr (GET_SPECIAL_PCREL (x, tlsgd)))