From 6fe014bcd33686cb75e6355f9c36ce483a64ec62 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 25 Apr 2019 07:53:46 -0700 Subject: [PATCH] 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. --- ld/ChangeLog | 11 +++++++++ ld/ld.texi | 3 --- ld/plugin.c | 35 +++++++++++++++++++++++------ ld/testsuite/ld-plugin/lto.exp | 12 ++++++++++ ld/testsuite/ld-plugin/pr24406-1.c | 17 ++++++++++++++ ld/testsuite/ld-plugin/pr24406-2a.c | 17 ++++++++++++++ ld/testsuite/ld-plugin/pr24406-2b.c | 4 ++++ 7 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 ld/testsuite/ld-plugin/pr24406-1.c create mode 100644 ld/testsuite/ld-plugin/pr24406-2a.c create mode 100644 ld/testsuite/ld-plugin/pr24406-2b.c diff --git a/ld/ChangeLog b/ld/ChangeLog index 8756b2e9f5b..7a0086460e7 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,14 @@ +2019-04-25 H.J. Lu + + 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. + 2019-04-25 Sudakshina Das * testsuite/ld-aarch64/bti-pac-plt-1.d: Update. diff --git a/ld/ld.texi b/ld/ld.texi index 20140bce780..41e95934745 100644 --- a/ld/ld.texi +++ b/ld/ld.texi @@ -2438,9 +2438,6 @@ g (void) @} @end smallexample -Please keep in mind that with link-time optimization (LTO) enabled, your whole -program may be a translation unit. - @kindex --eh-frame-hdr @kindex --no-eh-frame-hdr @item --eh-frame-hdr diff --git a/ld/plugin.c b/ld/plugin.c index 0e15654dcf4..e3ca3240693 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; } diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp index 3449a076ab9..b13a77333ff 100644 --- a/ld/testsuite/ld-plugin/lto.exp +++ b/ld/testsuite/ld-plugin/lto.exp @@ -231,6 +231,9 @@ set lto_link_tests [list \ {pr23958.c} \ "" \ "libpr23958.so"] \ + [list "Build pr24406-2b.o" \ + "" "-O2 -fno-lto" \ + {pr24406-2b.c}] \ ] if { [at_least_gcc_version 4 7] } { @@ -434,6 +437,15 @@ set lto_run_tests [list \ "-O2 -flto" "" \ {dummy.c} "pr22751" "pass.out" "-flto -O2" "c" "" \ "-Wl,--whole-archive tmpdir/pr22751.a -Wl,--no-whole-archive"] \ + [list "Run pr24406-1" \ + "-O2 -flto" "" \ + {pr24406-1.c} "pr24406-1" "pass.out" "-flto -O2" "c" "" \ + "-Wl,--wrap=read"] \ + [list "Run pr24406-2" \ + "-O2 -flto" "" \ + {pr24406-2a.c} "pr24406-2" "pass.out" \ + "-flto -O2" "c" "" \ + "tmpdir/pr24406-2b.o -Wl,--wrap=cook"] \ ] if { [at_least_gcc_version 4 7] } { diff --git a/ld/testsuite/ld-plugin/pr24406-1.c b/ld/testsuite/ld-plugin/pr24406-1.c new file mode 100644 index 00000000000..43995bdb079 --- /dev/null +++ b/ld/testsuite/ld-plugin/pr24406-1.c @@ -0,0 +1,17 @@ +#include +#include + +ssize_t +__wrap_read (int fd, void *buffer, size_t count) +{ + puts ("PASS"); + return fd + count + sizeof (buffer); +} + + +int +main () +{ + int i = read (1, "abc", 5); + return i == 0; +} diff --git a/ld/testsuite/ld-plugin/pr24406-2a.c b/ld/testsuite/ld-plugin/pr24406-2a.c new file mode 100644 index 00000000000..14f54ba0eab --- /dev/null +++ b/ld/testsuite/ld-plugin/pr24406-2a.c @@ -0,0 +1,17 @@ +#include + +extern int cook(void); + +int __wrap_cook(void) +{ + puts ("PASS"); + return 0; +} + +int main() +{ + if (cook () == -1) + __builtin_abort (); + + return 0; +} diff --git a/ld/testsuite/ld-plugin/pr24406-2b.c b/ld/testsuite/ld-plugin/pr24406-2b.c new file mode 100644 index 00000000000..bfb69dfe514 --- /dev/null +++ b/ld/testsuite/ld-plugin/pr24406-2b.c @@ -0,0 +1,4 @@ +int cook(void) +{ + return -1; +}