This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH] .symver x, x@foo (take 2)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: binutils at sources dot redhat dot com
- Date: Tue, 11 Feb 2003 09:31:08 +0100
- Subject: [PATCH] .symver x, x@foo (take 2)
- References: <20030210110331.I17910@sunsite.ms.mff.cuni.cz>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Mon, Feb 10, 2003 at 11:03:31AM +0100, Jakub Jelinek wrote:
> 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.
For alpha the symbol was changed into indirect too late.
The following patch works on all arches I've tried (IA-{32,64}, Alpha,
PPC32, s390{,x}, x86-64) and builds a working glibc (unlike
binutils without the patch).
2003-02-10 Jakub Jelinek <jakub@redhat.com>
bfd/
* elflink.h (elf_link_add_object_symbols): 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-10 10:42:05.000000000 -0500
@@ -1168,6 +1168,8 @@ elf_link_add_object_symbols (abfd, info)
Elf_External_Versym *extversym = NULL;
Elf_External_Versym *ever;
struct elf_link_hash_entry *weaks;
+ struct elf_link_hash_entry **nondeflt_vers = NULL;
+ bfd_size_type nondeflt_vers_cnt = 0;
Elf_Internal_Sym *isymbuf = NULL;
Elf_Internal_Sym *isym;
Elf_Internal_Sym *isymend;
@@ -1997,6 +1999,23 @@ elf_link_add_object_symbols (abfd, info)
override, dt_needed))
goto error_free_vers;
+ if (definition && (abfd->flags & DYNAMIC) == 0)
+ {
+ char *p = strchr (name, ELF_VER_CHR);
+ if (p != NULL && p[1] != ELF_VER_CHR)
+ {
+ /* Queue non-default versions so that .symver x, x@FOO
+ aliases can be checked. */
+ if (! nondeflt_vers)
+ {
+ amt = (isymend - isym + 1)
+ * sizeof (struct elf_link_hash_entry *);
+ nondeflt_vers = bfd_malloc (amt);
+ }
+ nondeflt_vers [nondeflt_vers_cnt++] = h;
+ }
+ }
+
if (dynsym && h->dynindx == -1)
{
if (! _bfd_elf_link_record_dynamic_symbol (info, h))
@@ -2071,6 +2090,56 @@ elf_link_add_object_symbols (abfd, info)
}
}
+ /* Now that all the symbols from this input file are created, handle
+ .symver foo, foo@BAR such that any relocs against foo become foo@BAR. */
+ if (nondeflt_vers != NULL)
+ {
+ bfd_size_type cnt, symidx;
+
+ for (cnt = 0; cnt < nondeflt_vers_cnt; ++cnt)
+ {
+ struct elf_link_hash_entry *h = nondeflt_vers[cnt], *hi;
+ char *shortname, *p;
+
+ p = strchr (h->root.root.string, ELF_VER_CHR);
+ if (p == NULL
+ || (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak))
+ continue;
+
+ amt = p - h->root.root.string;
+ shortname = bfd_malloc (amt + 1);
+ memcpy (shortname, h->root.root.string, amt);
+ shortname[amt] = '\0';
+
+ hi = (struct elf_link_hash_entry *)
+ bfd_link_hash_lookup (info->hash, shortname,
+ FALSE, FALSE, FALSE);
+ if (hi != NULL
+ && hi->root.type == h->root.type
+ && hi->root.u.def.value == h->root.u.def.value
+ && hi->root.u.def.section == h->root.u.def.section)
+ {
+ (*bed->elf_backend_hide_symbol) (info, hi, TRUE);
+ hi->root.type = bfd_link_hash_indirect;
+ hi->root.u.i.link = (struct bfd_link_hash_entry *) h;
+ (*bed->elf_backend_copy_indirect_symbol) (bed, h, hi);
+ hi->elf_link_hash_flags = 0;
+ sym_hash = elf_sym_hashes (abfd);
+ if (sym_hash)
+ for (symidx = 0; symidx < extsymcount; ++symidx)
+ if (sym_hash[symidx] == hi)
+ {
+ sym_hash[symidx] = h;
+ break;
+ }
+ }
+ free (shortname);
+ }
+ free (nondeflt_vers);
+ nondeflt_vers = NULL;
+ }
+
if (extversym != NULL)
{
free (extversym);
@@ -2277,6 +2346,8 @@ elf_link_add_object_symbols (abfd, info)
return TRUE;
error_free_vers:
+ if (nondeflt_vers != NULL)
+ free (nondeflt_vers);
if (extversym != NULL)
free (extversym);
error_free_sym:
--- 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