This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] LTO: Properly handle wrapper symbols in IR


On Tue, Apr 2, 2019 at 4:12 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Tue, Apr 2, 2019 at 3:12 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> >
> > Change resolution from PREVAILING_DEF_IRONLY to LDPR_PREVAILING_DEF
> > for wrapper symbol.
> >
> >         PR ld/24406
> >         * ld.texi: Remove LTO warning from --wrap.
> >         * plugin.c (get_symbols): Change resolution to LDPR_PREVAILING_DEF
> >         for wrapper symbol.
> >         * testsuite/ld-plugin/lto.exp: Run ld/24406 test.
> >         * testsuite/ld-plugin/pr24406.c: New file.
>
> This patch is incomplete.  I  am working on it.

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.


-- 
H.J.
From 4f5116cc9b5fdd6f9a0c9be0bd0bf77ebd5d85c7 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Tue, 2 Apr 2019 15:06:10 -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/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 ++++
 6 files changed, 78 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/ld.texi b/ld/ld.texi
index 0bcbec463f..f652740c04 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -2415,9 +2415,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 a76e44c79f..9d86c771f1 100644
--- a/ld/plugin.c
+++ b/ld/plugin.c
@@ -744,13 +744,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
@@ -836,9 +855,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 ce57705f46..c828ca5ab9 100644
--- a/ld/testsuite/ld-plugin/lto.exp
+++ b/ld/testsuite/ld-plugin/lto.exp
@@ -246,6 +246,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] } {
@@ -461,6 +464,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 0000000000..43995bdb07
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr24406-1.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <unistd.h>
+
+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 0000000000..14f54ba0ea
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr24406-2a.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+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 0000000000..bfb69dfe51
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr24406-2b.c
@@ -0,0 +1,4 @@
+int cook(void)
+{
+  return -1;
+}
-- 
2.20.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]