mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-05 01:00:14 +00:00
[BZ #16214] S/390: Fix TLS GOT pointer setup.
This commit is contained in:
parent
7475aef5fa
commit
acd98a8ed1
13
ChangeLog
13
ChangeLog
@ -1,3 +1,16 @@
|
|||||||
|
2013-11-29 Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||||
|
Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
|
||||||
|
|
||||||
|
[BZ #16214]
|
||||||
|
* sysdeps/s390/dl-tls.h (__TLS_GET_ADDR): Invoke
|
||||||
|
__tls_get_addr_internal instead of __tls_get_offset in order to
|
||||||
|
avoid GOT pointer dependency. Make rtld export
|
||||||
|
__tls_get_addr_internal@@GLIBC_PRIVATE while still hiding
|
||||||
|
__tls_get_addr since we are a __tls_get_offset platform.
|
||||||
|
* sysdeps/s390/s390-64/tls-macros.h (TLS_IE PIC): Don't rely on
|
||||||
|
GOT pointer being set up before.
|
||||||
|
* sysdeps/s390/s390-32/tls-macros.h (TLS_IE PIC): Likewise.
|
||||||
|
|
||||||
2013-11-28 Joseph Myers <joseph@codesourcery.com>
|
2013-11-28 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
* manual/math.texi (Errors in Math Functions): Document accuracy
|
* manual/math.texi (Errors in Math Functions): Document accuracy
|
||||||
|
@ -3,4 +3,8 @@ ld {
|
|||||||
# runtime interface to TLS
|
# runtime interface to TLS
|
||||||
__tls_get_offset;
|
__tls_get_offset;
|
||||||
}
|
}
|
||||||
|
GLIBC_PRIVATE {
|
||||||
|
# Exported by ld used by libc.
|
||||||
|
__tls_get_addr_internal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,26 @@ typedef struct
|
|||||||
|
|
||||||
|
|
||||||
#ifdef SHARED
|
#ifdef SHARED
|
||||||
/* This is the prototype for the GNU version. */
|
|
||||||
extern void *__tls_get_addr (tls_index *ti) attribute_hidden;
|
|
||||||
extern unsigned long __tls_get_offset (unsigned long got_offset);
|
extern unsigned long __tls_get_offset (unsigned long got_offset);
|
||||||
|
|
||||||
# ifdef IS_IN_rtld
|
# ifdef IS_IN_rtld
|
||||||
|
|
||||||
|
# include <shlib-compat.h>
|
||||||
|
|
||||||
|
extern void *__tls_get_addr (tls_index *ti) attribute_hidden;
|
||||||
|
/* Make a temporary alias of __tls_get_addr to remove the hidden
|
||||||
|
attribute. Then export __tls_get_addr as __tls_get_addr_internal
|
||||||
|
for use from libc. We do not want to export __tls_get_addr, but we
|
||||||
|
do need to use it from libc when looking up the address of a TLS
|
||||||
|
variable. We don't use __tls_get_offset because it requires r12 to
|
||||||
|
be setup and that might not always be true. Either way it's more
|
||||||
|
optimal to use __tls_get_addr directly (that's what
|
||||||
|
__tls_get_offset does anyways). */
|
||||||
|
strong_alias (__tls_get_addr, __tls_get_addr_internal_tmp);
|
||||||
|
versioned_symbol (ld, __tls_get_addr_internal_tmp,
|
||||||
|
__tls_get_addr_internal, GLIBC_PRIVATE);
|
||||||
|
|
||||||
/* The special thing about the s390 TLS ABI is that we do not have the
|
/* The special thing about the s390 TLS ABI is that we do not have the
|
||||||
standard __tls_get_addr function but the __tls_get_offset function
|
standard __tls_get_addr function but the __tls_get_offset function
|
||||||
which differs in two important aspects:
|
which differs in two important aspects:
|
||||||
@ -63,14 +78,20 @@ __tls_get_offset:\n\
|
|||||||
1: .long __tls_get_addr - 0b\n\
|
1: .long __tls_get_addr - 0b\n\
|
||||||
");
|
");
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# else /* IS_IN_rtld */
|
||||||
|
extern void *__tls_get_addr_internal (tls_index *ti);
|
||||||
|
# endif /* !IS_IN_rtld */
|
||||||
|
|
||||||
# define GET_ADDR_OFFSET \
|
# define GET_ADDR_OFFSET \
|
||||||
(ti->ti_offset - (unsigned long) __builtin_thread_pointer ())
|
(ti->ti_offset - (unsigned long) __builtin_thread_pointer ())
|
||||||
|
|
||||||
|
/* Use the privately exported __tls_get_addr_internal instead of
|
||||||
|
__tls_get_offset in order to avoid the __tls_get_offset special
|
||||||
|
linkage requiring the GOT pointer to be set up in r12. The
|
||||||
|
compiler will take care of setting up r12 only if itself issued the
|
||||||
|
__tls_get_offset call. */
|
||||||
# define __TLS_GET_ADDR(__ti) \
|
# define __TLS_GET_ADDR(__ti) \
|
||||||
({ extern char _GLOBAL_OFFSET_TABLE_[] attribute_hidden; \
|
({ (void *) __tls_get_addr_internal ((char *) (__ti)) \
|
||||||
(void *) __tls_get_offset ((char *) (__ti) - _GLOBAL_OFFSET_TABLE_) \
|
|
||||||
+ (unsigned long) __builtin_thread_pointer (); })
|
+ (unsigned long) __builtin_thread_pointer (); })
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,12 +8,15 @@
|
|||||||
|
|
||||||
#ifdef PIC
|
#ifdef PIC
|
||||||
# define TLS_IE(x) \
|
# define TLS_IE(x) \
|
||||||
({ unsigned long __offset; \
|
({ unsigned long __offset, __got; \
|
||||||
asm ("bras %0,1f\n" \
|
asm ("bras %0,1f\n" \
|
||||||
"0:\t.long " #x "@gotntpoff\n" \
|
"0:\t.long _GLOBAL_OFFSET_TABLE_-0b\n\t" \
|
||||||
"1:\tl %0,0(%0)\n\t" \
|
".long " #x "@gotntpoff\n" \
|
||||||
"l %0,0(%0,%%r12):tls_load:" #x \
|
"1:\tl %1,0(%0)\n\t" \
|
||||||
: "=&a" (__offset) : : "cc" ); \
|
"la %1,0(%1,%0)\n\t" \
|
||||||
|
"l %0,4(%0)\n\t" \
|
||||||
|
"l %0,0(%0,%1):tls_load:" #x "\n" \
|
||||||
|
: "=&a" (__offset), "=&a" (__got) : : "cc" ); \
|
||||||
(int *) (__builtin_thread_pointer() + __offset); })
|
(int *) (__builtin_thread_pointer() + __offset); })
|
||||||
#else
|
#else
|
||||||
# define TLS_IE(x) \
|
# define TLS_IE(x) \
|
||||||
|
@ -8,12 +8,13 @@
|
|||||||
|
|
||||||
#ifdef PIC
|
#ifdef PIC
|
||||||
# define TLS_IE(x) \
|
# define TLS_IE(x) \
|
||||||
({ unsigned long __offset; \
|
({ unsigned long __offset, __got; \
|
||||||
asm ("bras %0,1f\n" \
|
asm ("bras %0,0f\n\t" \
|
||||||
"0:\t.quad " #x "@gotntpoff\n" \
|
".quad " #x "@gotntpoff\n" \
|
||||||
"1:\tlg %0,0(%0)\n\t" \
|
"0:\tlarl %1,_GLOBAL_OFFSET_TABLE_\n\t" \
|
||||||
"lg %0,0(%0,%%r12):tls_load:" #x \
|
"lg %0,0(%0)\n\t" \
|
||||||
: "=&a" (__offset) : : "cc" ); \
|
"lg %0,0(%0,%1):tls_load:" #x "\n" \
|
||||||
|
: "=&a" (__offset), "=&a" (__got) : : "cc" ); \
|
||||||
(int *) (__builtin_thread_pointer() + __offset); })
|
(int *) (__builtin_thread_pointer() + __offset); })
|
||||||
#else
|
#else
|
||||||
# define TLS_IE(x) \
|
# define TLS_IE(x) \
|
||||||
|
Loading…
Reference in New Issue
Block a user