PR24567, assertion failure in ldlang.c:6868 when compiling with -flto

As the existing comment said: "a common ought to be overridden by a
def in a -flto object".  This patch makes the code actually do that,
rather than allowing a normal object file common to override a -flto
defined symbol.

	PR 24567
	* plugin.c (plugin_notice): Do not let a common symbol override
	a non-common definition in IR.
This commit is contained in:
Alan Modra 2019-05-17 19:09:42 +09:30
parent 2664858829
commit af4fa23fba
2 changed files with 30 additions and 18 deletions

View file

@ -1,3 +1,9 @@
2019-05-17 Alan Modra <amodra@gmail.com>
PR 24567
* plugin.c (plugin_notice): Do not let a common symbol override
a non-common definition in IR.
2019-05-09 Dimitar Dimitrov <dimitar@dinux.eu> 2019-05-09 Dimitar Dimitrov <dimitar@dinux.eu>
* scripttempl/pru.sc (__init_array_begin, __init_array_begin): * scripttempl/pru.sc (__init_array_begin, __init_array_begin):

View file

@ -1406,15 +1406,29 @@ plugin_notice (struct bfd_link_info *info,
ref = TRUE; ref = TRUE;
} }
/* Otherwise, it must be a new def. */
else /* A common symbol should be merged with other commons or
defs with the same name. In particular, a common ought
to be overridden by a def in a -flto object. In that
sense a common is also a ref. */
else if (bfd_is_com_section (section))
{ {
/* Ensure any symbol defined in an IR dummy BFD takes on a if (h->type == bfd_link_hash_common
&& is_ir_dummy_bfd (sym_bfd = h->u.c.p->section->owner))
{
h->type = bfd_link_hash_undefweak;
h->u.undef.abfd = sym_bfd;
}
ref = TRUE;
}
/* Otherwise, it must be a new def.
Ensure any symbol defined in an IR dummy BFD takes on a
new value from a real BFD. Weak symbols are not normally new value from a real BFD. Weak symbols are not normally
overridden by a new weak definition, and strong symbols overridden by a new weak definition, and strong symbols
will normally cause multiple definition errors. Avoid will normally cause multiple definition errors. Avoid
this by making the symbol appear to be undefined. */ this by making the symbol appear to be undefined. */
if (((h->type == bfd_link_hash_defweak else if (((h->type == bfd_link_hash_defweak
|| h->type == bfd_link_hash_defined) || h->type == bfd_link_hash_defined)
&& is_ir_dummy_bfd (sym_bfd = h->u.def.section->owner)) && is_ir_dummy_bfd (sym_bfd = h->u.def.section->owner))
|| (h->type == bfd_link_hash_common || (h->type == bfd_link_hash_common
@ -1424,14 +1438,6 @@ plugin_notice (struct bfd_link_info *info,
h->u.undef.abfd = sym_bfd; h->u.undef.abfd = sym_bfd;
} }
/* A common symbol should be merged with other commons or
defs with the same name. In particular, a common ought
to be overridden by a def in a -flto object. In that
sense a common is also a ref. */
if (bfd_is_com_section (section))
ref = TRUE;
}
if (ref) if (ref)
{ {
if ((abfd->flags & DYNAMIC) == 0) if ((abfd->flags & DYNAMIC) == 0)