From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10533 invoked by alias); 12 Jul 2006 17:19:04 -0000 Received: (qmail 10517 invoked by uid 22791); 12 Jul 2006 17:19:02 -0000 X-Spam-Check-By: sourceware.org Received: from smtp108.sbc.mail.mud.yahoo.com (HELO smtp108.sbc.mail.mud.yahoo.com) (68.142.198.207) by sourceware.org (qpsmtpd/0.31) with SMTP; Wed, 12 Jul 2006 17:18:54 +0000 Received: (qmail 64266 invoked from network); 12 Jul 2006 17:18:52 -0000 Received: from unknown (HELO lucon.org) (hjjean@sbcglobal.net@71.146.109.150 with login) by smtp108.sbc.mail.mud.yahoo.com with SMTP; 12 Jul 2006 17:18:51 -0000 Received: by lucon.org (Postfix, from userid 1000) id 3BCA864374; Wed, 12 Jul 2006 10:18:50 -0700 (PDT) Date: Wed, 12 Jul 2006 17:19:00 -0000 From: "H. J. Lu" To: Nick Clifton Cc: binutils@sources.redhat.com Subject: Re: PATCH: PR ld/2884: Crash in elf64_ia64_relocate_section Message-ID: <20060712171849.GA13132@lucon.org> References: <20060706232756.GA20456@lucon.org> <44B3B00C.8030103@redhat.com> <20060711174103.GA4385@lucon.org> <20060712040255.GA8103@lucon.org> <44B4BBE7.1010707@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <44B4BBE7.1010707@redhat.com> User-Agent: Mutt/1.4.2.1i Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org X-SW-Source: 2006-07/txt/msg00163.txt.bz2 On Wed, Jul 12, 2006 at 10:07:51AM +0100, Nick Clifton wrote: > Hi H.J. > > >bfd/ > >2006-07-11 H.J. Lu > > > > 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 > > > > 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 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 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 + +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 + +__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 + +__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 + +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 + +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 + } + } +}