* 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).