PATCH: Fix ELF visibility handling

H. J. Lu hjl@lucon.org
Tue May 20 01:27:00 GMT 2003


On Mon, May 19, 2003 at 05:38:02PM -0700, H. J. Lu wrote:
> On Tue, May 20, 2003 at 12:19:19AM +0200, Jakub Jelinek wrote:
> > On Wed, Apr 09, 2003 at 09:22:52AM -0700, H. J. Lu wrote:
> > > 2003-04-01  H.J. Lu <hjl@gnu.org>
> > > 
> > > 	(elf_link_output_extsym): Warn if a forced local symbol is
> > > 	referenced from dynamic objects. Make non-weak undefined symbol
> > > 	with non-default visibility a fatal error.
> > 
> > This change broke static linking with hidden common symbols
> > (testcase included in the patch below).
> 
> I don't think it works with dynamic linking either. I found another
> bug. I will post a testcase and a patch later.
> 
> > Any reason why you use h->root.type != bfd_link_hash_undefweak
> > which can well be a normal bfd_link_hash_defined symbol?
> 
> I have an old patch to fix a related problem:
> 
> http://sources.redhat.com/ml/binutils/2003-03/msg00080.html
> 
> in a different way. Then I changed it and forgot to update another
> patch. That is what happened when you had so many patches on top
> of each other.
> 

Here is the new patch.


H.J.
-------------- next part --------------
bfd/

2003-05-20  Jakub Jelinek  <jakub@redhat.com>

	* elflink.h (elf_link_output_extsym): Only issue error about !=
	STV_DEFAULT symbols if they are bfd_link_hash_undefined.

2003-05-20  H.J. Lu <hongjiu.lu@intel.com>

	* elflink.c (_bfd_elf_merge_symbol): Check ELF_LINK_DYNAMIC_DEF
	when removing the old definition for symbols with non-default
	visibility.

ld/testsuite/

2003-05-20  Jakub Jelinek  <jakub@redhat.com>

	* ld-elfvsb/common.c: New file.
	* ld-elfvsb/elfvsb.exp: Add common.

2003-05-20  H.J. Lu <hongjiu.lu@intel.com>

	* ld-elfvsb/sh3.c: New file.
	* ld-elfvsb/test.c: Likewise.

	* ld-elfvsb/elfvsb.exp: Add new weak hidden symbol tests.

--- binutils/bfd/elflink.c.vsb	2003-05-18 21:48:09.000000000 -0700
+++ binutils/bfd/elflink.c	2003-05-19 18:17:55.000000000 -0700
@@ -884,7 +884,8 @@ _bfd_elf_merge_symbol (abfd, info, name,
       if (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC)
 	{
 	  h->elf_link_hash_flags &= ~ELF_LINK_HASH_DEF_DYNAMIC;
-	  h->elf_link_hash_flags |= ELF_LINK_HASH_REF_DYNAMIC;
+	  h->elf_link_hash_flags |= (ELF_LINK_HASH_REF_DYNAMIC
+				     | ELF_LINK_DYNAMIC_DEF);
 	}
       /* FIXME: Should we check type and size for protected symbol?  */
       h->size = 0;
--- binutils/bfd/elflink.h.vsb	2003-05-18 21:48:10.000000000 -0700
+++ binutils/bfd/elflink.h	2003-05-19 17:42:25.000000000 -0700
@@ -4622,7 +4622,7 @@ elf_link_output_extsym (h, data)
   if (! finfo->info->relocateable
       && ELF_ST_VISIBILITY (sym.st_other) != STV_DEFAULT
       && ELF_ST_BIND (sym.st_info) != STB_WEAK
-      && h->root.type != bfd_link_hash_undefweak
+      && h->root.type == bfd_link_hash_undefined
       && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
     {
       (*_bfd_error_handler)
--- binutils/ld/testsuite/ld-elfvsb/common.c.vsb	2003-05-19 17:42:25.000000000 -0700
+++ binutils/ld/testsuite/ld-elfvsb/common.c	2003-05-19 17:51:43.000000000 -0700
@@ -0,0 +1,14 @@
+int foo;
+asm (".hidden foo");
+
+int
+_start (void)
+{
+  return foo;
+}
+
+int
+__start (void)
+{
+  return _start ();
+}
--- binutils/ld/testsuite/ld-elfvsb/elfvsb.exp.vsb	2003-05-18 21:48:13.000000000 -0700
+++ binutils/ld/testsuite/ld-elfvsb/elfvsb.exp	2003-05-19 18:19:04.000000000 -0700
@@ -412,6 +412,39 @@ visibility_run protected_undef_def
 visibility_run protected_weak
 visibility_run normal
 
+if { ![ld_compile "$CC -g $CFLAGS" $srcdir/$subdir/common.c tmpdir/common.o] } {
+    unresolved "common hidden symbol"
+} else {
+    if ![ld_simple_link $ld tmpdir/common "tmpdir/common.o"] {
+	fail "common hidden symbol"
+    } else {
+	pass "common hidden symbol"
+    }
+}
+
+if { ![ld_compile "$CC -g $CFLAGS" $srcdir/$subdir/test.c tmpdir/test.o] } {
+    unresolved "weak hidden symbol"
+} else {
+   if { ![ld_compile "$CC -g $CFLAGS $picflag" $srcdir/$subdir/sh3.c tmpdir/sh3.o] } {
+	unresolved "weak hidden symbol"
+    } else {
+	if ![ld_simple_link $ld tmpdir/sh3.so "-shared tmpdir/sh3.o"] {
+	    fail "weak hidden symbol"
+	} else {
+	    if ![ld_simple_link $ld tmpdir/weak "tmpdir/test.o tmpdir/sh3.o"] {
+		fail "weak hidden symbol DSO last"
+	    } else {
+		pass "weak hidden symbol DSO last"
+	    }
+	    if ![ld_simple_link $ld tmpdir/weak "tmpdir/sh3.so tmpdir/test.o"] {
+		fail "weak hidden symbol DSO first"
+	    } else {
+		pass "weak hidden symbol DSO first"
+	    }
+	}
+    }
+}
+
 if { [istarget rs6000*-*-aix*] || [istarget powerpc*-*-aix*] } {
     # Remove the temporary directory.
     catch "exec rm -rf $tmpdir" exec_status
--- binutils/ld/testsuite/ld-elfvsb/sh3.c.vsb	2003-05-19 18:17:08.000000000 -0700
+++ binutils/ld/testsuite/ld-elfvsb/sh3.c	2003-05-19 17:58:53.000000000 -0700
@@ -0,0 +1,7 @@
+int main_hidden_data = 1;
+
+int
+main_hidden_func ()
+{
+  return 1;
+}
--- binutils/ld/testsuite/ld-elfvsb/test.c.vsb	2003-05-19 18:17:26.000000000 -0700
+++ binutils/ld/testsuite/ld-elfvsb/test.c	2003-05-19 18:00:38.000000000 -0700
@@ -0,0 +1,26 @@
+#pragma weak main_hidden_data
+extern int main_hidden_data;
+asm (".hidden main_hidden_data");
+ 
+#pragma weak main_hidden_func
+extern int main_hidden_func ();
+asm (".hidden main_hidden_func");
+
+int
+_start (void)
+{
+  int ret = 0;
+
+  if (&main_hidden_data != 0)
+    ret = 1;
+  if (main_hidden_func != 0)
+    ret = 1;
+
+  return ret;
+}
+
+int
+__start (void)
+{
+  return _start ();
+}


More information about the Binutils mailing list