* elf/tst-tls4.c: Define an unused TLS variable here, so that no lazy

TLS setup is required.
	* 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.

	* elf/rtld.c (dl_main): Remove [! SHARED] conditional from
	`if (GL(dl_tls_max_dtv_idx) > 0)' tests for doing TLS setup.
	* elf/dl-close.c (libc_freeres_fn): Check GL(dl_tls_dtv_slotinfo_list)
	for being null before calling free_slotinfo.
	* elf/dl-load.c (_dl_map_object_from_fd) [SHARED]: For PT_TLS in
	dynamic loading, bail with error if GL(dl_tls_max_dtv_idx) is zero.
This commit is contained in:
Roland McGrath 2002-12-03 01:51:07 +00:00
parent f87277f2cd
commit 2d14868942
12 changed files with 143 additions and 23 deletions

View File

@ -1,3 +1,20 @@
2002-12-02 Roland McGrath <roland@redhat.com>
* elf/tst-tls4.c: Define an unused TLS variable here, so that no lazy
TLS setup is required.
* 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.
* elf/rtld.c (dl_main): Remove [! SHARED] conditional from
`if (GL(dl_tls_max_dtv_idx) > 0)' tests for doing TLS setup.
* elf/dl-close.c (libc_freeres_fn): Check GL(dl_tls_dtv_slotinfo_list)
for being null before calling free_slotinfo.
* elf/dl-load.c (_dl_map_object_from_fd) [SHARED]: For PT_TLS in
dynamic loading, bail with error if GL(dl_tls_max_dtv_idx) is zero.
2002-11-30 Bruno Haible <bruno@clisp.org>
* iconv/gconv.h (__gconv_btowc_fct): New typedef.

View File

@ -476,12 +476,15 @@ libc_freeres_fn (free_mem)
}
#ifdef USE_TLS
/* Free the memory allocated for the dtv slotinfo array. We can do
this only if all modules which used this memory are unloaded.
Also, the first element of the list does not have to be
deallocated. It was allocated in the dynamic linker (i.e., with
a different malloc). */
if (free_slotinfo (GL(dl_tls_dtv_slotinfo_list)->next))
GL(dl_tls_dtv_slotinfo_list)->next = NULL;
if (USE___THREAD || GL(dl_tls_dtv_slotinfo_list) != NULL)
{
/* Free the memory allocated for the dtv slotinfo array. We can do
this only if all modules which used this memory are unloaded.
Also, the first element of the list does not have to be
deallocated. It was allocated in the dynamic linker (i.e., with
a different malloc). */
if (free_slotinfo (GL(dl_tls_dtv_slotinfo_list)->next))
GL(dl_tls_dtv_slotinfo_list)->next = NULL;
}
#endif
}

View File

@ -942,7 +942,19 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
case PT_TLS:
#ifdef USE_TLS
if (ph->p_memsz > 0)
if (ph->p_memsz == 0)
/* Nothing to do for an empty segment. */
break;
/* If not loading the initial set of shared libraries,
check whether we should permit loading a TLS segment. */
if (
# ifdef SHARED
__builtin_expect (l->l_type == lt_library, 1) ||
# endif
/* If GL(dl_tls_max_dtv_idx) == 0, then rtld.c did not
set up TLS data structures, so don't use them now. */
__builtin_expect (GL(dl_tls_max_dtv_idx), 1) != 0)
{
l->l_tls_blocksize = ph->p_memsz;
l->l_tls_align = ph->p_align;
@ -953,14 +965,20 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
/* Assign the next available module ID. */
l->l_tls_modid = _dl_next_tls_modid ();
break;
}
#else
if (l->l_prev == NULL)
/* We are loading the executable itself when the dynamic linker
was executed directly. The setup will happen later. */
break;
#endif
/* Uh-oh, the binary expects TLS support but we cannot
provide it. */
errval = 0;
errstring = N_("cannot handle TLS data");
goto call_lose;
#endif
break;
}

View File

@ -1139,12 +1139,14 @@ of this helper program; chances are you did not intend to run this program.\n\
/* Assign a module ID. */
GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
# ifndef SHARED
/* If dynamic loading of modules with TLS is impossible we do not
have to initialize any of the TLS functionality unless any of the
initial modules uses TLS. */
/* We do not initialize any of the TLS functionality unless any of the
initial modules uses TLS. This makes dynamic loading of modules with
TLS impossible, but to support it requires either eagerly doing setup
now or lazily doing it later. Doing it now makes us incompatible with
an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
used. Trying to do it lazily is too hairy to try when there could be
multiple threads (from a non-TLS-using libpthread). */
if (GL(dl_tls_max_dtv_idx) > 0)
# endif
{
struct link_map *l;
size_t nelem;
@ -1555,9 +1557,7 @@ cannot allocate TLS data structures for initial thread");
GL(dl_initial_searchlist) = *GL(dl_main_searchlist);
#ifdef USE_TLS
# ifndef SHARED
if (GL(dl_tls_max_dtv_idx) > 0)
# endif
if (GL(dl_tls_max_dtv_idx) > 0 || USE___THREAD)
{
/* Now that we have completed relocation, the initializer data
for the TLS blocks has its final values and we can copy them

View File

@ -4,6 +4,14 @@
#include <tls.h>
#ifdef USE_TLS
# include "tls-macros.h"
/* This gives the executable a TLS segment so that even if the libc.so
it loads has none (i.e. --with-tls --without-__thread), ld.so will
permit loading of objects with TLS segments. */
COMMON_INT_DEF(loser);
#endif
#define TEST_FUNCTION do_test ()
static int

View File

@ -4,6 +4,15 @@
#include <tls.h>
#ifdef USE_TLS
# include "tls-macros.h"
/* This gives the executable a TLS segment so that even if the libc.so
it loads has none (i.e. --with-tls --without-__thread), ld.so will
permit loading of objects with TLS segments. */
COMMON_INT_DEF(loser);
#endif
#define TEST_FUNCTION do_test ()
static int

View File

@ -5,6 +5,15 @@
#include <link.h>
#include <tls.h>
#ifdef USE_TLS
# include "tls-macros.h"
/* This gives the executable a TLS segment so that even if the libc.so
it loads has none (i.e. --with-tls --without-__thread), ld.so will
permit loading of objects with TLS segments. */
COMMON_INT_DEF(loser);
#endif
#define TEST_FUNCTION do_test ()
static int

View File

@ -5,6 +5,15 @@
#include <link.h>
#include <tls.h>
#ifdef USE_TLS
# include "tls-macros.h"
/* This gives the executable a TLS segment so that even if the libc.so
it loads has none (i.e. --with-tls --without-__thread), ld.so will
permit loading of objects with TLS segments. */
COMMON_INT_DEF(loser);
#endif
#define TEST_FUNCTION do_test ()
static int

View File

@ -5,6 +5,15 @@
#include <link.h>
#include <tls.h>
#ifdef USE_TLS
# include "tls-macros.h"
/* This gives the executable a TLS segment so that even if the libc.so
it loads has none (i.e. --with-tls --without-__thread), ld.so will
permit loading of objects with TLS segments. */
COMMON_INT_DEF(loser);
#endif
#define TEST_FUNCTION do_test ()
static int

View File

@ -5,6 +5,15 @@
#include <link.h>
#include <tls.h>
#ifdef USE_TLS
# include "tls-macros.h"
/* This gives the executable a TLS segment so that even if the libc.so
it loads has none (i.e. --with-tls --without-__thread), ld.so will
permit loading of objects with TLS segments. */
COMMON_INT_DEF(loser);
#endif
#define TEST_FUNCTION do_test ()
static int

View File

@ -43,8 +43,17 @@ typedef struct
#endif
/* We can support TLS only if the floating-stack support is available. */
#if defined FLOATING_STACKS && defined HAVE_TLS_SUPPORT
/* We can support TLS only if the floating-stack support is available.
However, we want to compile in the support and test at runtime whether
the running kernel can support it or not. To avoid bothering with the
TLS support code at all, use configure --without-tls.
We need USE_TLS to be consistently defined, for ldsodefs.h conditionals.
But some of the code below can cause problems in building libpthread
(e.g. useldt.h will defined FLOATING_STACKS when it shouldn't). */
#if defined HAVE_TLS_SUPPORT \
&& (defined FLOATING_STACKS || !defined IS_IN_libpthread)
/* Signal that TLS support is available. */
# define USE_TLS 1
@ -96,8 +105,21 @@ typedef struct
# define TLS_LOAD_EBX
# endif
# if __ASSUME_LDT_WORKS > 0
# define TLS_DO_MODIFY_LDT_KERNEL_CHECK /* Nothing to do. */
# else
# include "useldt.h" /* For the structure. */
# define TLS_DO_MODIFY_LDT_KERNEL_CHECK \
if (__builtin_expect (GL(dl_osversion) < 131939, 0)) \
_dl_fatal_printf ("kernel %u.%u.%u cannot support thread-local storage\n",\
(GL(dl_osversion) >> 16) & 0xff, \
(GL(dl_osversion) >> 8) & 0xff, \
(GL(dl_osversion) >> 0) & 0xff);
# endif
# define TLS_DO_MODIFY_LDT(descr, nr) \
({ \
TLS_DO_MODIFY_LDT_KERNEL_CHECK \
struct modify_ldt_ldt_s ldt_entry = \
{ nr, (unsigned long int) (descr), 0xfffff /* 4GB in pages */, \
1, 0, 0, 1, 0, 1, 0 }; \
@ -177,7 +199,7 @@ typedef struct
({ struct _pthread_descr_struct *__descr; \
THREAD_GETMEM (__descr, p_header.data.dtvp); })
# endif /* FLOATING_STACKS && HAVE_TLS_SUPPORT */
# endif /* HAVE_TLS_SUPPORT && (FLOATING_STACKS || !IS_IN_libpthread) */
#endif /* __ASSEMBLER__ */
#endif /* tls.h */

View File

@ -1,3 +1,12 @@
/* Ack, a hack! We need to get the proper definition, or lack thereof,
for FLOATING_STACKS. But when !IS_IN_libpthread, this can get defined
incidentally by <tls.h>. So kludge around it. */
#define IS_IN_libpthread
#include <tls.h>
#undef IS_IN_libpthread
#undef USE___THREAD
#include <errno.h>
#include <error.h>
#include <pthread.h>
@ -5,8 +14,6 @@
#include <stdlib.h>
#include <ucontext.h>
#include "pt-machine.h"
#define N 4