public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* PATCH: PR ld/2884: Crash in elf64_ia64_relocate_section
@ 2006-07-06 23:28 H. J. Lu
  2006-07-10 20:11 ` James E Wilson
  2006-07-11 14:05 ` Nick Clifton
  0 siblings, 2 replies; 7+ messages in thread
From: H. J. Lu @ 2006-07-06 23:28 UTC (permalink / raw)
  To: binutils

The problem is when linker sees a reference and then a versioned dynamic
definition, it calls elf_backend_copy_indirect_symbol to copy the
symbol info to the versioned dynamic definition. When linker sees a
normal definition with non-default visibility, it removes the old
dynamic definition without saving the symbol info copied over
previously. This patch copies the symbol info from the old versioned
dynamic definition to the new one with non-default visibility.


H.J.
---
2006-07-06  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/2884
	* elflink.c (_bfd_elf_merge_symbol): Set ref_dynamic to 0 for
	hidden and internal visibility.  Copy the symbol info from the
	old versioned dynamic definition to the new one with
	non-default visibility.

--- bfd/elflink.c.foo	2006-07-05 11:50:35.000000000 -0700
+++ bfd/elflink.c	2006-07-06 16:23:17.000000000 -0700
@@ -988,16 +988,20 @@ _bfd_elf_merge_symbol (bfd *abfd,
       && !bfd_is_und_section (sec))
     {
       *skip = TRUE;
-      /* Make sure this symbol is dynamic.  */
-      h->ref_dynamic = 1;
       /* A protected symbol has external availability. Make sure it is
 	 recorded as dynamic.
 
 	 FIXME: Should we check type and size for protected symbol?  */
       if (ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
-	return bfd_elf_link_record_dynamic_symbol (info, h);
+	{
+	  h->ref_dynamic = 1;
+	  return bfd_elf_link_record_dynamic_symbol (info, h);
+	}
       else
-	return TRUE;
+	{
+	  h->ref_dynamic = 0;
+	  return TRUE;
+	}
     }
   else if (!newdyn
 	   && ELF_ST_VISIBILITY (sym->st_other) != STV_DEFAULT
@@ -1007,7 +1011,25 @@ _bfd_elf_merge_symbol (bfd *abfd,
 	 relocatable file and the old definition comes from a dynamic
 	 object, we remove the old definition.  */
       if ((*sym_hash)->root.type == bfd_link_hash_indirect)
-	h = *sym_hash;
+	{
+	  /* Handle the case where the old dynamic definition is
+	     versioned.  We need to copy the symbol info from the
+	     versioned symbol to the normal one if it is referenced
+	     before.  */
+	  if (h->ref_regular)
+	    {
+	      const struct elf_backend_data *bed
+		= get_elf_backend_data (abfd);
+	      struct elf_link_hash_entry *vh = *sym_hash;
+	      vh->root.type = h->root.type;
+	      h->root.type = bfd_link_hash_indirect;
+	      (*bed->elf_backend_copy_indirect_symbol) (info, vh, h);
+	      h->root.type = vh->root.type;
+	      h = vh;
+	    }
+	  else
+	    h = *sym_hash;
+	}
 
       if ((h->root.u.undef.next || info->hash->undefs_tail == &h->root)
 	  && bfd_is_und_section (sec))
@@ -1030,9 +1052,14 @@ _bfd_elf_merge_symbol (bfd *abfd,
       if (h->def_dynamic)
 	{
 	  h->def_dynamic = 0;
-	  h->ref_dynamic = 1;
+	  /* Hidden and internal symbols aren't available outside.  */
+	  if (ELF_ST_VISIBILITY (sym->st_other) == STV_PROTECTED)
+	    h->ref_dynamic = 1;
+	  else
+	    h->ref_dynamic = 0;
 	  h->dynamic_def = 1;
 	}
+
       /* FIXME: Should we check type and size for protected symbol?  */
       h->size = 0;
       h->type = 0;

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: PATCH: PR ld/2884: Crash in elf64_ia64_relocate_section
  2006-07-06 23:28 PATCH: PR ld/2884: Crash in elf64_ia64_relocate_section H. J. Lu
@ 2006-07-10 20:11 ` James E Wilson
  2006-07-11 14:05 ` Nick Clifton
  1 sibling, 0 replies; 7+ messages in thread
From: James E Wilson @ 2006-07-10 20:11 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

On Thu, 2006-07-06 at 16:27, H. J. Lu wrote:
> 	* elflink.c (_bfd_elf_merge_symbol): Set ref_dynamic to 0 for
> 	hidden and internal visibility.  Copy the symbol info from the
> 	old versioned dynamic definition to the new one with
> 	non-default visibility.

This is an area I don't understand well, but this does look reasonable
to me.

> +	  /* Handle the case where the old dynamic definition is
> +	     versioned.  We need to copy the symbol info from the
> +	     versioned symbol to the normal one if it is referenced
> +	     before.  */

The only thing I noticed is that the second sentence here does not look
right to me.  I think that should be "if it was referenced before".
-- 
Jim Wilson, GNU Tools Support, http://www.specifix.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: PATCH: PR ld/2884: Crash in elf64_ia64_relocate_section
  2006-07-06 23:28 PATCH: PR ld/2884: Crash in elf64_ia64_relocate_section H. J. Lu
  2006-07-10 20:11 ` James E Wilson
@ 2006-07-11 14:05 ` Nick Clifton
  2006-07-11 17:41   ` H. J. Lu
  1 sibling, 1 reply; 7+ messages in thread
From: Nick Clifton @ 2006-07-11 14:05 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

Hi H. J.

> 2006-07-06  H.J. Lu  <hongjiu.lu@intel.com>
> 
> 	PR ld/2884
> 	* elflink.c (_bfd_elf_merge_symbol): Set ref_dynamic to 0 for
> 	hidden and internal visibility.  Copy the symbol info from the
> 	old versioned dynamic definition to the new one with
> 	non-default visibility.

Approved (with the grammatical correction mentioned by Jim).

Cheers
   Nick

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: PATCH: PR ld/2884: Crash in elf64_ia64_relocate_section
  2006-07-11 14:05 ` Nick Clifton
@ 2006-07-11 17:41   ` H. J. Lu
  2006-07-12  4:03     ` H. J. Lu
  0 siblings, 1 reply; 7+ messages in thread
From: H. J. Lu @ 2006-07-11 17:41 UTC (permalink / raw)
  To: Nick Clifton; +Cc: binutils

On Tue, Jul 11, 2006 at 03:05:00PM +0100, Nick Clifton wrote:
> Hi H. J.
> 
> >2006-07-06  H.J. Lu  <hongjiu.lu@intel.com>
> >
> >	PR ld/2884
> >	* elflink.c (_bfd_elf_merge_symbol): Set ref_dynamic to 0 for
> >	hidden and internal visibility.  Copy the symbol info from the
> >	old versioned dynamic definition to the new one with
> >	non-default visibility.
> 
> Approved (with the grammatical correction mentioned by Jim).
> 

That piece code is very tricky. When elf_backend_copy_indirect_symbol
was called, we copied many bits, some of which are incorrect and
unexpected for hidden and internal symbols. We need to call
elf_backend_hide_symbol to remove those extra bits.


H.J.
-----
2006-07-11  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/2884
	* elflink.c (_bfd_elf_merge_symbol): Copy the symbol info from
	the old versioned dynamic definition to the new one with
	non-default visibility.  Hide the symbol if it is hidden or
	internal.

--- bfd/elflink.c.foo	2006-07-05 11:50:35.000000000 -0700
+++ bfd/elflink.c	2006-07-11 10:32:55.000000000 -0700
@@ -1007,7 +1007,41 @@ _bfd_elf_merge_symbol (bfd *abfd,
 	 relocatable file and the old definition comes from a dynamic
 	 object, we remove the old definition.  */
       if ((*sym_hash)->root.type == bfd_link_hash_indirect)
-	h = *sym_hash;
+	{
+	  /* Handle the case where the old dynamic definition is
+	     default versioned.  We need to copy the symbol info from
+	     the symbol with default version to the normal one if it
+	     was referenced before.  */
+	  if (h->ref_regular)
+	    {
+	      const struct elf_backend_data *bed
+		= get_elf_backend_data (abfd);
+	      struct elf_link_hash_entry *vh = *sym_hash;
+	      vh->root.type = h->root.type;
+	      h->root.type = bfd_link_hash_indirect;
+	      (*bed->elf_backend_copy_indirect_symbol) (info, vh, h);
+	      /* Protected symbols will override the dynamic definition
+		 with default version.  */
+	      if (ELF_ST_VISIBILITY (sym->st_other) == STV_PROTECTED)
+		{
+		  h->root.u.i.link = (struct bfd_link_hash_entry *) vh;
+		  vh->dynamic_def = 1;
+		  vh->ref_dynamic = 1;
+		}
+	      else
+		{
+		  h->root.type = vh->root.type;
+		  vh->ref_dynamic = 0;
+		  /* We have to hide it here since it was made dynamic
+		     global with extra bits when the symbol info was
+		     copied from the old dynamic definition.  */
+		  (*bed->elf_backend_hide_symbol) (info, vh, TRUE);
+		}
+	      h = vh;
+	    }
+	  else
+	    h = *sym_hash;
+	}
 
       if ((h->root.u.undef.next || info->hash->undefs_tail == &h->root)
 	  && bfd_is_und_section (sec))

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: PATCH: PR ld/2884: Crash in elf64_ia64_relocate_section
  2006-07-11 17:41   ` H. J. Lu
@ 2006-07-12  4:03     ` H. J. Lu
  2006-07-12  9:08       ` Nick Clifton
  0 siblings, 1 reply; 7+ messages in thread
From: H. J. Lu @ 2006-07-12  4:03 UTC (permalink / raw)
  To: Nick Clifton; +Cc: binutils

On Tue, Jul 11, 2006 at 10:41:03AM -0700, H. J. Lu wrote:
> On Tue, Jul 11, 2006 at 03:05:00PM +0100, Nick Clifton wrote:
> > Hi H. J.
> > 
> > >2006-07-06  H.J. Lu  <hongjiu.lu@intel.com>
> > >
> > >	PR ld/2884
> > >	* elflink.c (_bfd_elf_merge_symbol): Set ref_dynamic to 0 for
> > >	hidden and internal visibility.  Copy the symbol info from the
> > >	old versioned dynamic definition to the new one with
> > >	non-default visibility.
> > 
> > Approved (with the grammatical correction mentioned by Jim).
> > 
> 
> That piece code is very tricky. When elf_backend_copy_indirect_symbol
> was called, we copied many bits, some of which are incorrect and
> unexpected for hidden and internal symbols. We need to call
> elf_backend_hide_symbol to remove those extra bits.
> 

I added some testcases for this patch.


H.J.
----
bfd/

2006-07-11  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/2884
	* elflink.c (_bfd_elf_merge_symbol): Copy the symbol info from
	the old versioned dynamic definition to the new one with
	non-default visibility.  Hide the symbol if it is hidden or
	internal.

ld/testsuite/

2006-07-11  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/2884
	* ld-elf/begin.c: New file.
	* ld-elf/end.c: Likewise.
	* ld-elf/endhidden.c: Likewise.
	* ld-elf/endprotected.c: Likewise.
	* ld-elf/foo.c: Likewise.
	* ld-elf/foo.map: Likewise.
	* ld-elf/hidden.out: Likewise.
	* ld-elf/main.c: Likewise.
	* ld-elf/normal.out: Likewise.
	* ld-elf/shared.exp: Likewise.

	* lib/ld-lib.exp (run_cc_link_tests): New.

--- binutils/bfd/elflink.c.hidden	2006-07-11 12:55:04.000000000 -0700
+++ binutils/bfd/elflink.c	2006-07-11 18:07:12.000000000 -0700
@@ -1025,7 +1025,41 @@ _bfd_elf_merge_symbol (bfd *abfd,
 	 relocatable file and the old definition comes from a dynamic
 	 object, we remove the old definition.  */
       if ((*sym_hash)->root.type == bfd_link_hash_indirect)
-	h = *sym_hash;
+	{
+	  /* Handle the case where the old dynamic definition is
+	     default versioned.  We need to copy the symbol info from
+	     the symbol with default version to the normal one if it
+	     was referenced before.  */
+	  if (h->ref_regular)
+	    {
+	      const struct elf_backend_data *bed
+		= get_elf_backend_data (abfd);
+	      struct elf_link_hash_entry *vh = *sym_hash;
+	      vh->root.type = h->root.type;
+	      h->root.type = bfd_link_hash_indirect;
+	      (*bed->elf_backend_copy_indirect_symbol) (info, vh, h);
+	      /* Protected symbols will override the dynamic definition
+		 with default version.  */
+	      if (ELF_ST_VISIBILITY (sym->st_other) == STV_PROTECTED)
+		{
+		  h->root.u.i.link = (struct bfd_link_hash_entry *) vh;
+		  vh->dynamic_def = 1;
+		  vh->ref_dynamic = 1;
+		}
+	      else
+		{
+		  h->root.type = vh->root.type;
+		  vh->ref_dynamic = 0;
+		  /* We have to hide it here since it was made dynamic
+		     global with extra bits when the symbol info was
+		     copied from the old dynamic definition.  */
+		  (*bed->elf_backend_hide_symbol) (info, vh, TRUE);
+		}
+	      h = vh;
+	    }
+	  else
+	    h = *sym_hash;
+	}
 
       if ((h->root.u.undef.next || info->hash->undefs_tail == &h->root)
 	  && bfd_is_und_section (sec))
--- binutils/ld/testsuite/ld-elf/begin.c.hidden	2006-07-11 18:08:12.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/begin.c	2006-07-11 16:24:31.000000000 -0700
@@ -0,0 +1,5 @@
+extern void foo (void);
+
+static void (*const init_array []) (void)
+  __attribute__ ((used, section (".init_array"), aligned (sizeof (void *))))
+  = { foo };
--- binutils/ld/testsuite/ld-elf/end.c.hidden	2006-07-11 18:08:12.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/end.c	2006-07-11 14:03:16.000000000 -0700
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+void
+foo ()
+{
+  printf ("TEST1\n");
+}
--- binutils/ld/testsuite/ld-elf/endhidden.c.hidden	2006-07-11 18:08:12.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/endhidden.c	2006-07-11 14:02:34.000000000 -0700
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+__attribute__ ((visibility ("hidden")))
+void
+foo ()
+{
+  printf ("TEST1\n");
+}
--- binutils/ld/testsuite/ld-elf/endprotected.c.hidden	2006-07-11 18:08:12.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/endprotected.c	2006-07-11 14:03:05.000000000 -0700
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+__attribute__ ((visibility ("protected")))
+void
+foo ()
+{
+  printf ("TEST1\n");
+}
--- binutils/ld/testsuite/ld-elf/foo.c.hidden	2006-07-11 18:08:12.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/foo.c	2006-07-11 16:24:23.000000000 -0700
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+void
+foo (void)
+{
+  printf ("TEST2\n");
+}
+
+static void (*const init_array []) (void)
+  __attribute__ ((used, section (".init_array"), aligned (sizeof (void *))))
+  = { foo };
--- binutils/ld/testsuite/ld-elf/foo.map.hidden	2006-07-11 18:08:12.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/foo.map	2006-07-11 14:09:31.000000000 -0700
@@ -0,0 +1,4 @@
+FOO {
+  global: foo;
+  local: *;
+};
--- binutils/ld/testsuite/ld-elf/hidden.out.hidden	2006-07-11 18:08:12.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/hidden.out	2006-07-11 17:44:13.000000000 -0700
@@ -0,0 +1,3 @@
+TEST2
+TEST1
+MAIN
--- binutils/ld/testsuite/ld-elf/main.c.hidden	2006-07-11 18:08:12.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/main.c	2006-07-11 13:39:51.000000000 -0700
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int
+main (void)
+{
+  printf ("MAIN\n");
+  return 0;
+}
--- binutils/ld/testsuite/ld-elf/normal.out.hidden	2006-07-11 18:08:12.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/normal.out	2006-07-11 17:43:47.000000000 -0700
@@ -0,0 +1,3 @@
+TEST1
+TEST1
+MAIN
--- binutils/ld/testsuite/ld-elf/shared.exp.hidden	2006-07-11 13:25:35.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/shared.exp	2006-07-11 18:04:58.000000000 -0700
@@ -0,0 +1,115 @@
+# Expect script for various ELF tests.
+#   Copyright 2006 Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+# Exclude non-ELF targets.
+
+if ![is_elf_format] {
+    return
+}
+
+# The following tests require running the executable generated by ld.
+if ![isnative] {
+    return
+}
+
+# Check if compiler works
+if { [which $CC] == 0 } {
+    return
+}
+
+if { ![ld_compile $CC "$srcdir/$subdir/begin.c" tmpdir/begin.o]
+     || ![ld_compile $CC "$srcdir/$subdir/endhidden.c" tmpdir/end.o] } {
+    return
+}
+set build_tests {
+  {"Build libfoo.so"
+   "-shared" "-fPIC"
+   {foo.c} {} "libfoo.so"}
+  {"Build versioned libfoo.so"
+   "-shared -Wl,--version-script=foo.map" "-fPIC"
+   {foo.c} {} "libfoov.so" "-fPIC"}
+  {"Build libbar.so"
+   "-shared" "-fPIC"
+   {begin.c end.c} {} "libbar.so"}
+  {"Build hidden libbar.so"
+   "-shared" "-fPIC"
+   {begin.c endhidden.c} {} "libbarh.so"}
+  {"Build protected libbar.so"
+   "-shared" "-fPIC"
+   {begin.c endprotected.c} {} "libbarp.so"}
+  {"Build libbar.so with libfoo.so"
+   "-shared tmpdir/begin.o tmpdir/libfoo.so" "-fPIC"
+   {end.c} {} "libbarfoo.so"}
+  {"Build libar.so with versioned libfoo.so"
+   "-shared tmpdir/begin.o tmpdir/libfoov.so" "-fPIC"
+   {end.c} {} "libbarfoov.so"}
+  {"Build hidden libbar.so with libfoo.so"
+   "-shared tmpdir/begin.o tmpdir/libfoo.so" "-fPIC"
+   {endhidden.c} {} "libbarhfoo.so"}
+  {"Build hidden libar.so with versioned libfoo.so"
+   "-shared tmpdir/begin.o tmpdir/libfoov.so" "-fPIC"
+   {endhidden.c} {} "libbarhfoov.so"}
+  {"Build protected libbar.so with libfoo.so"
+   "-shared tmpdir/begin.o tmpdir/libfoo.so" "-fPIC"
+   {endprotected.c} {} "libbarpfoo.so"}
+  {"Build protected libbar.so with versioned libfoo.so"
+   "-shared tmpdir/begin.o tmpdir/libfoov.so" "-fPIC"
+   {endprotected.c} {} "libbarpfoov.so"}
+}
+
+set run_tests {
+    {"Run normal with libfoo.so"
+     "tmpdir/begin.o tmpdir/libfoo.so tmpdir/end.o" ""
+     {main.c} "normal" "normal.out"}
+    {"Run protected with libfoo.so"
+     "tmpdir/begin.o tmpdir/libfoo.so tmpdir/endprotected.o" ""
+     {main.c} "protected" "normal.out"}
+    {"Run hidden with libfoo.so"
+     "tmpdir/begin.o tmpdir/libfoo.so tmpdir/endhidden.o" ""
+     {main.c} "hidden" "hidden.out"}
+    {"Run normal with versioned libfoo.so"
+     "tmpdir/begin.o tmpdir/libfoov.so tmpdir/end.o" ""
+     {main.c} "normalv" "normal.out"}
+    {"Run protected with versioned libfoo.so"
+     "tmpdir/begin.o tmpdir/libfoov.so tmpdir/endprotected.o" ""
+     {main.c} "protected" "normal.out"}
+    {"Run hidden with versioned libfoo.so"
+     "tmpdir/begin.o tmpdir/libfoov.so tmpdir/endhidden.o" ""
+     {main.c} "hiddenv" "hidden.out"}
+    {"Run normal libbar.so with libfoo.so"
+     "tmpdir/libbarfoo.so tmpdir/libfoo.so" ""
+     {main.c} "normal" "normal.out"}
+    {"Run protected libbar.so with libfoo.so"
+     "tmpdir/libbarpfoo.so tmpdir/libfoo.so" ""
+     {main.c} "protected" "normal.out"}
+    {"Run hidden libbar.so with libfoo.so"
+     "tmpdir/libbarhfoo.so tmpdir/libfoo.so" ""
+     {main.c} "hidden" "hidden.out"}
+    {"Run normal libbar.so with versioned libfoo.so"
+     "tmpdir/libbarfoov.so tmpdir/libfoov.so" ""
+     {main.c} "normal" "normal.out"}
+    {"Run protected libbar.so with versioned libfoo.so"
+     "tmpdir/libbarpfoov.so tmpdir/libfoov.so" ""
+     {main.c} "protected" "normal.out"}
+    {"Run hidden libbar.so with versioned libfoo.so"
+     "tmpdir/libbarhfoov.so tmpdir/libfoov.so" ""
+     {main.c} "hidden" "hidden.out"}
+}
+
+run_cc_link_tests $build_tests
+run_ld_link_exec_tests [] $run_tests
--- binutils/ld/testsuite/lib/ld-lib.exp.hidden	2006-04-05 11:10:55.000000000 -0700
+++ binutils/ld/testsuite/lib/ld-lib.exp	2006-07-11 14:42:12.000000000 -0700
@@ -1341,3 +1341,126 @@ proc run_ld_link_exec_tests { targets_to
 	}
     }
 }
+
+# List contains test-items with 3 items followed by 2 lists, one item and
+# one optional item:
+# 0:name 1:link options 2:compile options
+# 3:filenames of assembler files 4: action and options. 5: name of output file
+#
+# Actions:
+# objdump: Apply objdump options on result.  Compare with regex (last arg).
+# nm: Apply nm options on result.  Compare with regex (last arg).
+# readelf: Apply readelf options on result.  Compare with regex (last arg).
+#
+proc run_cc_link_tests { ldtests } {
+    global nm
+    global objdump
+    global READELF
+    global srcdir
+    global subdir
+    global env
+    global CC
+    global CFLAGS
+
+    foreach testitem $ldtests {
+	set testname [lindex $testitem 0]
+	set ldflags [lindex $testitem 1]
+	set cflags [lindex $testitem 2]
+	set src_files  [lindex $testitem 3]
+	set actions [lindex $testitem 4]
+	set binfile tmpdir/[lindex $testitem 5]
+	set objfiles {}
+	set is_unresolved 0
+	set failed 0
+
+	# Compile each file in the test.
+	foreach src_file $src_files {
+	    set objfile "tmpdir/[file rootname $src_file].o"
+	    lappend objfiles $objfile
+
+	    if ![ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile] {
+		set is_unresolved 1
+		break
+	    }
+	}
+
+	# Catch errors.
+	if { $is_unresolved != 0 } {
+	    unresolved $testname
+	    continue
+	}
+
+	if ![ld_simple_link $CC $binfile "-L$srcdir/$subdir $ldflags $objfiles"] {
+	    fail $testname
+	} else {
+	    set failed 0
+	    foreach actionlist $actions {
+		set action [lindex $actionlist 0]
+		set progopts [lindex $actionlist 1]
+
+		# There are actions where we run regexp_diff on the
+		# output, and there are other actions (presumably).
+		# Handling of the former look the same.
+		set dump_prog ""
+		switch -- $action {
+		    objdump
+		        { set dump_prog $objdump }
+		    nm
+		        { set dump_prog $nm }
+		    readelf
+		        { set dump_prog $READELF }
+		    default
+			{
+			    perror "Unrecognized action $action"
+			    set is_unresolved 1
+			    break
+			}
+		    }
+
+		if { $dump_prog != "" } {
+		    set dumpfile [lindex $actionlist 2]
+		    set binary $dump_prog
+
+		    # Ensure consistent sorting of symbols
+		    if {[info exists env(LC_ALL)]} {
+			set old_lc_all $env(LC_ALL)
+		    }
+		    set env(LC_ALL) "C"
+		    set cmd "$binary $progopts $binfile > dump.out"
+		    send_log "$cmd\n"
+		    catch "exec $cmd" comp_output
+		    if {[info exists old_lc_all]} {
+			set env(LC_ALL) $old_lc_all
+		    } else {
+			unset env(LC_ALL)
+		    }
+		    set comp_output [prune_warnings $comp_output]
+
+		    if ![string match "" $comp_output] then {
+			send_log "$comp_output\n"
+			set failed 1
+			break
+		    }
+
+		    if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
+			verbose "output is [file_contents "dump.out"]" 2
+			set failed 1
+			break
+		    }
+		}
+	    }
+
+	    if { $failed != 0 } {
+		fail $testname
+	    } else { if { $is_unresolved == 0 } {
+		pass $testname
+	    } }
+	}
+
+	# Catch action errors.
+	if { $is_unresolved != 0 } {
+	    unresolved $testname
+	    continue
+	}
+    }
+}

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: PATCH: PR ld/2884: Crash in elf64_ia64_relocate_section
  2006-07-12  4:03     ` H. J. Lu
@ 2006-07-12  9:08       ` Nick Clifton
  2006-07-12 17:19         ` H. J. Lu
  0 siblings, 1 reply; 7+ messages in thread
From: Nick Clifton @ 2006-07-12  9:08 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

Hi H.J.

> bfd/
> 2006-07-11  H.J. Lu  <hongjiu.lu@intel.com>
> 
> 	PR ld/2884
> 	* elflink.c (_bfd_elf_merge_symbol): Copy the symbol info from
> 	the old versioned dynamic definition to the new one with
> 	non-default visibility.  Hide the symbol if it is hidden or
> 	internal.
> 
> ld/testsuite/
> 2006-07-11  H.J. Lu  <hongjiu.lu@intel.com>
> 
> 	PR ld/2884
> 	* ld-elf/begin.c: New file.
> 	* ld-elf/end.c: Likewise.
> 	* ld-elf/endhidden.c: Likewise.
> 	* ld-elf/endprotected.c: Likewise.
> 	* ld-elf/foo.c: Likewise.
> 	* ld-elf/foo.map: Likewise.
> 	* ld-elf/hidden.out: Likewise.
> 	* ld-elf/main.c: Likewise.
> 	* ld-elf/normal.out: Likewise.
> 	* ld-elf/shared.exp: Likewise.
> 
> 	* lib/ld-lib.exp (run_cc_link_tests): New.

Approved - please apply.

Cheers
   Nick

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: PATCH: PR ld/2884: Crash in elf64_ia64_relocate_section
  2006-07-12  9:08       ` Nick Clifton
@ 2006-07-12 17:19         ` H. J. Lu
  0 siblings, 0 replies; 7+ messages in thread
From: H. J. Lu @ 2006-07-12 17:19 UTC (permalink / raw)
  To: Nick Clifton; +Cc: binutils

On Wed, Jul 12, 2006 at 10:07:51AM +0100, Nick Clifton wrote:
> Hi H.J.
> 
> >bfd/
> >2006-07-11  H.J. Lu  <hongjiu.lu@intel.com>
> >
> >	PR ld/2884
> >	* elflink.c (_bfd_elf_merge_symbol): Copy the symbol info from
> >	the old versioned dynamic definition to the new one with
> >	non-default visibility.  Hide the symbol if it is hidden or
> >	internal.
> >
> >ld/testsuite/
> >2006-07-11  H.J. Lu  <hongjiu.lu@intel.com>
> >
> >	PR ld/2884
> >	* ld-elf/begin.c: New file.
> >	* ld-elf/end.c: Likewise.
> >	* ld-elf/endhidden.c: Likewise.
> >	* ld-elf/endprotected.c: Likewise.
> >	* ld-elf/foo.c: Likewise.
> >	* ld-elf/foo.map: Likewise.
> >	* ld-elf/hidden.out: Likewise.
> >	* ld-elf/main.c: Likewise.
> >	* ld-elf/normal.out: Likewise.
> >	* ld-elf/shared.exp: Likewise.
> >
> >	* lib/ld-lib.exp (run_cc_link_tests): New.
> 
> Approved - please apply.
> 

This is the patch I checked in. It now ignores the error from
ld_compile since older gcc may generate wrong section attributes
which will lead to assembler warnings.


H.J.
---
bfd/

2006-07-11  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/2884
	* elflink.c (_bfd_elf_merge_symbol): Copy the symbol info from
	the old versioned dynamic definition to the new one with
	non-default visibility.  Hide the symbol if it is hidden or
	internal.

ld/testsuite/

2006-07-11  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/2884
	* ld-elf/begin.c: New file.
	* ld-elf/end.c: Likewise.
	* ld-elf/endhidden.c: Likewise.
	* ld-elf/endprotected.c: Likewise.
	* ld-elf/foo.c: Likewise.
	* ld-elf/foo.map: Likewise.
	* ld-elf/hidden.out: Likewise.
	* ld-elf/main.c: Likewise.
	* ld-elf/normal.out: Likewise.
	* ld-elf/shared.exp: Likewise.

	* lib/ld-lib.exp (run_cc_link_tests): New.

--- binutils/bfd/elflink.c.hidden	2006-07-11 20:49:23.000000000 -0700
+++ binutils/bfd/elflink.c	2006-07-11 20:49:23.000000000 -0700
@@ -1025,7 +1025,41 @@ _bfd_elf_merge_symbol (bfd *abfd,
 	 relocatable file and the old definition comes from a dynamic
 	 object, we remove the old definition.  */
       if ((*sym_hash)->root.type == bfd_link_hash_indirect)
-	h = *sym_hash;
+	{
+	  /* Handle the case where the old dynamic definition is
+	     default versioned.  We need to copy the symbol info from
+	     the symbol with default version to the normal one if it
+	     was referenced before.  */
+	  if (h->ref_regular)
+	    {
+	      const struct elf_backend_data *bed
+		= get_elf_backend_data (abfd);
+	      struct elf_link_hash_entry *vh = *sym_hash;
+	      vh->root.type = h->root.type;
+	      h->root.type = bfd_link_hash_indirect;
+	      (*bed->elf_backend_copy_indirect_symbol) (info, vh, h);
+	      /* Protected symbols will override the dynamic definition
+		 with default version.  */
+	      if (ELF_ST_VISIBILITY (sym->st_other) == STV_PROTECTED)
+		{
+		  h->root.u.i.link = (struct bfd_link_hash_entry *) vh;
+		  vh->dynamic_def = 1;
+		  vh->ref_dynamic = 1;
+		}
+	      else
+		{
+		  h->root.type = vh->root.type;
+		  vh->ref_dynamic = 0;
+		  /* We have to hide it here since it was made dynamic
+		     global with extra bits when the symbol info was
+		     copied from the old dynamic definition.  */
+		  (*bed->elf_backend_hide_symbol) (info, vh, TRUE);
+		}
+	      h = vh;
+	    }
+	  else
+	    h = *sym_hash;
+	}
 
       if ((h->root.u.undef.next || info->hash->undefs_tail == &h->root)
 	  && bfd_is_und_section (sec))
--- binutils/ld/testsuite/ld-elf/begin.c.hidden	2006-07-11 20:49:23.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/begin.c	2006-07-11 20:49:23.000000000 -0700
@@ -0,0 +1,5 @@
+extern void foo (void);
+
+static void (*const init_array []) (void)
+  __attribute__ ((used, section (".init_array"), aligned (sizeof (void *))))
+  = { foo };
--- binutils/ld/testsuite/ld-elf/end.c.hidden	2006-07-11 20:49:23.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/end.c	2006-07-11 20:49:23.000000000 -0700
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+void
+foo ()
+{
+  printf ("TEST1\n");
+}
--- binutils/ld/testsuite/ld-elf/endhidden.c.hidden	2006-07-11 20:49:23.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/endhidden.c	2006-07-11 20:49:23.000000000 -0700
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+__attribute__ ((visibility ("hidden")))
+void
+foo ()
+{
+  printf ("TEST1\n");
+}
--- binutils/ld/testsuite/ld-elf/endprotected.c.hidden	2006-07-11 20:49:23.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/endprotected.c	2006-07-11 20:49:23.000000000 -0700
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+__attribute__ ((visibility ("protected")))
+void
+foo ()
+{
+  printf ("TEST1\n");
+}
--- binutils/ld/testsuite/ld-elf/foo.c.hidden	2006-07-11 20:49:23.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/foo.c	2006-07-11 20:49:23.000000000 -0700
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+void
+foo (void)
+{
+  printf ("TEST2\n");
+}
+
+static void (*const init_array []) (void)
+  __attribute__ ((used, section (".init_array"), aligned (sizeof (void *))))
+  = { foo };
--- binutils/ld/testsuite/ld-elf/foo.map.hidden	2006-07-11 20:49:23.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/foo.map	2006-07-11 20:49:23.000000000 -0700
@@ -0,0 +1,4 @@
+FOO {
+  global: foo;
+  local: *;
+};
--- binutils/ld/testsuite/ld-elf/hidden.out.hidden	2006-07-11 20:49:23.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/hidden.out	2006-07-11 20:49:23.000000000 -0700
@@ -0,0 +1,3 @@
+TEST2
+TEST1
+MAIN
--- binutils/ld/testsuite/ld-elf/main.c.hidden	2006-07-11 20:49:23.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/main.c	2006-07-11 20:49:23.000000000 -0700
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int
+main (void)
+{
+  printf ("MAIN\n");
+  return 0;
+}
--- binutils/ld/testsuite/ld-elf/normal.out.hidden	2006-07-11 20:49:23.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/normal.out	2006-07-11 20:49:23.000000000 -0700
@@ -0,0 +1,3 @@
+TEST1
+TEST1
+MAIN
--- binutils/ld/testsuite/ld-elf/shared.exp.hidden	2006-07-11 20:49:23.000000000 -0700
+++ binutils/ld/testsuite/ld-elf/shared.exp	2006-07-12 08:33:07.000000000 -0700
@@ -0,0 +1,112 @@
+# Expect script for various ELF tests.
+#   Copyright 2006 Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+# Exclude non-ELF targets.
+
+if ![is_elf_format] {
+    return
+}
+
+# The following tests require running the executable generated by ld.
+if ![isnative] {
+    return
+}
+
+# Check if compiler works
+if { [which $CC] == 0 } {
+    return
+}
+
+set build_tests {
+  {"Build libfoo.so"
+   "-shared" "-fPIC"
+   {foo.c} {} "libfoo.so"}
+  {"Build versioned libfoo.so"
+   "-shared -Wl,--version-script=foo.map" "-fPIC"
+   {foo.c} {} "libfoov.so" "-fPIC"}
+  {"Build libbar.so"
+   "-shared" "-fPIC"
+   {begin.c end.c} {} "libbar.so"}
+  {"Build hidden libbar.so"
+   "-shared" "-fPIC"
+   {begin.c endhidden.c} {} "libbarh.so"}
+  {"Build protected libbar.so"
+   "-shared" "-fPIC"
+   {begin.c endprotected.c} {} "libbarp.so"}
+  {"Build libbar.so with libfoo.so"
+   "-shared tmpdir/begin.o tmpdir/libfoo.so" "-fPIC"
+   {end.c} {} "libbarfoo.so"}
+  {"Build libar.so with versioned libfoo.so"
+   "-shared tmpdir/begin.o tmpdir/libfoov.so" "-fPIC"
+   {end.c} {} "libbarfoov.so"}
+  {"Build hidden libbar.so with libfoo.so"
+   "-shared tmpdir/begin.o tmpdir/libfoo.so" "-fPIC"
+   {endhidden.c} {} "libbarhfoo.so"}
+  {"Build hidden libar.so with versioned libfoo.so"
+   "-shared tmpdir/begin.o tmpdir/libfoov.so" "-fPIC"
+   {endhidden.c} {} "libbarhfoov.so"}
+  {"Build protected libbar.so with libfoo.so"
+   "-shared tmpdir/begin.o tmpdir/libfoo.so" "-fPIC"
+   {endprotected.c} {} "libbarpfoo.so"}
+  {"Build protected libbar.so with versioned libfoo.so"
+   "-shared tmpdir/begin.o tmpdir/libfoov.so" "-fPIC"
+   {endprotected.c} {} "libbarpfoov.so"}
+}
+
+set run_tests {
+    {"Run normal with libfoo.so"
+     "tmpdir/begin.o tmpdir/libfoo.so tmpdir/end.o" ""
+     {main.c} "normal" "normal.out"}
+    {"Run protected with libfoo.so"
+     "tmpdir/begin.o tmpdir/libfoo.so tmpdir/endprotected.o" ""
+     {main.c} "protected" "normal.out"}
+    {"Run hidden with libfoo.so"
+     "tmpdir/begin.o tmpdir/libfoo.so tmpdir/endhidden.o" ""
+     {main.c} "hidden" "hidden.out"}
+    {"Run normal with versioned libfoo.so"
+     "tmpdir/begin.o tmpdir/libfoov.so tmpdir/end.o" ""
+     {main.c} "normalv" "normal.out"}
+    {"Run protected with versioned libfoo.so"
+     "tmpdir/begin.o tmpdir/libfoov.so tmpdir/endprotected.o" ""
+     {main.c} "protected" "normal.out"}
+    {"Run hidden with versioned libfoo.so"
+     "tmpdir/begin.o tmpdir/libfoov.so tmpdir/endhidden.o" ""
+     {main.c} "hiddenv" "hidden.out"}
+    {"Run normal libbar.so with libfoo.so"
+     "tmpdir/libbarfoo.so tmpdir/libfoo.so" ""
+     {main.c} "normal" "normal.out"}
+    {"Run protected libbar.so with libfoo.so"
+     "tmpdir/libbarpfoo.so tmpdir/libfoo.so" ""
+     {main.c} "protected" "normal.out"}
+    {"Run hidden libbar.so with libfoo.so"
+     "tmpdir/libbarhfoo.so tmpdir/libfoo.so" ""
+     {main.c} "hidden" "hidden.out"}
+    {"Run normal libbar.so with versioned libfoo.so"
+     "tmpdir/libbarfoov.so tmpdir/libfoov.so" ""
+     {main.c} "normal" "normal.out"}
+    {"Run protected libbar.so with versioned libfoo.so"
+     "tmpdir/libbarpfoov.so tmpdir/libfoov.so" ""
+     {main.c} "protected" "normal.out"}
+    {"Run hidden libbar.so with versioned libfoo.so"
+     "tmpdir/libbarhfoov.so tmpdir/libfoov.so" ""
+     {main.c} "hidden" "hidden.out"}
+}
+
+run_cc_link_tests $build_tests
+# NetBSD ELF systems do not currently support the .*_array sections.
+run_ld_link_exec_tests [list "*-*-netbsdelf*"] $run_tests
--- binutils/ld/testsuite/lib/ld-lib.exp.hidden	2006-04-05 11:10:55.000000000 -0700
+++ binutils/ld/testsuite/lib/ld-lib.exp	2006-07-12 08:39:23.000000000 -0700
@@ -1341,3 +1341,123 @@ proc run_ld_link_exec_tests { targets_to
 	}
     }
 }
+
+# List contains test-items with 3 items followed by 2 lists, one item and
+# one optional item:
+# 0:name 1:link options 2:compile options
+# 3:filenames of assembler files 4: action and options. 5: name of output file
+#
+# Actions:
+# objdump: Apply objdump options on result.  Compare with regex (last arg).
+# nm: Apply nm options on result.  Compare with regex (last arg).
+# readelf: Apply readelf options on result.  Compare with regex (last arg).
+#
+proc run_cc_link_tests { ldtests } {
+    global nm
+    global objdump
+    global READELF
+    global srcdir
+    global subdir
+    global env
+    global CC
+    global CFLAGS
+
+    foreach testitem $ldtests {
+	set testname [lindex $testitem 0]
+	set ldflags [lindex $testitem 1]
+	set cflags [lindex $testitem 2]
+	set src_files  [lindex $testitem 3]
+	set actions [lindex $testitem 4]
+	set binfile tmpdir/[lindex $testitem 5]
+	set objfiles {}
+	set is_unresolved 0
+	set failed 0
+
+	# Compile each file in the test.
+	foreach src_file $src_files {
+	    set objfile "tmpdir/[file rootname $src_file].o"
+	    lappend objfiles $objfile
+
+	    # We ignore warnings since some compilers may generate
+	    # incorrect section attributes and the assembler will warn
+	    # them.
+	    ld_compile "$CC -c $CFLAGS $cflags" $srcdir/$subdir/$src_file $objfile
+	}
+
+	# Clear error and warning counts.
+	reset_vars
+
+	if ![ld_simple_link $CC $binfile "-L$srcdir/$subdir $ldflags $objfiles"] {
+	    fail $testname
+	} else {
+	    set failed 0
+	    foreach actionlist $actions {
+		set action [lindex $actionlist 0]
+		set progopts [lindex $actionlist 1]
+
+		# There are actions where we run regexp_diff on the
+		# output, and there are other actions (presumably).
+		# Handling of the former look the same.
+		set dump_prog ""
+		switch -- $action {
+		    objdump
+		        { set dump_prog $objdump }
+		    nm
+		        { set dump_prog $nm }
+		    readelf
+		        { set dump_prog $READELF }
+		    default
+			{
+			    perror "Unrecognized action $action"
+			    set is_unresolved 1
+			    break
+			}
+		    }
+
+		if { $dump_prog != "" } {
+		    set dumpfile [lindex $actionlist 2]
+		    set binary $dump_prog
+
+		    # Ensure consistent sorting of symbols
+		    if {[info exists env(LC_ALL)]} {
+			set old_lc_all $env(LC_ALL)
+		    }
+		    set env(LC_ALL) "C"
+		    set cmd "$binary $progopts $binfile > dump.out"
+		    send_log "$cmd\n"
+		    catch "exec $cmd" comp_output
+		    if {[info exists old_lc_all]} {
+			set env(LC_ALL) $old_lc_all
+		    } else {
+			unset env(LC_ALL)
+		    }
+		    set comp_output [prune_warnings $comp_output]
+
+		    if ![string match "" $comp_output] then {
+			send_log "$comp_output\n"
+			set failed 1
+			break
+		    }
+
+		    if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
+			verbose "output is [file_contents "dump.out"]" 2
+			set failed 1
+			break
+		    }
+		}
+	    }
+
+	    if { $failed != 0 } {
+		fail $testname
+	    } else { if { $is_unresolved == 0 } {
+		pass $testname
+	    } }
+	}
+
+	# Catch action errors.
+	if { $is_unresolved != 0 } {
+	    unresolved $testname
+	    continue
+	}
+    }
+}

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2006-07-12 17:19 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-07-06 23:28 PATCH: PR ld/2884: Crash in elf64_ia64_relocate_section H. J. Lu
2006-07-10 20:11 ` James E Wilson
2006-07-11 14:05 ` Nick Clifton
2006-07-11 17:41   ` H. J. Lu
2006-07-12  4:03     ` H. J. Lu
2006-07-12  9:08       ` Nick Clifton
2006-07-12 17:19         ` H. J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).