[PATCH] elf: Drop GRP_COMDAT when localizing a global symbol
Michael Matz
matz@suse.de
Tue Dec 7 14:19:24 GMT 2021
Hey,
On Tue, 7 Dec 2021, H.J. Lu via Binutils wrote:
> > > > > --- a/binutils/objcopy.c
> > > > > +++ b/binutils/objcopy.c
> > > > > @@ -1696,6 +1696,21 @@ filter_symbols (bfd *abfd, bfd *obfd, asymbol **osyms,
> > > > > && ! is_specified_symbol (name, keepglobal_specific_htab))
> > > > > || (localize_hidden && is_hidden_symbol (sym))))
> > > > > {
> > > > > + if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
> > > > > + {
> > > > > + sec_ptr s = sym->section;
> > > > > + if (s != NULL
> > > > > + && elf_section_data (s) != NULL
> > > > > + && elf_group_name (s) != NULL)
> > > > > + {
> > > > > + /* When a global symbol in a COMDAT group was
> > > > > + changed to local, drop GRP_COMDAT on the
> > > > > + group. */
> > > > > + s = elf_sec_group (s);
> > > > > + if (s != NULL && s->output_section != NULL)
> > > > > + s->output_section->flags &= ~SEC_LINK_ONCE;
> > > > > + }
> > > > > + }
> > > > > sym->flags &= ~ (BSF_GLOBAL | BSF_WEAK);
> > > > > sym->flags |= BSF_LOCAL;
> > > > > }
> > > >
> > > > I don't think this is quite correct. Surely you only want to change
> > > > the group semantics if the group symbol changes? This patch would
> > > > change group semantics if *any* symbol defined in the group is
> > > > localised.
> > >
> > > This is done on purpose. When any global symbol in a comdat group
> > > is localized, this comdat group is no longer interchangeable with other
> > > comdat groups of the same group signature.
> >
> > The ELF gABI says of GRP_COMDAT that "duplication is defined as having
> > the same group signature". There is no other requirement. Things
> > that you might imagine are necessary to make groups work in practice
>
> It is not my imagination:
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59842
>
> > are not relevant. objcopy is a tool that can destroy object files.
> >
> > Besides that, someone may be using objcopy on multiple object files
> > localising one symbol for every object, leaving all the comdat groups
> > with a given signature the same.
> >
> > Please read https://groups.google.com/g/generic-abi/c/2X6mR-s2zoc
> > again. The only symbol change that should affect the comdat status of
> > the group is the group symbol.
>
> From Roland in the URL above
>
> A. In step #2, merge COMDAT groups so all the desired merging from the
> step #1 translation units is complete before step #3.
> In step #3, have objcopy notice that it's localizing a symbol
> that's used as a COMDAT signature symbol and clear the GRP_COMDAT bit
> for that group.
> Now step #4 will not be doing any merging of the #1->#2 inputs but
> will do all appropriate merging among the other inputs to step #4 (and
> any non-localized symbols left after step #3).
>
> From Ali:
>
> To sum up, it sounds to me like objcopy failing to remove the
> GRP_COMDAT as part of step 3 in this process was the bug, and
> that your solution A is the right fix.
>
> My patch drops GRP_COMDAT.
But it does so if _any_ symbol associated with a comdat-grouped section is
localized. The thread above discusses the signature symbol only: if it's
merely a name donor, if its STB_binding should matter or not, how to deal
with the (probably buggy) situation when the signature symbol is
STT_SECTION/STB_LOCAL, and what ld -r should be doing.
Specifically, Rolands solution A for the objcopy --localize-hidden step
was:
>> In step #3, have objcopy notice that it's localizing a symbol that's
>> used as a *COMDAT signature symbol* and clear the GRP_COMDAT bit for
>> that group.
So, you would have to amend your change to only be active if the localized
symbol happens to be the group_signature() of a group.
Ciao,
Michael.
More information about the Binutils
mailing list