commit 8f8dd904c4a2207699bb666f30acceb5209c8d3f Author: Florian Weimer Date: Wed Nov 6 10:33:44 2024 +0100 elf: rtld_multiple_ref is always true For a long time, libc.so.6 has dependend on ld.so, which means that there is a reference to ld.so in all processes, and rtld_multiple_ref is always true. In fact, if rtld_multiple_ref were false, some of the ld.so setup code would not run. Reviewed-by: DJ Delorie Conflicts: elf/rtld.c ( - prelink support not removed downstream - "elf: Add _dl_find_object function" not ported downstream ) diff --git a/elf/rtld.c b/elf/rtld.c index d02ecc834c9a4d43..711bb77d70da6563 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -2002,43 +2002,37 @@ dl_main (const ElfW(Phdr) *phdr, if (main_map->l_searchlist.r_list[i] == &GL(dl_rtld_map)) break; - bool rtld_multiple_ref = false; - if (__glibc_likely (i < main_map->l_searchlist.r_nlist)) - { - /* Some DT_NEEDED entry referred to the interpreter object itself, so - put it back in the list of visible objects. We insert it into the - chain in symbol search order because gdb uses the chain's order as - its symbol search order. */ - rtld_multiple_ref = true; + /* Insert the link map for the dynamic loader into the chain in + symbol search order because gdb uses the chain's order as its + symbol search order. */ - GL(dl_rtld_map).l_prev = main_map->l_searchlist.r_list[i - 1]; - if (__glibc_likely (state.mode == rtld_mode_normal)) - { - GL(dl_rtld_map).l_next = (i + 1 < main_map->l_searchlist.r_nlist - ? main_map->l_searchlist.r_list[i + 1] - : NULL); + GL(dl_rtld_map).l_prev = main_map->l_searchlist.r_list[i - 1]; + if (__glibc_likely (state.mode == rtld_mode_normal)) + { + GL(dl_rtld_map).l_next = (i + 1 < main_map->l_searchlist.r_nlist + ? main_map->l_searchlist.r_list[i + 1] + : NULL); #ifdef NEED_DL_SYSINFO_DSO - if (GLRO(dl_sysinfo_map) != NULL - && GL(dl_rtld_map).l_prev->l_next == GLRO(dl_sysinfo_map) - && GL(dl_rtld_map).l_next != GLRO(dl_sysinfo_map)) - GL(dl_rtld_map).l_prev = GLRO(dl_sysinfo_map); + if (GLRO(dl_sysinfo_map) != NULL + && GL(dl_rtld_map).l_prev->l_next == GLRO(dl_sysinfo_map) + && GL(dl_rtld_map).l_next != GLRO(dl_sysinfo_map)) + GL(dl_rtld_map).l_prev = GLRO(dl_sysinfo_map); #endif - } - else - /* In trace mode there might be an invisible object (which we - could not find) after the previous one in the search list. - In this case it doesn't matter much where we put the - interpreter object, so we just initialize the list pointer so - that the assertion below holds. */ - GL(dl_rtld_map).l_next = GL(dl_rtld_map).l_prev->l_next; - - assert (GL(dl_rtld_map).l_prev->l_next == GL(dl_rtld_map).l_next); - GL(dl_rtld_map).l_prev->l_next = &GL(dl_rtld_map); - if (GL(dl_rtld_map).l_next != NULL) - { - assert (GL(dl_rtld_map).l_next->l_prev == GL(dl_rtld_map).l_prev); - GL(dl_rtld_map).l_next->l_prev = &GL(dl_rtld_map); - } + } + else + /* In trace mode there might be an invisible object (which we + could not find) after the previous one in the search list. + In this case it doesn't matter much where we put the + interpreter object, so we just initialize the list pointer so + that the assertion below holds. */ + GL(dl_rtld_map).l_next = GL(dl_rtld_map).l_prev->l_next; + + assert (GL(dl_rtld_map).l_prev->l_next == GL(dl_rtld_map).l_next); + GL(dl_rtld_map).l_prev->l_next = &GL(dl_rtld_map); + if (GL(dl_rtld_map).l_next != NULL) + { + assert (GL(dl_rtld_map).l_next->l_prev == GL(dl_rtld_map).l_prev); + GL(dl_rtld_map).l_next->l_prev = &GL(dl_rtld_map); } /* Now let us see whether all libraries are available in the @@ -2212,8 +2206,7 @@ dl_main (const ElfW(Phdr) *phdr, } } - if ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) - && rtld_multiple_ref) + if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) { /* Mark the link map as not yet relocated again. */ GL(dl_rtld_map).l_relocated = 0; @@ -2500,10 +2493,9 @@ 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 (! prelinked) { - /* There was an explicit ref to the dynamic linker as a shared lib. - Re-relocate ourselves with user-controlled symbol definitions. + /* Re-relocate ourselves with user-controlled symbol definitions. We must do this after TLS initialization in case after this re-relocation, we might call a user-supplied function