diff options
author | Alan Modra <amodra@gmail.com> | 2017-05-16 07:56:41 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2017-05-16 10:35:02 +0930 |
commit | 4070765b1a1640ff8f43483cd9ee06727f658dfe (patch) | |
tree | ea06dfc18946668b4a75631e39b22a822f2fd26a /ld/plugin.c | |
parent | 8cc2a9796024f2dd472985cc8ed1c65a85ec9a35 (diff) | |
download | gdb-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.
Diffstat (limited to 'ld/plugin.c')
-rw-r--r-- | ld/plugin.c | 65 |
1 files changed, 35 insertions, 30 deletions
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; } } |