From: H.J. Lu Date: Sun, 15 Jun 2025 03:38:54 +0000 (+0800) Subject: elf: Add optimization barrier for __ehdr_start and _end X-Git-Tag: glibc-2.42~141 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=81467d4b6168c7ce40d951d6b32e387109c0e5ae;p=thirdparty%2Fglibc.git elf: Add optimization barrier for __ehdr_start and _end rtld.c has extern const ElfW(Ehdr) __ehdr_start attribute_hidden; ... _dl_rtld_map.l_map_start = (ElfW(Addr)) &__ehdr_start; _dl_rtld_map.l_map_end = (ElfW(Addr)) _end; As https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120653 shows, compiler may generate run-time relocation on __ehdr_start with movq .LC0(%rip), %xmm0 ... .section .data.rel.ro.local,"aw" .align 8 .LC0: .quad __ehdr_start This won't work before run-time relocation is finished in rtld.c. Add optimization barrier to prevent run-time relocations against __ehdr_start and _end. Signed-off-by: H.J. Lu Reviewed-by: Sam James --- diff --git a/elf/rtld.c b/elf/rtld.c index 8e8f0e6253..e6a181dc31 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -477,7 +477,10 @@ _dl_start_final (void *arg, struct dl_start_final_info *info) _dl_setup_hash (&_dl_rtld_map); _dl_rtld_map.l_real = &_dl_rtld_map; _dl_rtld_map.l_map_start = (ElfW(Addr)) &__ehdr_start; + /* Prevent run-time relocations against __ehdr_start and _end. */ + asm ("" : "+g" (_dl_rtld_map.l_map_start)); _dl_rtld_map.l_map_end = (ElfW(Addr)) _end; + asm ("" : "+g" (_dl_rtld_map.l_map_end)); /* Copy the TLS related data if necessary. */ #ifndef DONT_USE_BOOTSTRAP_MAP # if NO_TLS_OFFSET != 0 diff --git a/sysdeps/x86_64/Makefile b/sysdeps/x86_64/Makefile index 5723ec1847..e8f8a52eea 100644 --- a/sysdeps/x86_64/Makefile +++ b/sysdeps/x86_64/Makefile @@ -214,6 +214,24 @@ $(objpfx)tst-plt-rewrite2: $(objpfx)tst-plt-rewritemod2.so endif test-internal-extras += tst-gnu2-tls2mod1 + +tests-special += $(objpfx)check-rtld.out + +$(objpfx)rtld.reloc: $(objpfx)rtld.os + @rm -f $@T + LC_ALL=C $(READELF) -rW $< > $@T + test -s $@T + mv -f $@T $@ +common-generated += $(objpfx)rtld.reloc + +# Verify that there are no run-time relocations against __ehdr_start nor +# _end. +$(objpfx)check-rtld.out: $(objpfx)rtld.reloc + LC_ALL=C; \ + if grep -E "R_X86_64_64.*(__ehdr_start|_end)" $^ > $@; \ + then false; else true; fi; \ + $(evaluate-test) +generated += check-rtld.out endif # $(subdir) == elf ifeq ($(subdir),csu)