[PATCH][LTO] Fixup gold/linker-plugin symbol resolution
Richard Guenther
rguenther@suse.de
Wed Mar 31 10:04:00 GMT 2010
It seems that the symbol resolution gold and/or the linker-plugin
provides for commons is completely broken. It also seems that the
linker-plugin code is now unmaintained (or rather that noone
understanding where the resolution comes from -- I only can
see a single assignment to it, entry->resolution = LDPR_UNKNOWN;,
wants to or is able to look into this bug).
Thus, the following papers over the problem. A different patch
would just dump the gold symbol resolution and would reset it
all to LDPR_UNKNOWN at the very same spot.
Well. I'm going to bootstrap and test the following variant
(but of course it ain't excercised in that cycle, we cannot
have -fuse-linker-plugin testsuite entries as we do not have
a testsuite support for detecting linker-plugin support).
Anyway. Here goes the patch - any preferences regarding the
fix? Any help from gold / linker-plugin people? Please?
Where does the resolution come from? Why is there no
prevailing definition for commons? Shouldn't the largest
entry win here?
Thanks,
Richard.
2010-03-31 Richard Guenther <rguenther@suse.de>
PR lto/42757
* lto-symtab.c (lto_symtab_resolve_symbols): Fixup broken
gold/linker-plugin symbol resolution for commons.
Index: gcc/lto-symtab.c
===================================================================
*** gcc/lto-symtab.c (revision 157854)
--- gcc/lto-symtab.c (working copy)
*************** lto_symtab_resolve_symbols (void **slot)
*** 410,418 ****
e = (lto_symtab_entry_t) *slot;
! /* If the chain is already resolved there is nothing else to do. */
! if (e->resolution != LDPR_UNKNOWN)
! return;
/* Find the single non-replaceable prevailing symbol and
diagnose ODR violations. */
--- 410,441 ----
e = (lto_symtab_entry_t) *slot;
! /* If the chain is already resolved there is nothing else to do.
! In theory. But gold and/or the linker-plugin is seriously broken
! with respect to commons, so try to fixup here. See PR42757. */
! if (e->resolution != LDPR_UNKNOWN
! && TREE_CODE (e->decl) == VAR_DECL)
! {
! bool has_can_prevailing_entry = false;
! for (; e; e = e->next)
! {
! if (e->resolution == LDPR_PREVAILING_DEF_IRONLY
! || e->resolution == LDPR_PREVAILING_DEF)
! return;
! if (lto_symtab_resolve_can_prevail_p (e))
! has_can_prevailing_entry = true;
! }
! if (has_can_prevailing_entry)
! for (e = (lto_symtab_entry_t) *slot; e; e = e->next)
! if (lto_symtab_resolve_can_prevail_p (e))
! {
! if (TREE_READONLY (e->decl))
! e->resolution = LDPR_PREVAILING_DEF_IRONLY;
! else
! e->resolution = LDPR_PREVAILING_DEF;
! }
! return;
! }
/* Find the single non-replaceable prevailing symbol and
diagnose ODR violations. */
More information about the Gcc-patches
mailing list