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/21306 Properly turn common symbol into definition


Common symbols in executable should be overridden by definitions in
shared objects, similar to definitions in relocatable objects.  But
when common symbols in executable override common symbols in shared
objects, we must make sure that def_regular is set so that ELF linker
sees it as a definition.

Tested with mopac7 on x86-64.  OK for master?


H.J.
---
bfd/

	PR ld/19579
	PR ld/21306
	* elf-bfd.h (_bfd_elf_define_common_symbol): New prototype.
	* elflink.c (_bfd_elf_merge_symbol): Revert commits
	202ac193bbbecc96a4978d1ac3d17148253f9b01 and
	07492f668d2173da7a2bda3707ff0985e0f460b6.
	(_bfd_elf_define_common_symbol): New function.
	* elfxx-target.h (bfd_elfNN_bfd_define_common_symbol): Default
	to _bfd_elf_define_common_symbol.

ld/

	PR ld/19579
	PR ld/21306
	* testsuite/ld-elf/pr19579a.c (main): Updated.

---
 bfd/elf-bfd.h                  |  3 +++
 bfd/elflink.c                  | 29 ++++++++++++++++++++++++-----
 bfd/elfxx-target.h             |  2 +-
 ld/testsuite/ld-elf/pr19579a.c |  2 +-
 4 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index af377ee..5843d55 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2365,6 +2365,9 @@ extern bfd_boolean bfd_elf_link_record_dynamic_symbol
 extern int bfd_elf_link_record_local_dynamic_symbol
   (struct bfd_link_info *, bfd *, long);
 
+extern bfd_boolean _bfd_elf_define_common_symbol
+  (bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *);
+
 extern bfd_boolean _bfd_elf_close_and_cleanup
   (bfd *);
 
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 9bf75c8..0f1aab7 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -1544,16 +1544,13 @@ _bfd_elf_merge_symbol (bfd *abfd,
      represent variables; this can cause confusion in principle, but
      any such confusion would seem to indicate an erroneous program or
      shared library.  We also permit a common symbol in a regular
-     object to override a weak symbol in a shared object.  A common
-     symbol in executable also overrides a symbol in a shared object.  */
+     object to override a weak symbol in a shared object.  */
 
   if (newdyn
       && newdef
       && (olddef
 	  || (h->root.type == bfd_link_hash_common
-	      && (newweak
-		  || newfunc
-		  || (!olddyn && bfd_link_executable (info))))))
+	      && (newweak || newfunc))))
     {
       *override = TRUE;
       newdef = FALSE;
@@ -14122,3 +14119,25 @@ elf_append_rel (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
   BFD_ASSERT (loc + bed->s->sizeof_rel <= s->contents + s->size);
   bed->s->swap_reloc_out (abfd, rel, loc);
 }
+
+/* Convert common symbol H into a defined symbol.  Return TRUE on
+   success and FALSE on failure.  */
+
+bfd_boolean
+_bfd_elf_define_common_symbol (bfd *output_bfd,
+			       struct bfd_link_info *info,
+			       struct bfd_link_hash_entry *h)
+{
+  bfd_boolean ret
+    = bfd_generic_define_common_symbol (output_bfd, info, h);
+  if (ret)
+    {
+      /* Since def_regular may not be set if it is overridden by a
+	 dynamic definition, we need to set def_regular when it is
+	 converted to a defined symbol.  */
+      struct elf_link_hash_entry *eh
+	= (struct elf_link_hash_entry *) h;
+      eh->def_regular = 1;
+    }
+  return TRUE;
+}
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
index 6cc9f3f..9775bfa 100644
--- a/bfd/elfxx-target.h
+++ b/bfd/elfxx-target.h
@@ -194,7 +194,7 @@
 #endif
 
 #ifndef bfd_elfNN_bfd_define_common_symbol
-#define bfd_elfNN_bfd_define_common_symbol bfd_generic_define_common_symbol
+#define bfd_elfNN_bfd_define_common_symbol _bfd_elf_define_common_symbol
 #endif
 
 #ifndef bfd_elfNN_bfd_lookup_section_flags
diff --git a/ld/testsuite/ld-elf/pr19579a.c b/ld/testsuite/ld-elf/pr19579a.c
index e4a6eb1..69d0f35 100644
--- a/ld/testsuite/ld-elf/pr19579a.c
+++ b/ld/testsuite/ld-elf/pr19579a.c
@@ -9,7 +9,7 @@ extern int *bar_p (void);
 int
 main ()
 {
-  if (foo[0] == 0 && foo == foo_p () && bar[0] == 0 && bar == bar_p ())
+  if (foo[0] == 0 && foo == foo_p () && bar[0] == -1 && bar == bar_p ())
     printf ("PASS\n");
   return 0;
 }
-- 
2.9.3


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