https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120653
--- Comment #15 from Florian Weimer <fw at gcc dot gnu.org> --- Jakub, thanks for the really helpful analysis! In glibc, we do additional gymnastics to self-relocate the dynamic linker earlier, with a compiler barrier, but only for HIDDEN_VAR_NEEDS_DYNAMIC_RELOC architectures (like MIPS)—not for x86-64. I admit that this is not entirely correct because GCC can materialize constants that require relocation into global data. This happens in the Fedora 42 build as well, for the rfv constant in dl_vdso_vsym in sysdeps/unix/sysv/linux/dl-vdso.h: const struct r_found_version rfv = { VDSO_NAME, VDSO_HASH, 1, NULL }; /* Search the scope of the vdso map. */ const ElfW (Sym) *ref = &wsym; lookup_t result = GLRO (dl_lookup_symbol_x) (name, map, &ref, map->l_local_scope, &rfv, 0, 0, NULL); return ref != NULL ? DL_SYMBOL_ADDRESS (result, ref) : NULL; It just so happens that the first call to dl_vdso_vsym happens after the call to ELF_DYNAMIC_RELOCATE for ld.so, which is why this works. But the entire design really assumes that the ELF_DYNAMIC_RELOCATE call is a no-op. So maybe we are just naïve, and need to treat all architectures as HIDDEN_VAR_NEEDS_DYNAMIC_RELOC? Or get real, remove the ELF_DYNAMIC_RELOCATE call for ld.so on !HIDDEN_VAR_NEEDS_DYNAMIC_RELOC architectures because it should do nothing at all, and add a test case that requires that there are no dynamic relocations whatsoever. But it looks like the latter would require a way to request that GCC does not produce global data constants (with relocations) for initializing local variables.