aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2017-05-16 07:56:41 +0930
committerAlan Modra <amodra@gmail.com>2017-05-16 10:35:02 +0930
commit4070765b1a1640ff8f43483cd9ee06727f658dfe (patch)
treeea06dfc18946668b4a75631e39b22a822f2fd26a
parent8cc2a9796024f2dd472985cc8ed1c65a85ec9a35 (diff)
downloadgdb-4070765b1a1640ff8f43483cd9ee06727f658dfe.zip
gdb-4070765b1a1640ff8f43483cd9ee06727f658dfe.tar.gz
gdb-4070765b1a1640ff8f43483cd9ee06727f658dfe.tar.bz2
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.
-rw-r--r--bfd/ChangeLog9
-rw-r--r--bfd/elf64-ppc.c1
-rw-r--r--bfd/elflink.c11
-rw-r--r--bfd/linker.c3
-rw-r--r--include/ChangeLog5
-rw-r--r--include/bfdlink.h10
-rw-r--r--ld/ChangeLog6
-rw-r--r--ld/plugin.c65
8 files changed, 69 insertions, 41 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 52c192d..8b3f1a5 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index a20d9b3..a2cc373 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -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;
diff --git a/bfd/elflink.c b/bfd/elflink.c
index ba50b68..8eaf533 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -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
diff --git a/bfd/linker.c b/bfd/linker.c
index 2f56b46..1f493a3 100644
--- a/bfd/linker.c
+++ b/bfd/linker.c
@@ -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);
diff --git a/include/ChangeLog b/include/ChangeLog
index 67bf02f..8425760 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -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>
diff --git a/include/bfdlink.h b/include/bfdlink.h
index cb4bad9..41f5338 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -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. */
diff --git a/ld/ChangeLog b/ld/ChangeLog
index a8dad5c..9fdd758 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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.
diff --git a/ld/plugin.c b/ld/plugin.c
index 164b5db..087cedc 100644
--- a/ld/plugin.c
+++ b/ld/plugin.c
@@ -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;
}
}