mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
* sysdeps/generic/ldsodefs.h (struct rtld_global): Move all [USE_TLS]
members to the end, so a libpthread compiled with !USE_TLS will still find other members properly. * sysdeps/i386/i486/bits/string.h (__strcpy_g): Add dummy output operand for DEST memory. Fix dummy input operand to use SRC. Reported by Davin McCall <davmac@ozonline.com.au>. * sysdeps/generic/libc-tls.c (__libc_setup_tls): Account for TCB alignment when initializing the DTV entry. * elf/dl-load.c (_dl_map_object_from_fd): If we hit a TLS segment when TLS has not been set up, try to set it up if we can. * elf/tst-tls4.c: Revert last change. * elf/tst-tls5.c: Likewise. * elf/tst-tls6.c: Likewise. * elf/tst-tls7.c: Likewise. * elf/tst-tls8.c: Likewise. * elf/tst-tls9.c: Likewise. * sysdeps/generic/dl-tls.c [SHARED] (_dl_tls_setup): New function. * sysdeps/generic/ldsodefs.h: Declare it. * elf/Versions (ld: GLIBC_PRIVATE): Add it. * sysdeps/generic/libc-tls.c (init_slotinfo): New static inline function, broken out of __libc_setup_tls. (init_static_tls): Likewise. (__libc_setup_tls): Call them. (_dl_tls_setup): New function, uses new subroutines. * elf/dl-close.c (free_slotinfo): Make argument pointer to pointer. Clear the pointer when returning true. (libc_freeres_fn) [SHARED]: If GL(dl_initial_dtv) is null, free the first element of the slotinfo list too. * sysdeps/generic/dl-tls.c (_dl_determine_tlsoffset): Define only if [SHARED]. * sysdeps/generic/ldsodefs.h (_dl_next_tls_modid): Declare as hidden. (_dl_determine_tlsoffset): Likewise. * elf/rtld.c (_dl_initial_error_catch_tsd): Renamed from startup_error_tsd, made global. (dl_main): Update initialization. * elf/dl-tsd.c: Likewise. * sysdeps/generic/ldsodefs.h: Declare it.
This commit is contained in:
@ -74,6 +74,35 @@ size_t _dl_tls_generation;
|
||||
TLS_INIT_HELPER
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
init_slotinfo (void)
|
||||
{
|
||||
/* Create the slotinfo list. */
|
||||
static_slotinfo.si.len = (((char *) (&static_slotinfo + 1)
|
||||
- (char *) &static_slotinfo.si.slotinfo[0])
|
||||
/ sizeof static_slotinfo.si.slotinfo[0]);
|
||||
// static_slotinfo.si.next = NULL; already zero
|
||||
|
||||
/* The slotinfo list. Will be extended by the code doing dynamic
|
||||
linking. */
|
||||
GL(dl_tls_max_dtv_idx) = 1;
|
||||
GL(dl_tls_dtv_slotinfo_list) = &static_slotinfo.si;
|
||||
}
|
||||
|
||||
static inline void
|
||||
init_static_tls (size_t memsz, size_t align)
|
||||
{
|
||||
/* That is the size of the TLS memory for this object. The initialized
|
||||
value of _dl_tls_static_size is provided by dl-open.c to request some
|
||||
surplus that permits dynamic loading of modules with IE-model TLS. */
|
||||
GL(dl_tls_static_size) = roundup (memsz + GL(dl_tls_static_size),
|
||||
TLS_TCB_ALIGN);
|
||||
GL(dl_tls_static_used) = memsz;
|
||||
/* The alignment requirement for the static TLS block. */
|
||||
GL(dl_tls_static_align) = align;
|
||||
/* Number of elements in the static TLS block. */
|
||||
GL(dl_tls_static_nelem) = GL(dl_tls_max_dtv_idx);
|
||||
}
|
||||
|
||||
void
|
||||
__libc_setup_tls (size_t tcbsize, size_t tcbalign)
|
||||
@ -117,8 +146,8 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
|
||||
to request some surplus that permits dynamic loading of modules with
|
||||
IE-model TLS. */
|
||||
# if TLS_TCB_AT_TP
|
||||
tlsblock = __sbrk (roundup (memsz, tcbalign) + tcbsize + max_align
|
||||
+ GL(dl_tls_static_size));
|
||||
tcb_offset = roundup (memsz + GL(dl_tls_static_size), tcbalign);
|
||||
tlsblock = __sbrk (tcb_offset + tcbsize + max_align);
|
||||
# elif TLS_DTV_AT_TP
|
||||
tlsblock = __sbrk (roundup (tcbsize, align) + memsz + max_align
|
||||
+ GL(dl_tls_static_size));
|
||||
@ -138,10 +167,13 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
|
||||
|
||||
/* Initialize the TLS block. */
|
||||
# if TLS_TCB_AT_TP
|
||||
static_dtv[2].pointer = tlsblock;
|
||||
static_dtv[2].pointer = ((char *) tlsblock + tcb_offset
|
||||
- roundup (memsz, align));
|
||||
static_map.l_tls_offset = roundup (memsz, align);
|
||||
# elif TLS_DTV_AT_TP
|
||||
tcb_offset = roundup (tcbsize, align);
|
||||
static_dtv[2].pointer = (char *) tlsblock + tcb_offset;
|
||||
static_map.l_tls_offset = tcb_offset;
|
||||
# else
|
||||
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
|
||||
# endif
|
||||
@ -152,8 +184,6 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
|
||||
|
||||
/* Initialize the thread pointer. */
|
||||
# if TLS_TCB_AT_TP
|
||||
tcb_offset = roundup (memsz, tcbalign);
|
||||
|
||||
INSTALL_DTV ((char *) tlsblock + tcb_offset, static_dtv);
|
||||
|
||||
TLS_INIT_TP ((char *) tlsblock + tcb_offset, 0);
|
||||
@ -171,39 +201,38 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
|
||||
static_map.l_tls_blocksize = memsz;
|
||||
static_map.l_tls_initimage = initimage;
|
||||
static_map.l_tls_initimage_size = filesz;
|
||||
static_map.l_tls_offset = tcb_offset;
|
||||
static_map.l_type = lt_executable;
|
||||
static_map.l_tls_modid = 1;
|
||||
|
||||
/* Create the slotinfo list. */
|
||||
static_slotinfo.si.len = (((char *) (&static_slotinfo + 1)
|
||||
- (char *) &static_slotinfo.si.slotinfo[0])
|
||||
/ sizeof static_slotinfo.si.slotinfo[0]);
|
||||
// static_slotinfo.si.next = NULL; already zero
|
||||
|
||||
static_slotinfo.si.slotinfo[1].gen = 0;
|
||||
init_slotinfo ();
|
||||
// static_slotinfo.si.slotinfo[1].gen = 0; already zero
|
||||
static_slotinfo.si.slotinfo[1].map = &static_map;
|
||||
|
||||
/* The slotinfo list. Will be extended by the code doing dynamic
|
||||
linking. */
|
||||
GL(dl_tls_max_dtv_idx) = 1;
|
||||
GL(dl_tls_dtv_slotinfo_list) = &static_slotinfo.si;
|
||||
|
||||
memsz = roundup (memsz, align ?: 1);
|
||||
|
||||
# if TLS_TCB_AT_TP
|
||||
memsz += tcbsize;
|
||||
# endif
|
||||
|
||||
/* That is the size of the TLS memory for this object. The initialized
|
||||
value of _dl_tls_static_size is provided by dl-open.c to request some
|
||||
surplus that permits dynamic loading of modules with IE-model TLS. */
|
||||
GL(dl_tls_static_size) = roundup (memsz + GL(dl_tls_static_size),
|
||||
TLS_TCB_ALIGN);
|
||||
GL(dl_tls_static_used) = memsz;
|
||||
/* The alignment requirement for the static TLS block. */
|
||||
GL(dl_tls_static_align) = MAX (TLS_TCB_ALIGN, max_align);
|
||||
/* Number of elements in the static TLS block. */
|
||||
GL(dl_tls_static_nelem) = GL(dl_tls_max_dtv_idx);
|
||||
init_static_tls (memsz, MAX (TLS_TCB_ALIGN, max_align));
|
||||
}
|
||||
|
||||
/* This is called only when the data structure setup was skipped at startup,
|
||||
when there was no need for it then. Now we have dynamically loaded
|
||||
something needing TLS, or libpthread needs it. */
|
||||
int
|
||||
internal_function
|
||||
_dl_tls_setup (void)
|
||||
{
|
||||
init_slotinfo ();
|
||||
init_static_tls (
|
||||
# if TLS_TCB_AT_TP
|
||||
TLS_TCB_SIZE,
|
||||
# else
|
||||
0,
|
||||
# endif
|
||||
TLS_TCB_ALIGN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user