This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH] .symver x, x@foo
- From: Jakub Jelinek <jakub at redhat dot com>
- To: binutils at sources dot redhat dot com
- Date: Mon, 10 Feb 2003 11:03:31 +0100
- Subject: [PATCH] .symver x, x@foo
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
The following patch changes .symver x, x@foo so that any references to x
in the same link aren't resolved to the local x copy, but end up
with dynamic relocation against x@foo.
See the thread from December about glibc errno on this list.
ATM there is no way to make dynamic relocations which are needed, so that
references to the compat symbol in the shared library defining
it are resolved to R_*_COPY in binaries referencing it if any.
The closest what hjl suggested was that the shared library defines x@foo
symbol and the relocations are against a different symbol, SHN_UNDEF
x. The problem then is that the binary might have legally x@bar COPY
reloc.
This is still a RFC, because although it works on most arches, it failed
on alpha with an assertion. Am going to look at it.
While at it, I've enabled ELF visibility/versioning/shlib tests on
x86_64/s390* linux too, on x86_64 they pass, on s390 there are lots of
failures. Haven't looked at them closely yet, but most of them look like
find_nearest_line doesn't work as it should (the expected errors are
reported with objectfile(section+offset), not as sourcefile:line.
2003-02-10 Jakub Jelinek <jakub@redhat.com>
bfd/
* elflink.h (elf_link_assign_sym_version): Handle .symver x, x@FOO.
ld/testsuite/
* ld-shared/shared.exp: Run on s390*-*-linux* and x86_64-*-linux* too.
xfail tests linking non-pic code into shared libs on x86_64-*-linux*.
* ld-elfvsb/elfvsb.exp: Likewise.
* ld-elfvers/vers.exp: Likewise. Add vers24a, vers24b and vers24c
tests.
* ld-elfvers/vers3.ver: Allow VERS_2.0 to come before GLIBC_*
version.
* ld-elfvers/vers19.ver: Likewise.
* ld-elfvers/vers24a.c: New test.
* ld-elfvers/vers24b.c: New test.
* ld-elfvers/vers24c.c: New test.
* ld-elfvers/vers24.map: New test.
* ld-elfvers/vers24.rd: New test.
* lib/ld-lib.exp (run_ld_link_tests): Add optional 7th argument
cflags. If source files have .c extension, compile them first.
--- bfd/elflink.h.jj 2003-02-05 18:24:42.000000000 -0500
+++ bfd/elflink.h 2003-02-08 06:28:47.000000000 -0500
@@ -4358,7 +4358,46 @@ elf_link_assign_sym_version (h, data)
if ((*d->match) (d, h->root.root.string))
{
if (d->symver)
- matched = TRUE;
+ {
+ /* Handle .symver x, x@FOO, such that relocations
+ against x cause dynamic relocations against
+ x@FOO. */
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ {
+ bfd_size_type len = strlen (h->root.root.string);
+ char *vername;
+ struct elf_link_hash_entry *vh;
+
+ vername = bfd_malloc (len + 1
+ + strlen (t->name) + 1);
+ memcpy (vername, h->root.root.string, len);
+ vername[len] = ELF_VER_CHR;
+ strcpy (vername + len + 1, t->name);
+ vh = (struct elf_link_hash_entry *)
+ bfd_link_hash_lookup (info->hash, vername,
+ FALSE, FALSE, FALSE);
+ free (vername);
+ if (vh != NULL
+ && vh->root.type == h->root.type
+ && vh->root.u.def.value
+ == h->root.u.def.value
+ && vh->root.u.def.section
+ == h->root.u.def.section)
+ {
+ (*bed->elf_backend_hide_symbol) (info, h,
+ TRUE);
+ h->root.type = bfd_link_hash_indirect;
+ h->root.u.i.link
+ = (struct bfd_link_hash_entry *) vh;
+ (*bed->elf_backend_copy_indirect_symbol)
+ (bed, vh, h);
+ h->elf_link_hash_flags = 0;
+ break;
+ }
+ }
+ matched = TRUE;
+ }
else
{
/* There is a version without definition. Make
--- ld/testsuite/ld-elfvers/vers.exp.jj 2002-09-10 08:51:14.000000000 -0400
+++ ld/testsuite/ld-elfvers/vers.exp 2003-02-09 17:59:11.000000000 -0500
@@ -43,7 +43,9 @@ if { ![istarget hppa*64*-*-hpux*] \
&& ![istarget sparc*-*-linux*] \
&& ![istarget arm*-*-linux*] \
&& ![istarget mips*-*-linux*] \
- && ![istarget alpha*-*-linux*] } {
+ && ![istarget alpha*-*-linux*] \
+ && ![istarget s390*-*-linux*] \
+ && ![istarget x86_64-*-linux*] } {
return
}
@@ -719,7 +721,12 @@ build_vers_lib "vers1" vers1.c vers1 ""
# Test #2 - build a library, and link it against the library we built in step
# 1.
#
-build_vers_lib "vers2" vers2.c vers2 vers1.so vers2.map vers2.ver vers2.dsym ""
+if [istarget x86_64-*-linux*] {
+ # x86_64 doesn't like non-pic shared libraries
+ xfail "vers2"
+} else {
+ build_vers_lib "vers2" vers2.c vers2 vers1.so vers2.map vers2.ver vers2.dsym ""
+}
#
# Test #3 - build an executable, and link it against vers1.so.
@@ -838,3 +845,21 @@ build_vers_lib "vers23b" vers23b.c vers2
build_vers_lib "vers23c" vers23b.c vers23c "vers23a.so" vers23b.map vers23c.ver vers23b.dsym ""
build_exec "vers23d" vers23.c vers23d "tmpdir/vers23a.so tmpdir/vers23c.so" "" vers23.ver vers23d.dsym ""
build_exec "vers23" vers23.c vers23 "tmpdir/vers23a.so tmpdir/vers23b.o tmpdir/vers23b.so" "" vers23.ver vers23.dsym ""
+
+# Test .symver x,x@VERS.0
+set as_pic_flags ""
+if [istarget sparc*-*-*] {
+ set as_pic_flags "-K PIC"
+}
+run_ld_link_tests [list "\"vers24a\"
+ \"-shared --version-script $srcdir/$subdir/vers24.map\"
+ \"$as_pic_flags\" {vers24a.c vers24b.c} { { readelf -Wrs vers24.rd } }
+ \"libvers24a.so\" \"-fpic\""]
+run_ld_link_tests [list "\"vers24b\"
+ \"-shared --version-script $srcdir/$subdir/vers24.map\"
+ \"$as_pic_flags\" {vers24b.c vers24a.c} { { readelf -Wrs vers24.rd } }
+ \"libvers24b.so\" \"-fpic\""]
+run_ld_link_tests [list "\"vers24c\"
+ \"-shared --version-script $srcdir/$subdir/vers24.map\"
+ \"$as_pic_flags\" {vers24c.c} { { readelf -Wrs vers24.rd } }
+ \"libvers24c.so\" \"-fpic\""]
--- ld/testsuite/ld-elfvers/vers24a.c.jj 2003-02-08 16:00:04.000000000 -0500
+++ ld/testsuite/ld-elfvers/vers24a.c 2003-02-08 17:27:53.000000000 -0500
@@ -0,0 +1,5 @@
+/* Test whether .symver x, x@foo
+ causes relocations against x within the same shared library
+ to become dynamic relocations against x@foo. */
+int x = 12;
+__asm__ (".symver x, x@VERS.0");
--- ld/testsuite/ld-elfvers/vers24b.c.jj 2003-02-08 16:00:15.000000000 -0500
+++ ld/testsuite/ld-elfvers/vers24b.c 2003-02-07 17:43:02.000000000 -0500
@@ -0,0 +1,5 @@
+extern int x;
+void foo (void)
+{
+ x = 24;
+}
--- ld/testsuite/ld-elfvers/vers24.map.jj 2003-02-08 16:00:32.000000000 -0500
+++ ld/testsuite/ld-elfvers/vers24.map 2003-02-08 16:01:23.000000000 -0500
@@ -0,0 +1,4 @@
+VERS.0 {
+ global: x; foo;
+ local: *;
+};
--- ld/testsuite/ld-elfvers/vers3.ver.jj 2001-07-11 09:48:54.000000000 -0400
+++ ld/testsuite/ld-elfvers/vers3.ver 2003-02-09 17:57:40.000000000 -0500
@@ -1,4 +1,4 @@
Version References:
required from tmpdir/vers1.so:
- 0x0a7922b0 0x00 02 VERS_2.0
+ 0x0a7922b0 0x00 0[23] VERS_2.0
--- ld/testsuite/ld-elfvers/vers24.rd.jj 2003-02-08 17:18:25.000000000 -0500
+++ ld/testsuite/ld-elfvers/vers24.rd 2003-02-09 18:22:41.000000000 -0500
@@ -0,0 +1,15 @@
+Relocation section .*
+# Ensure there is a dynamic relocation against x
+#...
+[0-9a-f]+ +[0-9a-f]+ R_.* +x(| \+ 0)
+#...
+Symbol table '.dynsym' contains [0-9]+ entries:
+# And ensure the dynamic symbol table contains at least x@VERS.0
+# and foo@@VERS.0 symbols
+#...
+ +[0-9]+: [0-9a-f]+ +(4 OBJECT +GLOBAL DEFAULT +[0-9]+ x|[0-9]+ FUNC +GLOBAL DEFAULT +[0-9]+ foo@)@VERS\.0
+#...
+ +[0-9]+: [0-9a-f]+ +(4 OBJECT +GLOBAL DEFAULT +[0-9]+ x|[0-9]+ FUNC +GLOBAL DEFAULT +[0-9]+ foo@)@VERS\.0
+#...
+Symbol table '.symtab' contains [0-9]+ entries:
+#pass
--- ld/testsuite/ld-elfvers/vers24c.c.jj 2003-02-08 17:29:10.000000000 -0500
+++ ld/testsuite/ld-elfvers/vers24c.c 2003-02-08 17:29:04.000000000 -0500
@@ -0,0 +1,9 @@
+/* Test whether .symver x, x@foo
+ causes relocations against x within the same shared library
+ to become dynamic relocations against x@foo. */
+int x = 12;
+__asm__ (".symver x, x@VERS.0");
+void foo (void)
+{
+ x = 24;
+}
--- ld/testsuite/ld-elfvers/vers19.ver.jj 2001-05-11 06:26:01.000000000 -0400
+++ ld/testsuite/ld-elfvers/vers19.ver 2003-02-09 17:57:53.000000000 -0500
@@ -1,3 +1,3 @@
Version References:
required from vers17.so:
- 0x0a7922b0 0x00 02 VERS_2.0
+ 0x0a7922b0 0x00 0[23] VERS_2.0
--- ld/testsuite/ld-elfvsb/elfvsb.exp.jj 2002-07-30 10:20:17.000000000 -0400
+++ ld/testsuite/ld-elfvsb/elfvsb.exp 2003-02-09 18:23:44.000000000 -0500
@@ -1,5 +1,5 @@
# Expect script for ld-visibility tests
-# Copyright 2000, 2001 Free Software Foundation, Inc.
+# Copyright 2000, 2001, 2003 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
@@ -35,7 +35,9 @@ if { ![istarget hppa*64*-*-hpux*] \
&& ![istarget powerpc-*-linux*] \
&& ![istarget arm*-*-linux*] \
&& ![istarget alpha*-*-linux*] \
- && ![istarget sparc*-*-linux*] } {
+ && ![istarget sparc*-*-linux*] \
+ && ![istarget s390*-*-linux*] \
+ && ![istarget x86_64-*-linux*] } {
return
}
@@ -255,6 +257,7 @@ proc visibility_run {visibility} {
setup_xfail "ia64-*-linux*"
setup_xfail "alpha*-*-linux*"
}
+ setup_xfail "x86_64-*-linux*"
visibility_test $visibility vnp "visibility ($visibility) (non PIC)" mainnp.o sh1np.o sh2np.o elfvsb
@@ -285,6 +288,7 @@ proc visibility_run {visibility} {
setup_xfail "alpha*-*-linux*"
setup_xfail "mips*-*-linux*"
}
+ setup_xfail "x86_64-*-linux*"
visibility_test $visibility vnp "visibility ($visibility) (non PIC, load offset)" \
mainnp.o sh1np.o sh2np.o elfvsb \
"-T $srcdir/$subdir/elf-offset.ld"
@@ -341,6 +345,7 @@ proc visibility_run {visibility} {
setup_xfail "ia64-*-linux*"
setup_xfail "alpha*-*-linux*"
}
+ setup_xfail "x86_64-*-linux*"
visibility_test $visibility vmpnp "visibility ($visibility) (PIC main, non PIC so)" mainp.o sh1np.o sh2np.o elfvsb
}
} else {
--- ld/testsuite/lib/ld-lib.exp.jj 2002-12-28 17:19:23.000000000 -0500
+++ ld/testsuite/lib/ld-lib.exp 2003-02-08 16:15:19.000000000 -0500
@@ -1,5 +1,5 @@
# Support routines for LD testsuite.
-# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify
@@ -978,9 +978,11 @@ proc file_contents { filename } {
return $contents
}
-# List contains test-items with 3 items followed by 2 lists:
+# List contains test-items with 3 items followed by 2 lists, one item and
+# one optional item:
# 0:name 1:ld options 2:assembler options
# 3:filenames of assembler files 4: action and options. 5: name of output file
+# 6:compiler flags (optional)
# Actions:
# objdump: Apply objdump options on result. Compare with regex (last arg).
@@ -996,14 +998,17 @@ proc run_ld_link_tests { ldtests } {
global srcdir
global subdir
global env
+ global CC
+ global CFLAGS
foreach testitem $ldtests {
set testname [lindex $testitem 0]
set ld_options [lindex $testitem 1]
set as_options [lindex $testitem 2]
- set as_files [lindex $testitem 3]
+ set src_files [lindex $testitem 3]
set actions [lindex $testitem 4]
set binfile tmpdir/[lindex $testitem 5]
+ set cflags [lindex $testitem 6]
set objfiles {}
set is_unresolved 0
set failed 0
@@ -1011,16 +1016,25 @@ proc run_ld_link_tests { ldtests } {
# verbose -log "Testname is $testname"
# verbose -log "ld_options is $ld_options"
# verbose -log "as_options is $as_options"
-# verbose -log "as_files is $as_files"
+# verbose -log "src_files is $src_files"
# verbose -log "actions is $actions"
# verbose -log "binfile is $binfile"
# Assemble each file in the test.
- foreach as_file $as_files {
- set objfile "tmpdir/[file rootname $as_file].o"
+ foreach src_file $src_files {
+ set objfile "tmpdir/[file rootname $src_file].o"
lappend objfiles $objfile
- if ![ld_assemble $as "$as_options $srcdir/$subdir/$as_file" $objfile] {
+ if { [file extension $src_file] == ".c" } {
+ set as_file "tmpdir/[file rootname $src_file].s"
+ if ![ld_compile "$CC -S $CFLAGS $cflags" $srcdir/$subdir/$src_file $as_file] {
+ set is_unresolved 1
+ break
+ }
+ } else {
+ set as_file "$srcdir/$subdir/$src_file"
+ }
+ if ![ld_assemble $as "$as_options $as_file" $objfile] {
set is_unresolved 1
break
}
--- ld/testsuite/ld-shared/shared.exp.jj 2002-07-30 10:20:20.000000000 -0400
+++ ld/testsuite/ld-shared/shared.exp 2003-02-09 18:00:00.000000000 -0500
@@ -1,5 +1,5 @@
# Expect script for ld-shared tests
-# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003
# Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify
@@ -49,7 +49,9 @@ if { ![istarget hppa*64*-*-hpux*] \
&& ![istarget arm*-*-linux*] \
&& ![istarget alpha*-*-linux*] \
&& ![istarget rs6000*-*-aix*] \
- && ![istarget powerpc*-*-aix*] } {
+ && ![istarget powerpc*-*-aix*] \
+ && ![istarget s390*-*-linux*] \
+ && ![istarget x86_64-*-linux*] } {
return
}
@@ -198,6 +200,7 @@ if ![ld_compile "$CC $CFLAGS $SHCFLAG" $
setup_xfail "*-*-sunos4*"
setup_xfail "ia64-*-linux*"
setup_xfail "alpha*-*-linux*"
+ setup_xfail "x86_64-*-linux*"
shared_test shnp "shared (non PIC)" mainnp.o sh1np.o sh2np.o shared
# Test ELF shared library relocations with a non-zero load
@@ -210,6 +213,7 @@ if ![ld_compile "$CC $CFLAGS $SHCFLAG" $
setup_xfail "ia64-*-linux*"
setup_xfail "alpha*-*-linux*"
setup_xfail "mips*-*-linux*"
+ setup_xfail "x86_64-*-linux*"
shared_test shnp "shared (non PIC, load offset)" \
mainnp.o sh1np.o sh2np.o shared \
"-T $srcdir/$subdir/elf-offset.ld"
@@ -251,6 +255,7 @@ if ![ld_compile "$CC $CFLAGS $SHCFLAG $p
setup_xfail "*-*-sunos4*"
setup_xfail "ia64-*-linux*"
setup_xfail "alpha*-*-linux*"
+ setup_xfail "x86_64-*-linux*"
shared_test shmpnp "shared (PIC main, non PIC so)" mainp.o sh1np.o sh2np.o shared
}
} else {
Jakub