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]

Re: PATCH: PR ld/2884: Crash in elf64_ia64_relocate_section


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
+	}
+    }
+}


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