bfd/
2006-07-12 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-12 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.
This commit is contained in:
parent
fb405f8a9f
commit
d2dee3b25c
@ -1,3 +1,11 @@
|
||||
2006-07-12 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.
|
||||
|
||||
2006-07-12 Matthew R. Dempsky <mrd@alkemio.org>
|
||||
|
||||
* cpu-m68k.c (bfd_m68k_compatible): Handle CPU32.
|
||||
|
@ -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))
|
||||
|
@ -1,3 +1,19 @@
|
||||
2006-07-12 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.
|
||||
|
||||
2006-07-12 Richard Sandiford <richard@codesourcery.com>
|
||||
|
||||
* ld-m68k/merge-ok-1c.d: New test.
|
||||
|
5
ld/testsuite/ld-elf/begin.c
Normal file
5
ld/testsuite/ld-elf/begin.c
Normal file
@ -0,0 +1,5 @@
|
||||
extern void foo (void);
|
||||
|
||||
static void (*const init_array []) (void)
|
||||
__attribute__ ((used, section (".init_array"), aligned (sizeof (void *))))
|
||||
= { foo };
|
7
ld/testsuite/ld-elf/end.c
Normal file
7
ld/testsuite/ld-elf/end.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
void
|
||||
foo ()
|
||||
{
|
||||
printf ("TEST1\n");
|
||||
}
|
8
ld/testsuite/ld-elf/endhidden.c
Normal file
8
ld/testsuite/ld-elf/endhidden.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include <stdio.h>
|
||||
|
||||
__attribute__ ((visibility ("hidden")))
|
||||
void
|
||||
foo ()
|
||||
{
|
||||
printf ("TEST1\n");
|
||||
}
|
8
ld/testsuite/ld-elf/endprotected.c
Normal file
8
ld/testsuite/ld-elf/endprotected.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include <stdio.h>
|
||||
|
||||
__attribute__ ((visibility ("protected")))
|
||||
void
|
||||
foo ()
|
||||
{
|
||||
printf ("TEST1\n");
|
||||
}
|
11
ld/testsuite/ld-elf/foo.c
Normal file
11
ld/testsuite/ld-elf/foo.c
Normal file
@ -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 };
|
4
ld/testsuite/ld-elf/foo.map
Normal file
4
ld/testsuite/ld-elf/foo.map
Normal file
@ -0,0 +1,4 @@
|
||||
FOO {
|
||||
global: foo;
|
||||
local: *;
|
||||
};
|
3
ld/testsuite/ld-elf/hidden.out
Normal file
3
ld/testsuite/ld-elf/hidden.out
Normal file
@ -0,0 +1,3 @@
|
||||
TEST2
|
||||
TEST1
|
||||
MAIN
|
8
ld/testsuite/ld-elf/main.c
Normal file
8
ld/testsuite/ld-elf/main.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
printf ("MAIN\n");
|
||||
return 0;
|
||||
}
|
3
ld/testsuite/ld-elf/normal.out
Normal file
3
ld/testsuite/ld-elf/normal.out
Normal file
@ -0,0 +1,3 @@
|
||||
TEST1
|
||||
TEST1
|
||||
MAIN
|
112
ld/testsuite/ld-elf/shared.exp
Normal file
112
ld/testsuite/ld-elf/shared.exp
Normal file
@ -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
|
@ -1341,3 +1341,123 @@ proc run_ld_link_exec_tests { targets_to_xfail ldtests } {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user