non_ir_ref_dynamic

dynamic_ref_after_ir_def is a little odd compared to other symbol
flags in that as the name suggests, it is set only for certain
references after a definition.  It turns out that setting a flag for
any non-ir reference from a dynamic object can be used to solve the
problem for which this flag was invented, which I think is a cleaner.
This patch does that, and sets non_ir_ref only for regular object
references.

include/
	* bfdlink.h (struct bfd_link_hash_entry): Update non_ir_ref
	comment.  Rename dynamic_ref_after_ir_def to non_ir_ref_dynamic.
ld/
	* plugin.c (is_visible_from_outside): Use non_ir_ref_dynamic.
	(plugin_notice): Set non_ir_ref for references from regular
	objects, non_ir_ref_dynamic for references from dynamic objects.
bfd/
	* elf64-ppc.c (add_symbol_adjust): Transfer non_ir_ref_dynamic.
	* elflink.c (elf_link_add_object_symbols): Update to use
	non_ir_ref_dynamic.
	(elf_link_input_bfd): Test non_ir_ref_dynamic in addition to
	non_ir_ref.
	* linker.c (_bfd_generic_link_add_one_symbol): Likewise.
This commit is contained in:
Alan Modra 2017-05-16 07:56:41 +09:30
parent 8cc2a97960
commit 4070765b1a
8 changed files with 69 additions and 41 deletions

View File

@ -1,3 +1,12 @@
2017-05-16 Alan Modra <amodra@gmail.com>
* elf64-ppc.c (add_symbol_adjust): Transfer non_ir_ref_dynamic.
* elflink.c (elf_link_add_object_symbols): Update to use
non_ir_ref_dynamic.
(elf_link_input_bfd): Test non_ir_ref_dynamic in addition to
non_ir_ref.
* linker.c (_bfd_generic_link_add_one_symbol): Likewise.
2017-05-15 Maciej W. Rozycki <macro@imgtec.com>
* elfxx-mips.c (print_mips_ases): Handle MIPS16e2 ASE.

View File

@ -5119,6 +5119,7 @@ add_symbol_adjust (struct ppc_link_hash_entry *eh, struct bfd_link_info *info)
/* Propagate reference flags from entry symbol to function
descriptor symbol. */
fdh->elf.root.non_ir_ref |= eh->elf.root.non_ir_ref;
fdh->elf.root.non_ir_ref_dynamic |= eh->elf.root.non_ir_ref_dynamic;
fdh->elf.ref_regular |= eh->elf.ref_regular;
fdh->elf.ref_regular_nonweak |= eh->elf.ref_regular_nonweak;

View File

@ -4939,7 +4939,7 @@ error_free_dyn:
struct elf_link_hash_entry *h;
bfd_size_type size;
unsigned int alignment_power;
unsigned int dynamic_ref_after_ir_def;
unsigned int non_ir_ref_dynamic;
for (p = htab->root.table.table[i]; p != NULL; p = p->next)
{
@ -4961,10 +4961,10 @@ error_free_dyn:
size = 0;
alignment_power = 0;
}
/* Preserve dynamic_ref_after_ir_def so that this symbol
/* Preserve non_ir_ref_dynamic so that this symbol
will be exported when the dynamic lib becomes needed
in the second pass. */
dynamic_ref_after_ir_def = h->root.dynamic_ref_after_ir_def;
non_ir_ref_dynamic = h->root.non_ir_ref_dynamic;
memcpy (p, old_ent, htab->root.table.entsize);
old_ent = (char *) old_ent + htab->root.table.entsize;
h = (struct elf_link_hash_entry *) p;
@ -4981,7 +4981,7 @@ error_free_dyn:
if (alignment_power > h->root.u.c.p->alignment_power)
h->root.u.c.p->alignment_power = alignment_power;
}
h->root.dynamic_ref_after_ir_def = dynamic_ref_after_ir_def;
h->root.non_ir_ref_dynamic = non_ir_ref_dynamic;
}
}
@ -10472,7 +10472,8 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
linker may attach linker created dynamic sections
to the plugin bfd. Symbols defined in linker
created sections are not plugin symbols. */
if (h->root.non_ir_ref
if ((h->root.non_ir_ref
|| h->root.non_ir_ref_dynamic)
&& (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
&& (h->root.u.def.section->flags

View File

@ -1735,7 +1735,8 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
otherwise add a warning. */
if ((!info->lto_plugin_active
&& (h->u.undef.next != NULL || info->hash->undefs_tail == h))
|| h->non_ir_ref)
|| h->non_ir_ref
|| h->non_ir_ref_dynamic)
{
(*info->callbacks->warning) (info, string, h->root.string,
hash_entry_bfd (h), NULL, 0);

View File

@ -1,3 +1,8 @@
2017-05-16 Alan Modra <amodra@gmail.com>
* bfdlink.h (struct bfd_link_hash_entry): Update non_ir_ref
comment. Rename dynamic_ref_after_ir_def to non_ir_ref_dynamic.
2017-05-15 Maciej W. Rozycki <macro@imgtec.com>
Matthew Fortune <matthew.fortune@imgtec.com>

View File

@ -100,13 +100,13 @@ struct bfd_link_hash_entry
/* Type of this entry. */
ENUM_BITFIELD (bfd_link_hash_type) type : 8;
/* Symbol is referenced in a normal object file, as distict from a LTO
IR object file. */
/* Symbol is referenced in a normal regular object file,
as distinct from a LTO IR object file. */
unsigned int non_ir_ref : 1;
/* Symbol is referenced in a dynamic object after it has been defined
in an IR object. */
unsigned int dynamic_ref_after_ir_def : 1;
/* Symbol is referenced in a normal dynamic object file,
as distinct from a LTO IR object file. */
unsigned int non_ir_ref_dynamic : 1;
/* Symbol is a built-in define. These will be overridden by PROVIDE
in a linker script. */

View File

@ -1,3 +1,9 @@
2017-05-16 Alan Modra <amodra@gmail.com>
* plugin.c (is_visible_from_outside): Use non_ir_ref_dynamic.
(plugin_notice): Set non_ir_ref for references from regular
objects, non_ir_ref_dynamic for references from dynamic objects.
2017-05-15 Maciej W. Rozycki <macro@imgtec.com>
* testsuite/ld-mips-elf/mips16e2-pcrel-0.d: New test.

View File

@ -629,7 +629,7 @@ is_visible_from_outside (struct ld_plugin_symbol *lsym,
if (bfd_link_relocatable (&link_info))
return TRUE;
if (blhe->dynamic_ref_after_ir_def
if (blhe->non_ir_ref_dynamic
|| link_info.export_dynamic
|| bfd_link_dll (&link_info))
{
@ -1266,9 +1266,10 @@ plugin_call_cleanup (void)
/* To determine which symbols should be resolved LDPR_PREVAILING_DEF
and which LDPR_PREVAILING_DEF_IRONLY, we notice all the symbols as
the linker adds them to the linker hash table. Mark those
referenced from a non-IR file with non_ir_ref. We have to
notice_all symbols, because we won't necessarily know until later
which ones will be contributed by IR files. */
referenced from a non-IR file with non_ir_ref or
non_ir_ref_dynamic as appropriate. We have to notice_all symbols,
because we won't necessarily know until later which ones will be
contributed by IR files. */
static bfd_boolean
plugin_notice (struct bfd_link_info *info,
struct bfd_link_hash_entry *h,
@ -1283,6 +1284,7 @@ plugin_notice (struct bfd_link_info *info,
if (h != NULL)
{
bfd *sym_bfd;
bfd_boolean ref = FALSE;
if (h->type == bfd_link_hash_warning)
h = h->u.i.link;
@ -1298,13 +1300,17 @@ plugin_notice (struct bfd_link_info *info,
{
/* ??? Some of this is questionable. See comments in
_bfd_generic_link_add_one_symbol for case IND. */
if (h->type != bfd_link_hash_new)
if (h->type != bfd_link_hash_new
|| inh->type == bfd_link_hash_new)
{
h->non_ir_ref = TRUE;
inh->non_ir_ref = TRUE;
if ((abfd->flags & DYNAMIC) == 0)
inh->non_ir_ref = TRUE;
else
inh->non_ir_ref_dynamic = TRUE;
}
else if (inh->type == bfd_link_hash_new)
inh->non_ir_ref = TRUE;
if (h->type != bfd_link_hash_new)
ref = TRUE;
}
/* Nothing to do here for warning symbols. */
@ -1318,34 +1324,18 @@ plugin_notice (struct bfd_link_info *info,
/* If this is a ref, set non_ir_ref. */
else if (bfd_is_und_section (section))
{
if (h->type == bfd_link_hash_defweak
|| h->type == bfd_link_hash_defined)
{
/* Check if the symbol is referenced in a dynamic object
after it has been defined in an IR object. */
if ((abfd->flags & DYNAMIC) != 0
&& is_ir_dummy_bfd (h->u.def.section->owner))
h->dynamic_ref_after_ir_def = TRUE;
}
/* Replace the undefined dummy bfd with the real one. */
else if ((h->type == bfd_link_hash_undefined
|| h->type == bfd_link_hash_undefweak)
&& (h->u.undef.abfd == NULL
|| (h->u.undef.abfd->flags & BFD_PLUGIN) != 0))
if ((h->type == bfd_link_hash_undefined
|| h->type == bfd_link_hash_undefweak)
&& (h->u.undef.abfd == NULL
|| (h->u.undef.abfd->flags & BFD_PLUGIN) != 0))
h->u.undef.abfd = abfd;
h->non_ir_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. */
if (bfd_is_com_section (section))
h->non_ir_ref = TRUE;
/* Ensure any symbol defined in an IR dummy BFD takes on a
new value from a real BFD. Weak symbols are not normally
overridden by a new weak definition, and strong symbols
@ -1360,6 +1350,21 @@ plugin_notice (struct bfd_link_info *info,
h->type = bfd_link_hash_undefweak;
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 ((abfd->flags & DYNAMIC) == 0)
h->non_ir_ref = TRUE;
else
h->non_ir_ref_dynamic = TRUE;
}
}