[PATCH v2] elf: Add optimization barrier for __ehdr_start and _end

Sam James sam@gentoo.org
Mon Jun 16 00:12:20 GMT 2025


"H.J. Lu" <hjl.tools@gmail.com> writes:

> On Mon, Jun 16, 2025 at 6:32 AM Sam James <sam@gentoo.org> wrote:
>>
>> "H.J. Lu" <hjl.tools@gmail.com> writes:
>>
>> > rtld.c has
>> >
>> > extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
>> > ...
>> >   _dl_rtld_map.l_map_start = (ElfW(Addr)) &__ehdr_start;
>> >
>> > 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.  Define
>> > _dl_ehdr_start_before_reloc to allow x86-64 to generate LEA to avoid
>> > run-time relocation on __ehdr_start in rtld.c.
>>
>> LGTM, but please give Florian a chance to object. Thanks for adding a
>> test too.
>>
>> I still feel a bit uneasy about the general approach here
>> (whack-a-mole). Florian had some thoughts at
>
> That is the nature of ld.so.
>
>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120653#c15 on doing better
>> but I don't think that should block this simple (and backportable in due
>> course) fix.
>>
>> I see Jakub has a broader suggestion as well on the bug.
>
> Here is the v2 patch to add
>
> 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 *inf
> o)
>    _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
>
> as Jakub suggested.

LGTM and tested it too (confirmed broken before, worked after). Thanks.


More information about the Libc-alpha mailing list