This is the mail archive of the binutils-cvs@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]

[binutils-gdb] Mark the plugin symbol undefined


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=60f79275127603876d94da4bf4e3f6212903b407

commit 60f79275127603876d94da4bf4e3f6212903b407
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Feb 3 09:03:23 2015 -0800

    Mark the plugin symbol undefined
    
    LTO may optimize out a plugin symbol, which is also referenced by a
    non-IR file.  When that happens, we should mark the plugin symbol
    undefined.  It isn't the problem since LTO already determined the
    symbols in the non-IR file aren't used.
    
    bfd/
    
    	PR ld/12365
    	PR ld/14272
    	* elflink.c (_bfd_elf_fix_symbol_flags): Mark the plugin symbol
    	undefined if it is referenced from a non-IR file.
    
    ld/testsuite/
    
    	PR ld/12365
    	* ld-plugin/pr12365a.c: New file.
    	* ld-plugin/pr12365b.c: Likewise.
    	* ld-plugin/pr12365c.c: Likewise.
    
    	* ld-plugin/lto.exp (lto_link_tests): Prepare for the PR ld/12365
    	test.
    	Run the PR ld/12365 test.

Diff:
---
 bfd/ChangeLog                     |  7 ++++
 bfd/elflink.c                     | 14 +++++++
 ld/testsuite/ChangeLog            | 11 ++++++
 ld/testsuite/ld-plugin/lto.exp    | 10 +++++
 ld/testsuite/ld-plugin/pr12365a.c | 25 +++++++++++++
 ld/testsuite/ld-plugin/pr12365b.c | 47 +++++++++++++++++++++++
 ld/testsuite/ld-plugin/pr12365c.c | 79 +++++++++++++++++++++++++++++++++++++++
 7 files changed, 193 insertions(+)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 4924f03..a7fe73c 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2015-02-03  H.J. Lu  <hongjiu.lu@intel.com>
+
+	PR ld/12365
+	PR ld/14272
+	* elflink.c (_bfd_elf_fix_symbol_flags): Mark the plugin symbol
+	undefined if it is referenced from a non-IR file.
+
 2015-02-03  Nick Clifton  <nickc@redhat.com>
 
 	PR binutils/17512
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 26af870..604cfb6 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -2423,6 +2423,20 @@ _bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h,
     }
   else
     {
+      /* If a plugin symbol is referenced from a non-IR file, mark
+         the symbol as undefined, except for symbol for linker
+	 created section.  */
+      if (h->root.non_ir_ref
+	  && (h->root.type == bfd_link_hash_defined
+	      || h->root.type == bfd_link_hash_defweak)
+	  && (h->root.u.def.section->flags & SEC_LINKER_CREATED) == 0
+	  && h->root.u.def.section->owner != NULL
+	  && (h->root.u.def.section->owner->flags & BFD_PLUGIN) != 0)
+	{
+	  h->root.type = bfd_link_hash_undefined;
+	  h->root.u.undef.abfd = h->root.u.def.section->owner;
+	}
+
       /* Unfortunately, NON_ELF is only correct if the symbol
 	 was first seen in a non-ELF file.  Fortunately, if the symbol
 	 was first seen in an ELF file, we're probably OK unless the
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 8351d6f..876bafa 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,5 +1,16 @@
 2015-02-03  H.J. Lu  <hongjiu.lu@intel.com>
 
+	PR ld/12365
+	* ld-plugin/pr12365a.c: New file.
+	* ld-plugin/pr12365b.c: Likewise.
+	* ld-plugin/pr12365c.c: Likewise.
+
+	* ld-plugin/lto.exp (lto_link_tests): Prepare for the PR ld/12365
+	test.
+	Run the PR ld/12365 test.
+
+2015-02-03  H.J. Lu  <hongjiu.lu@intel.com>
+
 	PR ld/14918
 	* ld-plugin/lto.exp (lto_link_elf_tests): Add PR ld/14918 test.
 
diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp
index f0643cc..400e683 100644
--- a/ld/testsuite/ld-plugin/lto.exp
+++ b/ld/testsuite/ld-plugin/lto.exp
@@ -88,6 +88,9 @@ set lto_link_tests [list \
   [list "LTO 6" \
    "-O2 -flto -fuse-linker-plugin" "" \
    {lto-6.c} {} "lto-6.exe" "c"] \
+  [list "Compile PR ld/12365" \
+   "" "-flto -O2 $lto_fat" \
+   {pr12365a.c pr12365b.c pr12365c.c} {} ""] \
   [list "Compile 9" \
    "" "-O2 -finline -flto" \
    {lto-9.cc} {} "" "c++"] \
@@ -380,6 +383,13 @@ if {![string match "" $catch_output]} {
 
 if { [at_least_gcc_version 4 7] } {
     # Check expected LTO linker errors.
+    set testname "PR ld/12365"
+    set exec_output [run_host_cmd "$CC" "-O2 -flto -fuse-linker-plugin tmpdir/pr12365a.o tmpdir/pr12365b.o tmpdir/pr12365c.o"]
+    if { [ regexp "undefined reference to `my_bcopy'" $exec_output ] } {
+	pass $testname
+    } {
+	fail $testname
+    }
     set testname "PR ld/12942 (3)"
     set exec_output [run_host_cmd "$CXX" "-O2 -flto -fuse-linker-plugin tmpdir/pr12942b.o tmpdir/pr12942a.o"]
     if { [ regexp "undefined reference to `link_error\\(\\)'" $exec_output ] } {
diff --git a/ld/testsuite/ld-plugin/pr12365a.c b/ld/testsuite/ld-plugin/pr12365a.c
new file mode 100644
index 0000000..a9bb6c6
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr12365a.c
@@ -0,0 +1,25 @@
+extern void abort(void);
+extern void main_test (void);
+extern void abort (void);
+int inside_main;
+
+int
+main ()
+{
+  inside_main = 1;
+  main_test ();
+  inside_main = 0;
+  return 0;
+}
+
+/* When optimizing, all the constant cases should have been
+   constant folded, so no calls to link_error should remain.
+   In any case, link_error should not be called.  */
+
+#ifndef __OPTIMIZE__
+void
+link_error (void)
+{
+  abort ();
+}
+#endif
diff --git a/ld/testsuite/ld-plugin/pr12365b.c b/ld/testsuite/ld-plugin/pr12365b.c
new file mode 100644
index 0000000..a5a80e0
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr12365b.c
@@ -0,0 +1,47 @@
+#define ASMNAME(cname)  ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+#define ASMNAME2(prefix, cname) STRING (prefix) cname
+#define STRING(x)    #x
+
+typedef __SIZE_TYPE__ size_t;
+extern void abort (void);
+extern void *memcpy (void *, const void *, size_t)
+  __asm (ASMNAME ("my_memcpy"));
+extern void bcopy (const void *, void *, size_t)
+  __asm (ASMNAME ("my_bcopy"));
+extern void *memset (void *, int, size_t)
+  __asm (ASMNAME ("my_memset"));
+extern void bzero (void *, size_t)
+  __asm (ASMNAME ("my_bzero"));
+extern int memcmp (const void *, const void *, size_t);
+
+struct A { char c[32]; } a = { "foobar" };
+char x[64] = "foobar", y[64];
+int i = 39, j = 6, k = 4;
+
+extern int inside_main;
+
+void
+main_test (void)
+{
+  struct A b = a;
+  struct A c = { { 'x' } };
+
+  inside_main = 1;
+
+  if (memcmp (b.c, x, 32) || c.c[0] != 'x' || memcmp (c.c + 1, x + 32, 31))
+    abort ();
+  if (__builtin_memcpy (y, x, i) != y || memcmp (x, y, 64))
+    abort ();
+  if (memcpy (y + 6, x, j) != y + 6
+      || memcmp (x, y, 6) || memcmp (x, y + 6, 58))
+    abort ();
+  if (__builtin_memset (y + 2, 'X', k) != y + 2
+      || memcmp (y, "foXXXXfoobar", 13))
+    abort ();
+  bcopy (y + 1, y + 2, 6);
+  if (memcmp (y, "fooXXXXfobar", 13))
+    abort ();
+  __builtin_bzero (y + 4, 2);
+  if (memcmp (y, "fooX\0\0Xfobar", 13))
+    abort ();
+}
diff --git a/ld/testsuite/ld-plugin/pr12365c.c b/ld/testsuite/ld-plugin/pr12365c.c
new file mode 100644
index 0000000..2edd0ff
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr12365c.c
@@ -0,0 +1,79 @@
+extern void abort (void);
+extern int inside_main;
+typedef __SIZE_TYPE__ size_t;
+
+#define TEST_ABORT if (inside_main) abort()
+
+void *
+my_memcpy (void *d, const void *s, size_t n)
+{
+  char *dst = (char *) d;
+  const char *src = (const char *) s;
+  while (n--)
+    *dst++ = *src++;
+  return (char *) d;
+}
+
+void
+my_bcopy (const void *s, void *d, size_t n)
+{
+  char *dst = (char *) d;
+  const char *src = (const char *) s;
+  if (src >= dst)
+    while (n--)
+      *dst++ = *src++;
+  else
+    {
+      dst += n;
+      src += n;
+      while (n--)
+        *--dst = *--src;
+    }
+}
+
+void *
+my_memset (void *d, int c, size_t n)
+{
+  char *dst = (char *) d;
+  while (n--)
+    *dst++ = c;
+  return (char *) d;
+}
+
+void
+my_bzero (void *d, size_t n)
+{
+  char *dst = (char *) d;
+  while (n--)
+    *dst++ = '\0';
+}
+
+void *
+memcpy (void *d, const void *s, size_t n)
+{
+  void *result = my_memcpy (d, s, n);
+  TEST_ABORT;
+  return result;
+}
+
+void
+bcopy (const void *s, void *d, size_t n)
+{
+  my_bcopy (s, d, n);
+  TEST_ABORT;
+}
+
+void *
+memset (void *d, int c, size_t n)
+{
+  void *result = my_memset (d, c, n);
+  TEST_ABORT;
+  return result;
+}
+
+void
+bzero (void *d, size_t n)
+{
+  my_bzero (d, n);
+  TEST_ABORT;
+}


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