[PATCH] ld: Add -z start-stop-gc to let __start_/__stop_ not retain C identifier name sections
Fangrui Song
i@maskray.me
Sun Feb 28 05:03:19 GMT 2021
On 2021-02-28, Alan Modra via Binutils wrote:
>On Sat, Feb 27, 2021 at 12:26:17PM -0800, Fangrui Song wrote:
>> --- a/ld/ldlang.c
>> +++ b/ld/ldlang.c
>> @@ -8089,7 +8089,7 @@ lang_process (void)
>> /* Give initial values for __start and __stop symbols, so that ELF
>> gc_sections will keep sections referenced by these symbols. Must
>> be done before lang_do_assignments below. */
>> - if (config.build_constructors)
>> + if (config.build_constructors && !link_info.start_stop_gc)
>> lang_init_start_stop ();
>>
>> /* PR 13683: We must rerun the assignments prior to running garbage
>
>This will mean start/stop symbols are not defined, which is rather
>more than your stated aim of changing the behaviour of garbage
>collection. Not setting h->start_stop in bfd_elf_define_start_stop
>would do what you want, I think. (I haven't checked..)
This looks much more difficult than I expected.
1. The current approach does not actually make __start_ useful.
2.
Setting h->start_stop to 0 in bfd_elf_define_start_stop does not work.
There will be null pointer dereference due to h->u2.start_stop_section
misused as h->u2.vtable .
3.
I tried another approach before sending this patch.
I added an info->start_stop_gc check here:
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -13451,7 +13451,7 @@ _bfd_elf_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
symbols. */
if (h->start_stop)
{
asection *s = h->u2.start_stop_section;
*start_stop = !s->gc_mark;
return s;
}
Unfortunately if there is an undefined weak "__start_xx" and no xx is retained =>
undefined symbol error due to ldlang.c:undef_start_stop .
I don't know how to distinguish undefined strong and undefined weak in undef_start_stop.
Perhaps I should hand this over to you expert:)
More information about the Binutils
mailing list