This is the mail archive of the binutils@sources.redhat.com 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: Fix weak symbol


This patch finally fixes the weak symbol handling. But you will need
glibc 2.3.2 or above to pass the weak symbol test.


H.J.
----
bfd/

2003-03-24  H.J. Lu <hjl at gnu dot org>

	* elflink.h (elf_merge_symbol): Correctly handle weak definiton.

ld/testsuite/

2003-03-24  H.J. Lu <hjl at gnu dot org>

	* ld-elfvers/vers18.dsym: Updated for weak definiton change.
	* ld-elfvers/vers18.ver: Likewise.
	* ld-elfvers/vers19.ver: Likewise.

	* ld-elfweak/elfweak.exp: Remove xfail.

--- binutils/bfd/elflink.h.weak	2003-03-24 09:53:51.000000000 -0800
+++ binutils/bfd/elflink.h	2003-03-24 10:08:17.000000000 -0800
@@ -483,6 +483,7 @@ elf_merge_symbol (abfd, info, name, sym,
   int bind;
   bfd *oldbfd;
   bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
+  bfd_boolean newweakdef, oldweakdef, newweakundef, oldweakundef;
 
   *skip = FALSE;
   *override = FALSE;
@@ -657,6 +658,49 @@ elf_merge_symbol (abfd, info, name, sym,
       return TRUE;
     }
 
+  /* We need to treat weak definiton right, depending on if there is a
+     definition from a dynamic object.  */
+  if (bind == STB_WEAK)
+    {
+      if (olddef == TRUE)
+	{
+	   newweakdef = TRUE;
+	   newweakundef = FALSE;
+	}
+      else
+	{
+	   newweakdef = FALSE;
+	   newweakundef = TRUE;
+	}
+    }
+  else
+    newweakdef = newweakundef = FALSE;
+
+  /* If the new weak definition comes from a relocatable file and the
+     old symbol comes from a dynamic object, we treat the new one as
+     strong.  */
+  if (newweakdef && !newdyn && olddyn)
+    newweakdef = FALSE;
+
+  if (h->root.type == bfd_link_hash_defweak)
+    {
+      oldweakdef = TRUE;
+      oldweakundef = FALSE;
+    }
+  else if (h->root.type == bfd_link_hash_undefweak)
+    {
+      oldweakdef = FALSE;
+      oldweakundef = TRUE;
+    }
+  else
+    oldweakdef = oldweakundef = FALSE;
+
+  /* If the old weak definition comes from a relocatable file and the
+     new symbol comes from a dynamic object, we treat the old one as
+     strong.  */
+  if (oldweakdef && !olddyn && newdyn)
+    oldweakdef = FALSE;
+
   /* NEWDYNCOMMON and OLDDYNCOMMON indicate whether the new or old
      symbol, respectively, appears to be a common symbol in a dynamic
      object.  If a symbol appears in an uninitialized section, and is
@@ -685,7 +729,8 @@ elf_merge_symbol (abfd, info, name, sym,
       && (sec->flags & SEC_ALLOC) != 0
       && (sec->flags & SEC_LOAD) == 0
       && sym->st_size > 0
-      && bind != STB_WEAK
+      && !newweakdef
+      && !newweakundef
       && ELF_ST_TYPE (sym->st_info) != STT_FUNC)
     newdyncommon = TRUE;
   else
@@ -708,9 +753,10 @@ elf_merge_symbol (abfd, info, name, sym,
      a shared object, in which case, the DT_NEEDED entry may not be
      required at the run time.  */
 
-  if ((! dt_needed && h->root.type == bfd_link_hash_defweak)
-      || h->root.type == bfd_link_hash_undefweak
-      || bind == STB_WEAK)
+  if ((! dt_needed && oldweakdef)
+      || oldweakundef
+      || newweakdef
+      || newweakundef)
     *type_change_ok = TRUE;
 
   /* It's OK to change the size if either the existing symbol or the
@@ -768,11 +814,13 @@ elf_merge_symbol (abfd, info, name, sym,
       && newdef
       && (olddef
 	  || (h->root.type == bfd_link_hash_common
-	      && (bind == STB_WEAK
+	      && (newweakdef
+		  || newweakundef
 		  || ELF_ST_TYPE (sym->st_info) == STT_FUNC)))
-      && (h->root.type != bfd_link_hash_defweak
+      && (!oldweakdef
 	  || dt_needed
-	  || bind == STB_WEAK))
+	  || newweakdef
+	  || newweakundef))
     {
       *override = TRUE;
       newdef = FALSE;
@@ -824,13 +872,11 @@ elf_merge_symbol (abfd, info, name, sym,
   if (! newdyn
       && (newdef
 	  || (bfd_is_com_section (sec)
-	      && (h->root.type == bfd_link_hash_defweak
-		  || h->type == STT_FUNC)))
+	      && (oldweakdef || h->type == STT_FUNC)))
       && olddyn
       && olddef
       && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
-      && (bind != STB_WEAK
-	  || h->root.type == bfd_link_hash_defweak))
+      && ((!newweakdef && !newweakundef) || oldweakdef))
     {
       /* Change the hash table entry to undefined, and let
 	 _bfd_generic_link_add_one_symbol do the right thing with the
@@ -911,10 +957,11 @@ elf_merge_symbol (abfd, info, name, sym,
      the DT_NEEDED entry may not be required at the run time.  */
   if (olddef
       && ! dt_needed
-      && h->root.type == bfd_link_hash_defweak
+      && oldweakdef
       && newdef
       && newdyn
-      && bind != STB_WEAK)
+      && !newweakdef
+      && !newweakundef)
     {
       /* To make this work we have to frob the flags so that the rest
 	 of the code does not think we are using the regular
@@ -940,10 +987,10 @@ elf_merge_symbol (abfd, info, name, sym,
      as a definition.  */
   if (olddef
       && olddyn
-      && h->root.type != bfd_link_hash_defweak
+      && !oldweakdef
       && newdef
       && ! newdyn
-      && bind == STB_WEAK)
+      && (newweakdef || newweakundef))
     *override = TRUE;
 
   return TRUE;
--- binutils/ld/testsuite/ld-elfvers/vers18.dsym.weak	1999-07-09 08:21:41.000000000 -0700
+++ binutils/ld/testsuite/ld-elfvers/vers18.dsym	2003-04-03 13:48:18.000000000 -0800
@@ -1,7 +1,7 @@
-[0-9a-f]*  w   DF (\*UND\*)	[0-9a-f]*  VERS_2.0    (0x[0-9a-f][0-9a-f] )?show_foo
 [0]* g    DO \*ABS\*	[0]*  VERS_1.1    VERS_1.1
 [0]* g    DO \*ABS\*	[0]*  VERS_1.2    VERS_1.2
 [0]* g    DO \*ABS\*	[0]*  VERS_2.0    VERS_2.0
 [0-9a-f]*  w   DF (.text|\*ABS\*)	[0-9a-f]* \(Base\)       (0x[0-9a-f][0-9a-f] )?show_foo
 [0-9a-f]*  w   DF (.text|\*ABS\*)	[0-9a-f]* \(VERS_1.1\)   (0x[0-9a-f][0-9a-f] )?show_foo
 [0-9a-f]*  w   DF (.text|\*ABS\*)	[0-9a-f]* \(VERS_1.2\)   (0x[0-9a-f][0-9a-f] )?show_foo
+[0-9a-f]*  w   DF (.text|\*ABS\*)	[0-9a-f]*  VERS_2.0    (0x[0-9a-f][0-9a-f] )?show_foo
--- binutils/ld/testsuite/ld-elfvers/vers18.ver.weak	2001-05-21 10:38:02.000000000 -0700
+++ binutils/ld/testsuite/ld-elfvers/vers18.ver	2003-04-03 13:48:18.000000000 -0800
@@ -3,10 +3,5 @@ Version definitions:
 2 0x00 0x0a7927b1 VERS_1.1
 3 0x00 0x0a7927b2 VERS_1.2
 	VERS_1.1 
-4 0x02 0x0a7922b0 VERS_2.0
+4 0x00 0x0a7922b0 VERS_2.0
 	VERS_1.2 
-
-Version References:
-  required from tmpdir/vers17.so:
-    0x0a7922b0 0x00 05 VERS_2.0
-
--- binutils/ld/testsuite/ld-elfvers/vers19.ver.weak	2003-02-27 11:27:18.000000000 -0800
+++ binutils/ld/testsuite/ld-elfvers/vers19.ver	2003-04-03 13:48:18.000000000 -0800
@@ -1,3 +1,3 @@
 Version References:
-  required from vers17.so:
+  required from tmpdir/vers18.so:
     0x0a7922b0 0x00 0[23] VERS_2.0
--- binutils/ld/testsuite/ld-elfweak/dsowdata.dsym.weak	2001-09-11 11:16:56.000000000 -0700
+++ binutils/ld/testsuite/ld-elfweak/dsowdata.dsym	2003-04-03 16:46:31.000000000 -0800
@@ -1 +1 @@
-[0-9a-f]*[ 	]+w[ 	]+DO[ 	]+.data[	]+[0-9a-f]*[ 	]+(Base[ 	]+|[ 	]*)deallocate_foo
+[0-9a-f]*[ 	]+w[ 	]+DO[ 	]+.(s|)data[	]+[0-9a-f]*[ 	]+(Base[ 	]+|[ 	]*)deallocate_foo
--- binutils/ld/testsuite/ld-elfweak/elfweak.exp.weak	2002-07-30 14:02:48.000000000 -0700
+++ binutils/ld/testsuite/ld-elfweak/elfweak.exp	2003-04-03 13:48:18.000000000 -0800
@@ -443,36 +443,24 @@ if {![ld_link $ld $tmpdir/libbar1a.so "$
 
 build_lib "ELF DSO weak func first" libfoo "foo.o bar.o" dso.dsym
 build_lib "ELF DSO weak func last" libfoo "bar.o foo.o" dso.dsym
-setup_xfail "*-*-*"
 build_lib "ELF DSO weak func first DSO" libfoo "foo.o libbar.so" dsow.dsym
-setup_xfail "*-*-*"
 build_lib "ELF DSO weak func last DSO" libfoo "libbar.so foo.o" dsow.dsym
 build_exec "ELF weak func first" foo "main.o bar.o" "" strong "" strong.sym
 build_exec "ELF weak func last" foo "bar.o main.o" "" strong "" strong.sym
-setup_xfail "*-*-*"
 build_exec "ELF weak func first DSO" foo "main.o libbar.so" "-rpath ." weak weak.dsym ""
-setup_xfail "*-*-*"
 build_exec "ELF weak func last DSO" foo "libbar.so main.o" "-rpath ." weak weak.dsym ""
 
 build_lib "ELF DSO weak data first" libfoo "bar1a.o foo1a.o" dsodata.dsym
 build_lib "ELF DSO weak data last" libfoo "foo1a.o bar1a.o" dsodata.dsym
-setup_xfail "*-*-*"
 build_lib "ELF DSO weak data first DSO" libfoo "main1.o libfoo1a.so" dsowdata.dsym
-setup_xfail "*-*-*"
 build_lib "ELF DSO weak data last DSO" libfoo "libfoo1a.so main1.o" dsowdata.dsym
-setup_xfail "*-*-*"
 build_lib "ELF DSO weak data first DSO common" libfoo "main1.o libfoo1b.so" dsowdata.dsym
-setup_xfail "*-*-*"
 build_lib "ELF DSO weak data last DSO common" libfoo "libfoo1b.so main1.o" dsowdata.dsym
 build_exec "ELF weak data first" foo "main1.o bar1a.o foo1a.o" "" strongdata "" strongdata.sym
 build_exec "ELF weak data last" foo "foo1a.o main1.o bar1a.o" "" strongdata "" strongdata.sym
 build_exec "ELF weak data first common" foo "main1.o bar1a.o foo1b.o" "" strongdata "" strongcomm.sym
 build_exec "ELF weak data last common" foo "foo1b.o main1.o bar1a.o" "" strongdata "" strongcomm.sym
-setup_xfail "*-*-*"
 build_exec "ELF weak data first DSO" foo "main1.o libbar1a.so libfoo1a.so" "-rpath ." weakdata weakdata.dsym ""
-setup_xfail "*-*-*"
 build_exec "ELF weak data last DSO" foo "libfoo1a.so main1.o libbar1a.so" "-rpath ." weakdata weakdata.dsym ""
-setup_xfail "*-*-*"
 build_exec "ELF weak data first DSO common" foo "main1.o libbar1a.so libfoo1b.so" "-rpath ." weakdata weakdata.dsym ""
-setup_xfail "*-*-*"
 build_exec "ELF weak data last DSO common" foo "libfoo1b.so main1.o libbar1a.so" "-rpath ." weakdata weakdata.dsym ""
--- binutils/ld/testsuite/ld-elfweak/weakdata.dsym.weak	2001-09-14 16:51:01.000000000 -0700
+++ binutils/ld/testsuite/ld-elfweak/weakdata.dsym	2003-04-03 16:48:10.000000000 -0800
@@ -1 +1 @@
-[0-9a-f]*[ 	]+w[ 	]+DO[ 	]+.data[	]+[0-9a-f]*[ 	]+(Base[ 	]+|[ 	]*)deallocate_foo
+[0-9a-f]*[ 	]+w[ 	]+DO[ 	]+.(s|)data[	]+[0-9a-f]*[ 	]+(Base[ 	]+|[ 	]*)deallocate_foo


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