[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