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] PR ld/19579: [Regression] link error linking fortran code with PIE


Common symbol in executable is a definition, which overrides definition
from shared objects.  When linker sees a new definition from a shared
object, the new dynamic definition should be overridden by the previous
common symbol in executable.

Tested on x86 and s390.  I will check it into trunk and backport it to
2.26 branch laster.

H.J.
---
bfd/

	PR ld/19579
	* elflink.c (_bfd_elf_merge_symbol): Treat common symbol in
	executable as definition if the new definition comes from a
	shared library.

ld/

	PR ld/19579
	* testsuite/ld-elf/pr19579a.c: New file.
	* testsuite/ld-elf/pr19579b.c: Likewise.
	* testsuite/ld-elf/shared.exp (build_tests): Prepare for PR
	ld/19579 test.
	(run_tests): Add a test for PR ld/19579.
---
 bfd/elflink.c                  |  5 ++++-
 ld/testsuite/ld-elf/pr19579a.c | 15 +++++++++++++++
 ld/testsuite/ld-elf/pr19579b.c | 14 ++++++++++++++
 ld/testsuite/ld-elf/shared.exp |  9 +++++++++
 4 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 ld/testsuite/ld-elf/pr19579a.c
 create mode 100644 ld/testsuite/ld-elf/pr19579b.c

diff --git a/bfd/elflink.c b/bfd/elflink.c
index 0e3abff..39157bf 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -1172,9 +1172,12 @@ _bfd_elf_merge_symbol (bfd *abfd,
 
   newdef = !bfd_is_und_section (sec) && !bfd_is_com_section (sec);
 
+  /* The old common symbol in executable is a definition if the new
+     definition comes from a shared library.  */
   olddef = (h->root.type != bfd_link_hash_undefined
 	    && h->root.type != bfd_link_hash_undefweak
-	    && h->root.type != bfd_link_hash_common);
+	    && (h->root.type != bfd_link_hash_common
+		|| (!olddyn && newdyn && bfd_link_executable (info))));
 
   /* NEWFUNC and OLDFUNC indicate whether the new or old symbol,
      respectively, appear to be a function.  */
diff --git a/ld/testsuite/ld-elf/pr19579a.c b/ld/testsuite/ld-elf/pr19579a.c
new file mode 100644
index 0000000..e4a6eb1
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr19579a.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int foo[1];
+int bar[2];
+
+extern int *foo_p (void);
+extern int *bar_p (void);
+
+int
+main ()
+{
+  if (foo[0] == 0 && foo == foo_p () && bar[0] == 0 && bar == bar_p ())
+    printf ("PASS\n");
+  return 0;
+}
diff --git a/ld/testsuite/ld-elf/pr19579b.c b/ld/testsuite/ld-elf/pr19579b.c
new file mode 100644
index 0000000..d906545
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr19579b.c
@@ -0,0 +1,14 @@
+int foo[2];
+int bar[2] = { -1, -1 };
+
+int *
+foo_p (void)
+{
+  return foo;
+}
+
+int *
+bar_p (void)
+{
+  return bar;
+}
diff --git a/ld/testsuite/ld-elf/shared.exp b/ld/testsuite/ld-elf/shared.exp
index 678ab1b..7c7a171 100644
--- a/ld/testsuite/ld-elf/shared.exp
+++ b/ld/testsuite/ld-elf/shared.exp
@@ -279,6 +279,12 @@ set build_tests {
   {"Build libpr19073.so"
    "-shared -Wl,--version-script=pr19073.map tmpdir/pr19073a.o" "-fPIC"
    {dummy.c} {{readelf {--dyn-syms --wide} pr19073.rd}} "libpr19073.so"}
+  {"Build pr19579a.o"
+   "-r -nostdlib" "-fPIE"
+   {pr19579a.c} {} "pr19073a.o"}
+  {"Build libpr19579.so"
+   "-shared" "-fPIC"
+   {pr19579b.c} {} "libpr19579.so"}
 }
 
 run_cc_link_tests $build_tests
@@ -432,6 +438,9 @@ set run_tests {
     {"Run pr18458"
      "tmpdir/libpr18458a.so tmpdir/libpr18458b.so -z now" ""
      {pr18458c.c} "pr18458" "pass.out"}
+    {"Run pr19579"
+     "-pie -z text tmpdir/pr19579a.o tmpdir/libpr19579.so" ""
+     {dummy.c} "pr19579" "pass.out"}
 }
 
 # NetBSD ELF systems do not currently support the .*_array sections.
-- 
2.5.0


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