aboutsummaryrefslogtreecommitdiff
path: root/elf
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2002-02-09 01:41:44 +0000
committerUlrich Drepper <drepper@redhat.com>2002-02-09 01:41:44 +0000
commita52d15621f2f03891944550b0b71ff117e15c16a (patch)
tree14cace4b408dc7ee21138ad62550a2123445ad8a /elf
parent013aafb7d098153e8df3a133ce6302c20396a33f (diff)
downloadglibc-a52d15621f2f03891944550b0b71ff117e15c16a.zip
glibc-a52d15621f2f03891944550b0b71ff117e15c16a.tar.gz
glibc-a52d15621f2f03891944550b0b71ff117e15c16a.tar.bz2
Update.
2002-02-08 Ulrich Drepper <drepper@redhat.com> * elf/rtld.c (_dl_start_final): Install DTV explicitly. (dl_main): Move dtv/static TLS handling before relocation. Unconditionally call _dl_tlsoffset. Call _dl_allocate_tls and TLS_INIT_TP to allocate and install the dtv/static TLS block. * sysdeps/generic/dl-tls.c (_dl_determine_tlsoffset): If no object so far uses TLS initialize GL(dl_tls_static_size) and GL(dl_tls_static_align) to account for the TCB. (_dl_allocate_tls): New function. * sysdeps/generic/ldsodefs.h (rtld_global): Add _dl_initial_dtv_malloced. * configure.in: Test for __builtin_memset more realistically. * csu/version.c (banner): If TLS support available say so.
Diffstat (limited to 'elf')
-rw-r--r--elf/rtld.c101
1 files changed, 58 insertions, 43 deletions
diff --git a/elf/rtld.c b/elf/rtld.c
index a19fad2..2ebde45 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -309,14 +309,20 @@ _dl_start_final (void *arg, struct link_map *bootstrap_map_p,
'\0', (GL(dl_rtld_map).l_tls_blocksize
- GL(dl_rtld_map).l_tls_initimage_size));
+ /* Install the pointer to the dtv. */
+
/* Initialize the thread pointer. */
# if TLS_TCB_AT_TP
GL(dl_rtld_map).l_tls_offset
= roundup (GL(dl_rtld_map).l_tls_blocksize, TLS_INIT_TCB_ALIGN);
- TLS_INIT_TP ((char *) tlsblock + GL(dl_rtld_map).l_tls_offset,
+
+ INSTALL_DTV ((char *) tlsblock + GL(dl_rtld_map).l_tls_offset,
initdtv);
+
+ TLS_INIT_TP ((char *) tlsblock + GL(dl_rtld_map).l_tls_offset);
# elif TLS_DTV_AT_TP
- TLS_INIT_TP (tlsblock, initdtv);
+ INSTALL_DTV (tlsblock, initdtv);
+ TLS_INIT_TP (tlsblock);
# else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
# endif
@@ -477,6 +483,9 @@ dl_main (const ElfW(Phdr) *phdr,
hp_timing_t stop;
hp_timing_t diff;
#endif
+#ifdef USE_TLS
+ void *tcbp;
+#endif
/* Process the environment variable which control the behaviour. */
process_envvars (&mode);
@@ -1169,6 +1178,53 @@ of this helper program; chances are you did not intend to run this program.\n\
_exit (0);
}
+#ifdef USE_TLS
+ /* Now it is time to determine the layout of the static TLS block
+ and allocate it for the initial thread. Note that we always
+ allocate the static block, we never defer it even if no
+ DF_STATIC_TLS bit is set. The reason is that we know glibc will
+ use the static model. First add the dynamic linker to the list
+ if it also uses TLS. */
+ if (GL(dl_rtld_map).l_tls_blocksize != 0)
+ {
+ /* At to the list. */
+ if (GL(dl_initimage_list) == NULL)
+ GL(dl_initimage_list) = GL(dl_rtld_map).l_tls_nextimage
+ = GL(dl_rtld_map).l_tls_previmage = &GL(dl_rtld_map);
+ else
+ {
+ GL(dl_rtld_map).l_tls_nextimage
+ = GL(dl_initimage_list)->l_tls_nextimage;
+ GL(dl_rtld_map).l_tls_nextimage->l_tls_previmage
+ = &GL(dl_rtld_map);
+ GL(dl_rtld_map).l_tls_previmage = GL(dl_initimage_list);
+ GL(dl_rtld_map).l_tls_previmage->l_tls_nextimage
+ = &GL(dl_rtld_map);
+ GL(dl_initimage_list) = &GL(dl_rtld_map);
+ }
+
+ /* Assign a module ID. */
+ GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
+ }
+
+ /* Computer the TLS offsets for the various blocks. We call this
+ function even if none of the modules available at startup time
+ uses TLS to initialize some variables. */
+ _dl_determine_tlsoffset (GL(dl_initimage_list));
+
+ /* Construct the static TLS block and the dtv for the initial
+ thread. For some platforms this will include allocating memory
+ for the thread descriptor. The memory for the TLS block will
+ never be freed. It should be allocated accordingly. The dtv
+ array can be changed if dynamic loading requires it. */
+ tcbp = _dl_allocate_tls ();
+ if (tcbp == NULL)
+ _dl_fatal_printf ("cannot allocate TLS data structures for inital thread");
+
+ /* And finally install it for the main thread. */
+ TLS_INIT_TP (tcbp);
+#endif
+
if (GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_LIBLIST)]
&& ! __builtin_expect (GL(dl_profile) != NULL, 0))
{
@@ -1333,47 +1389,6 @@ of this helper program; chances are you did not intend to run this program.\n\
we need it in the memory handling later. */
GL(dl_initial_searchlist) = *GL(dl_main_searchlist);
-#ifdef USE_TLS
- /* Now it is time to determine the layout of the static TLS block
- and allocate it for the initial thread. Note that we always
- allocate the static block, we never defer it even if no
- DF_STATIC_TLS bit is set. The reason is that we know glibc will
- use the static model. First add the dynamic linker to the list
- if it also uses TLS. */
- if (GL(dl_rtld_map).l_tls_blocksize != 0)
- {
- /* At to the list. */
- if (GL(dl_initimage_list) == NULL)
- GL(dl_initimage_list) = GL(dl_rtld_map).l_tls_nextimage
- = GL(dl_rtld_map).l_tls_previmage = &GL(dl_rtld_map);
- else
- {
- GL(dl_rtld_map).l_tls_nextimage
- = GL(dl_initimage_list)->l_tls_nextimage;
- GL(dl_rtld_map).l_tls_nextimage->l_tls_previmage
- = &GL(dl_rtld_map);
- GL(dl_rtld_map).l_tls_previmage = GL(dl_initimage_list);
- GL(dl_rtld_map).l_tls_previmage->l_tls_nextimage
- = &GL(dl_rtld_map);
- GL(dl_initimage_list) = &GL(dl_rtld_map);
- }
-
- /* Assign a module ID. */
- GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
- }
-
- if (GL(dl_initimage_list) != NULL)
- /* This means we actually have some modules which use TLS.
- Computer the TLS offsets for the various blocks. */
- _dl_determine_tlsoffset (GL(dl_initimage_list)->l_tls_nextimage);
-
- /* Construct the static TLS block and the dtv for the initial
- thread. For some platforms this will include allocating memory
- for the thread descriptor. The memory for the TLS block will
- never be freed. It should be allocated accordingly. The dtv
- array can be changed if dynamic loading requires it. */
-#endif
-
{
/* Initialize _r_debug. */
struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_addr);