diff options
Diffstat (limited to 'elf/rtld.c')
-rw-r--r-- | elf/rtld.c | 71 |
1 files changed, 51 insertions, 20 deletions
diff --git a/elf/rtld.c b/elf/rtld.c index 5e6ee51603..a357a46987 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1,5 +1,5 @@ /* Run time dynamic linker. - Copyright (C) 1995-2002,2003,2004,2005,2006 Free Software Foundation, Inc. + Copyright (C) 1995-2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -207,7 +207,8 @@ DL_SYSINFO_IMPLEMENTATION is fine, too. The latter is important here. We can avoid setting up a temporary link map for ld.so if we can mark _rtld_global as hidden. */ -#ifdef PI_STATIC_AND_HIDDEN +#if defined PI_STATIC_AND_HIDDEN && defined HAVE_HIDDEN \ + && defined HAVE_VISIBILITY_ATTRIBUTE # define DONT_USE_BOOTSTRAP_MAP 1 #endif @@ -291,7 +292,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info) GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end; GL(dl_rtld_map).l_text_end = (ElfW(Addr)) _etext; /* Copy the TLS related data if necessary. */ -#ifndef DONT_USE_BOOTSTRAP_MAP +#if USE_TLS && !defined DONT_USE_BOOTSTRAP_MAP # if USE___THREAD assert (info->l.l_tls_modid != 0); GL(dl_rtld_map).l_tls_blocksize = info->l.l_tls_blocksize; @@ -399,7 +400,7 @@ _dl_start (void *arg) bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic (); elf_get_dynamic_info (&bootstrap_map, NULL); -#if NO_TLS_OFFSET != 0 +#if defined USE_TLS && NO_TLS_OFFSET != 0 bootstrap_map.l_tls_offset = NO_TLS_OFFSET; #endif @@ -700,6 +701,7 @@ match_version (const char *string, struct link_map *map) return 0; } +#ifdef USE_TLS static bool tls_init_tp_called; static void * @@ -771,6 +773,7 @@ cannot allocate TLS data structures for initial thread"); return tcbp; } +#endif #ifdef _LIBC_REENTRANT /* _dl_error_catch_tsd points to this for the single-threaded case. @@ -858,14 +861,18 @@ dl_main (const ElfW(Phdr) *phdr, hp_timing_t stop; hp_timing_t diff; #endif +#ifdef USE_TLS void *tcbp = NULL; +#endif #ifdef _LIBC_REENTRANT /* Explicit initialization since the reloc would just be more work. */ GL(dl_error_catch_tsd) = &_dl_initial_error_catch_tsd; #endif +#ifdef USE_TLS GL(dl_init_static_tls) = &_dl_nothread_init_static_tls; +#endif #if defined SHARED && defined _LIBC_REENTRANT \ && defined __rtld_lock_default_lock_recursive @@ -1150,6 +1157,7 @@ of this helper program; chances are you did not intend to run this program.\n\ break; case PT_TLS: +#ifdef USE_TLS if (ph->p_memsz > 0) { /* Note that in the case the dynamic linker we duplicate work @@ -1169,6 +1177,10 @@ of this helper program; chances are you did not intend to run this program.\n\ /* This image gets the ID one. */ GL(dl_tls_max_dtv_idx) = main_map->l_tls_modid = 1; } +#else + _dl_fatal_printf ("\ +ld.so does not support TLS, but program uses it!\n"); +#endif break; case PT_GNU_STACK: @@ -1180,12 +1192,13 @@ of this helper program; chances are you did not intend to run this program.\n\ main_map->l_relro_size = ph->p_memsz; break; } - - /* Adjust the address of the TLS initialization image in case - the executable is actually an ET_DYN object. */ - if (main_map->l_tls_initimage != NULL) - main_map->l_tls_initimage - = (char *) main_map->l_tls_initimage + main_map->l_addr; +#ifdef USE_TLS + /* Adjust the address of the TLS initialization image in case + the executable is actually an ET_DYN object. */ + if (main_map->l_tls_initimage != NULL) + main_map->l_tls_initimage + = (char *) main_map->l_tls_initimage + main_map->l_addr; +#endif if (! main_map->l_map_end) main_map->l_map_end = ~0; if (! main_map->l_text_end) @@ -1388,10 +1401,12 @@ of this helper program; chances are you did not intend to run this program.\n\ break; } +#ifdef USE_TLS /* Add the dynamic linker to the TLS list if it also uses TLS. */ if (GL(dl_rtld_map).l_tls_blocksize != 0) /* Assign a module ID. Do this before loading any audit modules. */ GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid (); +#endif /* If we have auditing DSOs to load, do it now. */ if (__builtin_expect (audit_list != NULL, 0)) @@ -1399,8 +1414,15 @@ of this helper program; chances are you did not intend to run this program.\n\ /* Iterate over all entries in the list. The order is important. */ struct audit_ifaces *last_audit = NULL; struct audit_list *al = audit_list->next; + +#ifdef USE_TLS + /* Since we start using the auditing DSOs right away we need to + initialize the data structures now. */ + tcbp = init_tls (); +#endif do { +#ifdef USE_TLS int tls_idx = GL(dl_tls_max_dtv_idx); /* Now it is time to determine the layout of the static TLS @@ -1408,11 +1430,7 @@ of this helper program; chances are you did not intend to run this program.\n\ 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. */ - - /* Since we start using the auditing DSOs right away we need to - initialize the data structures now. */ - tcbp = init_tls (); - +#endif struct dlmopen_args dlmargs; dlmargs.fname = al->name; dlmargs.map = NULL; @@ -1527,7 +1545,9 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", assert (GL(dl_ns)[ns]._ns_loaded == NULL); assert (GL(dl_ns)[ns]._ns_nloaded == 0); +#ifdef USE_TLS GL(dl_tls_max_dtv_idx) = tls_idx; +#endif goto not_loaded; } } @@ -1803,6 +1823,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", _dl_receive_error (print_missing_version, version_check_doit, &args); } +#ifdef USE_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 @@ -1813,6 +1834,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", bool was_tls_init_tp_called = tls_init_tp_called; if (tcbp == NULL) tcbp = init_tls (); +#endif /* Set up the stack checker's canary. */ uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (); @@ -1869,12 +1891,13 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", (size_t) l->l_map_start, (int) sizeof l->l_addr * 2, (size_t) l->l_addr); - +#ifdef USE_TLS if (l->l_tls_modid) _dl_printf (" TLS(0x%Zx, 0x%0*Zx)\n", l->l_tls_modid, (int) sizeof l->l_tls_offset * 2, (size_t) l->l_tls_offset); else +#endif _dl_printf ("\n"); } } @@ -1942,8 +1965,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", lookup_t result; result = _dl_lookup_symbol_x (INTUSE(_dl_argv)[i], main_map, - &ref, main_map->l_scope, - NULL, ELF_RTYPE_CLASS_PLT, + &ref, main_map->l_scope, NULL, + ELF_RTYPE_CLASS_PLT, DL_LOOKUP_ADD_DEPENDENCY, NULL); loadbase = LOOKUP_VALUE_ADDRESS (result); @@ -1985,8 +2008,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", { /* Mark the link map as not yet relocated again. */ GL(dl_rtld_map).l_relocated = 0; - _dl_relocate_object (&GL(dl_rtld_map), - main_map->l_scope, 0, 0); + _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, + 0, 0); } } #define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED)) @@ -2157,9 +2180,11 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", if (l->l_relro_size) _dl_protect_relro (l); +#ifdef USE_TLS /* Add object to slot information data if necessasy. */ if (l->l_tls_blocksize != 0 && tls_init_tp_called) _dl_add_to_slotinfo (l); +#endif } _dl_sysdep_start_cleanup (); @@ -2206,9 +2231,11 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy), consider_profiling); +#ifdef USE_TLS /* Add object to slot information data if necessasy. */ if (l->l_tls_blocksize != 0 && tls_init_tp_called) _dl_add_to_slotinfo (l); +#endif l = l->l_prev; } @@ -2237,6 +2264,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", # define NONTLS_INIT_TP do { } while (0) #endif +#ifdef USE_TLS if (!was_tls_init_tp_called && GL(dl_tls_max_dtv_idx) > 0) ++GL(dl_tls_generation); @@ -2254,6 +2282,9 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", _dl_fatal_printf ("cannot set up thread-local storage: %s\n", lossage); } +#else + NONTLS_INIT_TP; +#endif if (! prelinked && rtld_multiple_ref) { |