This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] .symver x, x@foo


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]