diff options
Diffstat (limited to 'elf/rtld.c')
-rw-r--r-- | elf/rtld.c | 250 |
1 files changed, 50 insertions, 200 deletions
@@ -565,7 +565,7 @@ _dl_start (void *arg) ELF_MACHINE_BEFORE_RTLD_RELOC (&bootstrap_map, bootstrap_map.l_info); #endif - if (bootstrap_map.l_addr || ! bootstrap_map.l_info[VALIDX(DT_GNU_PRELINKED)]) + if (bootstrap_map.l_addr) { /* Relocate ourselves so we can do normal function calls and data access using the global offset table. */ @@ -1322,7 +1322,6 @@ dl_main (const ElfW(Phdr) *phdr, size_t file_size; char *file; unsigned int i; - bool prelinked = false; bool rtld_is_main = false; void *tcbp = NULL; @@ -2055,37 +2054,7 @@ dl_main (const ElfW(Phdr) *phdr, after relocation. */ struct link_map *l; - if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) - { - struct r_scope_elem *scope = &main_map->l_searchlist; - - for (i = 0; i < scope->r_nlist; i++) - { - l = scope->r_list [i]; - if (l->l_faked) - { - _dl_printf ("\t%s => not found\n", l->l_libname->name); - continue; - } - if (_dl_name_match_p (GLRO(dl_trace_prelink), l)) - GLRO(dl_trace_prelink_map) = l; - _dl_printf ("\t%s => %s (0x%0*Zx, 0x%0*Zx)", - DSO_FILENAME (l->l_libname->name), - DSO_FILENAME (l->l_name), - (int) sizeof l->l_map_start * 2, - (size_t) l->l_map_start, - (int) sizeof l->l_addr * 2, - (size_t) l->l_addr); - - 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 - _dl_printf ("\n"); - } - } - else if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED) + if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED) { /* Look through the dependencies of the main executable and determine which of them is not actually @@ -2193,14 +2162,6 @@ dl_main (const ElfW(Phdr) *phdr, } } - if ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) - && rtld_multiple_ref) - { - /* 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, __RTLD_NOIFUNC, 0); - } } #define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED)) if (state.version_info) @@ -2277,61 +2238,6 @@ dl_main (const ElfW(Phdr) *phdr, _exit (0); } - if (main_map->l_info[ADDRIDX (DT_GNU_LIBLIST)] - && ! __builtin_expect (GLRO(dl_profile) != NULL, 0) - && ! __builtin_expect (GLRO(dl_dynamic_weak), 0)) - { - ElfW(Lib) *liblist, *liblistend; - struct link_map **r_list, **r_listend, *l; - const char *strtab = (const void *) D_PTR (main_map, l_info[DT_STRTAB]); - - assert (main_map->l_info[VALIDX (DT_GNU_LIBLISTSZ)] != NULL); - liblist = (ElfW(Lib) *) - main_map->l_info[ADDRIDX (DT_GNU_LIBLIST)]->d_un.d_ptr; - liblistend = (ElfW(Lib) *) - ((char *) liblist - + main_map->l_info[VALIDX (DT_GNU_LIBLISTSZ)]->d_un.d_val); - r_list = main_map->l_searchlist.r_list; - r_listend = r_list + main_map->l_searchlist.r_nlist; - - for (; r_list < r_listend && liblist < liblistend; r_list++) - { - l = *r_list; - - if (l == main_map) - continue; - - /* If the library is not mapped where it should, fail. */ - if (l->l_addr) - break; - - /* Next, check if checksum matches. */ - if (l->l_info [VALIDX(DT_CHECKSUM)] == NULL - || l->l_info [VALIDX(DT_CHECKSUM)]->d_un.d_val - != liblist->l_checksum) - break; - - if (l->l_info [VALIDX(DT_GNU_PRELINKED)] == NULL - || l->l_info [VALIDX(DT_GNU_PRELINKED)]->d_un.d_val - != liblist->l_time_stamp) - break; - - if (! _dl_name_match_p (strtab + liblist->l_name, l)) - break; - - ++liblist; - } - - - if (r_list == r_listend && liblist == liblistend) - prelinked = true; - - if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) - _dl_debug_printf ("\nprelink checking: %s\n", - prelinked ? "ok" : "failed"); - } - - /* Now set up the variable which helps the assembler startup code. */ GL(dl_ns)[LM_ID_BASE]._ns_main_searchlist = &main_map->l_searchlist; @@ -2356,103 +2262,59 @@ dl_main (const ElfW(Phdr) *phdr, _rtld_main_check (main_map, _dl_argv[0]); - if (prelinked) - { - if (main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)] != NULL) - { - ElfW(Rela) *conflict, *conflictend; + /* Now we have all the objects loaded. Relocate them all except for + the dynamic linker itself. We do this in reverse order so that copy + relocs of earlier objects overwrite the data written by later + objects. We do not re-relocate the dynamic linker itself in this + loop because that could result in the GOT entries for functions we + call being changed, and that would break us. It is safe to relocate + the dynamic linker out of order because it has no copy relocs (we + know that because it is self-contained). */ - RTLD_TIMING_VAR (start); - rtld_timer_start (&start); + int consider_profiling = GLRO(dl_profile) != NULL; - assert (main_map->l_info [VALIDX (DT_GNU_CONFLICTSZ)] != NULL); - conflict = (ElfW(Rela) *) - main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)]->d_un.d_ptr; - conflictend = (ElfW(Rela) *) - ((char *) conflict - + main_map->l_info [VALIDX (DT_GNU_CONFLICTSZ)]->d_un.d_val); - _dl_resolve_conflicts (main_map, conflict, conflictend); - - rtld_timer_stop (&relocate_time, start); - } + /* If we are profiling we also must do lazy reloaction. */ + GLRO(dl_lazy) |= consider_profiling; - /* Set up the object lookup structures. */ - _dl_find_object_init (); - - /* The library defining malloc has already been relocated due to - prelinking. Resolve the malloc symbols for the dynamic - loader. */ - __rtld_malloc_init_real (main_map); - - /* Likewise for the locking implementation. */ - __rtld_mutex_init (); - - /* Mark all the objects so we know they have been already relocated. */ - for (struct link_map *l = main_map; l != NULL; l = l->l_next) - { - l->l_relocated = 1; - if (l->l_relro_size) - _dl_protect_relro (l); - - /* Add object to slot information data if necessasy. */ - if (l->l_tls_blocksize != 0 && tls_init_tp_called) - _dl_add_to_slotinfo (l, true); - } - } - else - { - /* Now we have all the objects loaded. Relocate them all except for - the dynamic linker itself. We do this in reverse order so that copy - relocs of earlier objects overwrite the data written by later - objects. We do not re-relocate the dynamic linker itself in this - loop because that could result in the GOT entries for functions we - call being changed, and that would break us. It is safe to relocate - the dynamic linker out of order because it has no copy relocs (we - know that because it is self-contained). */ - - int consider_profiling = GLRO(dl_profile) != NULL; - - /* If we are profiling we also must do lazy reloaction. */ - GLRO(dl_lazy) |= consider_profiling; + RTLD_TIMING_VAR (start); + rtld_timer_start (&start); + { + unsigned i = main_map->l_searchlist.r_nlist; + while (i-- > 0) + { + struct link_map *l = main_map->l_initfini[i]; - RTLD_TIMING_VAR (start); - rtld_timer_start (&start); - unsigned i = main_map->l_searchlist.r_nlist; - while (i-- > 0) - { - struct link_map *l = main_map->l_initfini[i]; + /* While we are at it, help the memory handling a bit. We have to + mark some data structures as allocated with the fake malloc() + implementation in ld.so. */ + struct libname_list *lnp = l->l_libname->next; - /* While we are at it, help the memory handling a bit. We have to - mark some data structures as allocated with the fake malloc() - implementation in ld.so. */ - struct libname_list *lnp = l->l_libname->next; + while (__builtin_expect (lnp != NULL, 0)) + { + lnp->dont_free = 1; + lnp = lnp->next; + } + /* Also allocated with the fake malloc(). */ + l->l_free_initfini = 0; - while (__builtin_expect (lnp != NULL, 0)) - { - lnp->dont_free = 1; - lnp = lnp->next; - } - /* Also allocated with the fake malloc(). */ - l->l_free_initfini = 0; + if (l != &GL(dl_rtld_map)) + _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy) ? RTLD_LAZY : 0, + consider_profiling); - if (l != &GL(dl_rtld_map)) - _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy) ? RTLD_LAZY : 0, - consider_profiling); + /* Add object to slot information data if necessasy. */ + if (l->l_tls_blocksize != 0 && tls_init_tp_called) + _dl_add_to_slotinfo (l, true); + } + } + rtld_timer_stop (&relocate_time, start); - /* Add object to slot information data if necessasy. */ - if (l->l_tls_blocksize != 0 && tls_init_tp_called) - _dl_add_to_slotinfo (l, true); - } - rtld_timer_stop (&relocate_time, start); - - /* Now enable profiling if needed. Like the previous call, - this has to go here because the calls it makes should use the - rtld versions of the functions (particularly calloc()), but it - needs to have _dl_profile_map set up by the relocator. */ - if (__glibc_unlikely (GL(dl_profile_map) != NULL)) - /* We must prepare the profiling. */ - _dl_start_profile (); - } + /* Now enable profiling if needed. Like the previous call, + this has to go here because the calls it makes should use the + rtld versions of the functions (particularly calloc()), but it + needs to have _dl_profile_map set up by the relocator. */ + if (__glibc_unlikely (GL(dl_profile_map) != NULL)) + /* We must prepare the profiling. */ + _dl_start_profile (); if ((!was_tls_init_tp_called && GL(dl_tls_max_dtv_idx) > 0) || count_modids != _dl_count_modids ()) @@ -2478,7 +2340,7 @@ dl_main (const ElfW(Phdr) *phdr, /* Make sure no new search directories have been added. */ assert (GLRO(dl_init_all_dirs) == GL(dl_all_dirs)); - if (! prelinked && rtld_multiple_ref) + if (rtld_multiple_ref) { /* There was an explicit ref to the dynamic linker as a shared lib. Re-relocate ourselves with user-controlled symbol definitions. @@ -2811,17 +2673,6 @@ process_envvars (struct dl_main_state *state) GLRO(dl_profile_output) = &envline[15]; break; - case 16: - /* The mode of the dynamic linker can be set. */ - if (memcmp (envline, "TRACE_PRELINKING", 16) == 0) - { - state->mode = rtld_mode_trace; - GLRO(dl_verbose) = 1; - GLRO(dl_debug_mask) |= DL_DEBUG_PRELINK; - GLRO(dl_trace_prelink) = &envline[17]; - } - break; - case 20: /* The mode of the dynamic linker can be set. */ if (memcmp (envline, "TRACE_LOADED_OBJECTS", 20) == 0) @@ -2955,9 +2806,8 @@ print_statistics (const hp_timing_t *rtld_total_timep) += l->l_info[VERSYMIDX (DT_RELCOUNT)]->d_un.d_val; #ifndef ELF_MACHINE_REL_RELATIVE /* Relative relocations are processed on these architectures if - library is loaded to different address than p_vaddr or - if not prelinked. */ - if ((l->l_addr != 0 || !l->l_info[VALIDX(DT_GNU_PRELINKED)]) + library is loaded to different address than p_vaddr. */ + if ((l->l_addr != 0) && l->l_info[VERSYMIDX (DT_RELACOUNT)]) #else /* On e.g. IA-64 or Alpha, relative relocations are processed |