[PATCH][BZ #16214] Fix TLS access on S390 with -march=z10
Carlos O'Donell
carlos@redhat.com
Wed Nov 27 20:34:00 GMT 2013
On 11/25/2013 12:50 AM, Siddhesh Poyarekar wrote:
> +# ifdef __s390x__
> +# define LOAD_R12(r12) asm ("lgr %0,%%r12" : "=r" (r12) ::)
> +# elif defined __s390__
> +# define LOAD_R12(r12) asm ("lr %0,%%r12" : "=r" (r12) ::)
> +# endif
> +
> # define GET_ADDR_OFFSET \
> (ti->ti_offset - (unsigned long) __builtin_thread_pointer ())
>
> +/* Subtract contents of r12 from __TI. We don't really care if this is the
> + GOT pointer. */
> # define __TLS_GET_ADDR(__ti) \
> - ({ extern char _GLOBAL_OFFSET_TABLE_[] attribute_hidden; \
> - (void *) __tls_get_offset ((char *) (__ti) - _GLOBAL_OFFSET_TABLE_) \
> - + (unsigned long) __builtin_thread_pointer (); })
> +({ \
> + unsigned long int r12; \
> + LOAD_R12 (r12); \
> + ((void *) __tls_get_offset ((unsigned long int) (__ti) - r12) \
> + + (unsigned long) __builtin_thread_pointer ()); \
> +})
Something was bothering me about doing it this way and then I remembered
that it can't be done this way because the compiler might change r12
at any point.
The compiler may change r12 between when we load it and when it gets
used by __tls_get_offset, this whole sequence has to be written in
assembly (as previously suggested by Jakub Jelinek).
Otherwise it is going to be fragile.
Cheers,
Carlos.
More information about the Libc-alpha
mailing list