diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2019-04-25 07:53:46 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2019-04-25 07:54:00 -0700 |
commit | 6fe014bcd33686cb75e6355f9c36ce483a64ec62 (patch) | |
tree | d1ff965badb244f102cee2bb1f3f9e6df38c84e5 /ld/plugin.c | |
parent | 723adb650a31859d7cc45832cb8adca0206455ed (diff) | |
download | gdb-6fe014bcd33686cb75e6355f9c36ce483a64ec62.zip gdb-6fe014bcd33686cb75e6355f9c36ce483a64ec62.tar.gz gdb-6fe014bcd33686cb75e6355f9c36ce483a64ec62.tar.bz2 |
LTO: Properly handle wrapper symbols in IR
When a wrapper symbol, __wrap_FOO, is defined in IR, its resolution
should be LDPR_PREVAILING_DEF, not PREVAILING_DEF_IRONLY, since LTO
doesn't know that __wrap_FOO provides definition of FOO. And resolution
of FOO should be LDPR_RESOLVED_IR since it is resolved by __wrap_FOO in
IR.
PR ld/24406
* ld.texi: Remove LTO warning from --wrap.
* plugin.c (get_symbols): Update resolution for wrapper and
wrapped symbols.
* testsuite/ld-plugin/lto.exp: Run ld/24406 tests.
* testsuite/ld-plugin/pr24406-1.c: New file.
* testsuite/ld-plugin/pr24406-2a.c: Likewise.
* testsuite/ld-plugin/pr24406-2b.c: Likewise.
Diffstat (limited to 'ld/plugin.c')
-rw-r--r-- | ld/plugin.c | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/ld/plugin.c b/ld/plugin.c index 0e15654..e3ca324 100644 --- a/ld/plugin.c +++ b/ld/plugin.c @@ -741,13 +741,32 @@ get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms, struct bfd_link_hash_entry *blhe; asection *owner_sec; int res; + struct bfd_link_hash_entry *h + = bfd_link_hash_lookup (link_info.hash, syms[n].name, + FALSE, FALSE, TRUE); + enum { wrap_none, wrapper, wrapped } wrap_status = wrap_none; - if (syms[n].def != LDPK_UNDEF) - blhe = bfd_link_hash_lookup (link_info.hash, syms[n].name, - FALSE, FALSE, TRUE); + if (syms[n].def != LDPK_UNDEF && syms[n].def != LDPK_WEAKUNDEF) + { + blhe = h; + if (blhe) + { + /* Check if a symbol is a wrapper symbol. */ + struct bfd_link_hash_entry *unwrap + = unwrap_hash_lookup (&link_info, (bfd *) abfd, blhe); + if (unwrap && unwrap != h) + wrap_status = wrapper; + } + } else - blhe = bfd_wrapped_link_hash_lookup (link_info.output_bfd, &link_info, - syms[n].name, FALSE, FALSE, TRUE); + { + blhe = bfd_wrapped_link_hash_lookup (link_info.output_bfd, + &link_info, syms[n].name, + FALSE, FALSE, TRUE); + /* Check if a symbol is a wrapped symbol. */ + if (blhe && blhe != h) + wrap_status = wrapped; + } if (!blhe) { /* The plugin is called to claim symbols in an archive element @@ -833,9 +852,11 @@ get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms, /* We need to know if the sym is referenced from non-IR files. Or even potentially-referenced, perhaps in a future final link if this is a partial one, perhaps dynamically at load-time if the - symbol is externally visible. */ - if (blhe->non_ir_ref_regular) + symbol is externally visible. Also check for wrapper symbol. */ + if (blhe->non_ir_ref_regular || wrap_status == wrapper) res = LDPR_PREVAILING_DEF; + else if (wrap_status == wrapped) + res = LDPR_RESOLVED_IR; else if (is_visible_from_outside (&syms[n], blhe)) res = def_ironly_exp; } |