diff options
author | Cary Coutant <ccoutant@gmail.com> | 2015-07-27 15:09:08 -0700 |
---|---|---|
committer | Cary Coutant <ccoutant@gmail.com> | 2015-08-18 19:24:41 -0700 |
commit | b45e00b3ed40589af75b8a36a67905ae265a20f8 (patch) | |
tree | b9b7e0b810d2cc3327cb743f14f3241e173b0d5c /gold/testsuite | |
parent | e49433d22dae92a56ae15a8b5742cbf1f31d5fd1 (diff) | |
download | gdb-b45e00b3ed40589af75b8a36a67905ae265a20f8.zip gdb-b45e00b3ed40589af75b8a36a67905ae265a20f8.tar.gz gdb-b45e00b3ed40589af75b8a36a67905ae265a20f8.tar.bz2 |
Fix symbol versioning problems in PR 18703.
If a symbol is defined with ".symver foo,foo@VER", the assembler
creates two symbols in the object: one unversioned, and one with
the (non-default) version "VER". If foo is listed in a version
script, gold would then make the first of those symbols the
default version, and would ignore the second symbol as a
duplicate, without making it a non-default version. While this is
arguably reasonable behavior, it doesn't match Gnu ld behavior,
so this patch fixes that by allowing the second definition to
override the first by resetting the "default version" indication.
Several test cases from the Gnu ld testsuite also exposed another
related problem, where a symbol defined with ".symver foo,foo@",
placed into a shared library, is not handled properly by gold.
This patch also fixes that case, binding the symbol to the base
version.
gold/
PR gold/18703
* dynobj.cc (Versions::record_version): Handle symbol defined with
base version.
(Versions::symbol_section_contents): Likewise.
* symtab.h (Symbol::set_is_not_default): New class method.
(Symbol_table::resolve): Add is_default_version parameter.
(Symbol_table::should_override): Likewise.
* resolve.cc (Symbol_table::resolve): Add is_default_version parameter,
and pass to should_override. Adjust all callers and explicit
instantiations.
(Symbol_table::should_override): Add is_default_value parameter;
allow default version in a dynamic object to override existing
definition from same object.
* symtab.cc (Symbol_table::add_from_object): Handle case where same
symbol is defined as unversioned and non-default version in the same
object.
* testsuite/Makefile.am (ver_test_13): New test case.
* testsuite/Makefile.in: Regenerate.
* testsuite/ver_test_4.cc: Add test for symbol with base version.
* testsuite/ver_test_4.sh: Likewise.
* testsuite/ver_test_13.c: New source file.
* testsuite/ver_test_13.script: New version script.
* testsuite/ver_test_13.sh: New test case.
Diffstat (limited to 'gold/testsuite')
-rw-r--r-- | gold/testsuite/Makefile.am | 9 | ||||
-rw-r--r-- | gold/testsuite/Makefile.in | 12 | ||||
-rw-r--r-- | gold/testsuite/ver_test_13.c | 7 | ||||
-rw-r--r-- | gold/testsuite/ver_test_13.script | 4 | ||||
-rwxr-xr-x | gold/testsuite/ver_test_13.sh | 59 | ||||
-rw-r--r-- | gold/testsuite/ver_test_4.cc | 10 | ||||
-rwxr-xr-x | gold/testsuite/ver_test_4.sh | 5 |
7 files changed, 102 insertions, 4 deletions
diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index ca07016..5ceaeef 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -1563,6 +1563,15 @@ ver_test_12_LDADD = ver_test_12.o ver_test_12.o: gcctestdir/ld ver_test_1.o ver_test_2.o ver_test_4.o gcctestdir/ld -r -o $@ ver_test_1.o ver_test_2.o ver_test_4.o +check_SCRIPTS += ver_test_13.sh +check_DATA += ver_test_13.syms +ver_test_13.syms: ver_test_13.so + $(TEST_READELF) -s $< >$@ 2>/dev/null +ver_test_13.so: gcctestdir/ld ver_test_13.o ver_test_13.script + $(LINK) -Bgcctestdir/ -shared -Wl,--version-script,$(srcdir)/ver_test_13.script ver_test_13.o +ver_test_13.o: ver_test_13.c + $(COMPILE) -c -fpic -o $@ $< + check_PROGRAMS += protected_1 protected_1_SOURCES = \ protected_main_1.cc protected_main_2.cc protected_main_3.cc diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index d4cc5dc..9cabcd8 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -327,7 +327,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_1.sh ver_test_2.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_4.sh ver_test_5.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_7.sh ver_test_10.sh \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ relro_test.sh \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_13.sh relro_test.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_matching_test.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_3.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_4.sh \ @@ -371,7 +371,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_1.syms ver_test_2.syms \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_4.syms ver_test_5.syms \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_7.syms ver_test_10.syms \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ protected_3.err \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_13.syms protected_3.err \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ relro_test.stdout \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_matching_test.stdout \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_3.stdout \ @@ -4432,6 +4432,8 @@ ver_test_7.sh.log: ver_test_7.sh @p='ver_test_7.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) ver_test_10.sh.log: ver_test_10.sh @p='ver_test_10.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) +ver_test_13.sh.log: ver_test_13.sh + @p='ver_test_13.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) relro_test.sh.log: relro_test.sh @p='relro_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) ver_matching_test.sh.log: ver_matching_test.sh @@ -5747,6 +5749,12 @@ uninstall-am: @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_AR) rc $@ $^ @GCC_TRUE@@NATIVE_LINKER_TRUE@ver_test_12.o: gcctestdir/ld ver_test_1.o ver_test_2.o ver_test_4.o @GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir/ld -r -o $@ ver_test_1.o ver_test_2.o ver_test_4.o +@GCC_TRUE@@NATIVE_LINKER_TRUE@ver_test_13.syms: ver_test_13.so +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -s $< >$@ 2>/dev/null +@GCC_TRUE@@NATIVE_LINKER_TRUE@ver_test_13.so: gcctestdir/ld ver_test_13.o ver_test_13.script +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(LINK) -Bgcctestdir/ -shared -Wl,--version-script,$(srcdir)/ver_test_13.script ver_test_13.o +@GCC_TRUE@@NATIVE_LINKER_TRUE@ver_test_13.o: ver_test_13.c +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(COMPILE) -c -fpic -o $@ $< @GCC_TRUE@@NATIVE_LINKER_TRUE@protected_1.so: gcctestdir/ld protected_1_pic.o protected_2_pic.o protected_3_pic.o @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -shared protected_1_pic.o protected_2_pic.o protected_3_pic.o diff --git a/gold/testsuite/ver_test_13.c b/gold/testsuite/ver_test_13.c new file mode 100644 index 0000000..01f4ba7 --- /dev/null +++ b/gold/testsuite/ver_test_13.c @@ -0,0 +1,7 @@ +__asm__ (".symver foo, foo@VER_0"); + +int foo(void); + +int foo(void) { + return 0; +} diff --git a/gold/testsuite/ver_test_13.script b/gold/testsuite/ver_test_13.script new file mode 100644 index 0000000..f0205cf --- /dev/null +++ b/gold/testsuite/ver_test_13.script @@ -0,0 +1,4 @@ +VER_0 { + global: + foo; +}; diff --git a/gold/testsuite/ver_test_13.sh b/gold/testsuite/ver_test_13.sh new file mode 100755 index 0000000..b0435ff --- /dev/null +++ b/gold/testsuite/ver_test_13.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +# ver_test_13.sh -- a test case for version script matching + +# Copyright (C) 2015 Free Software Foundation, Inc. +# Written by Cary Coutant <ccoutant@gmail.com>. + +# This file is part of gold. + +# This program 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 3 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. + +# This test verifies that a symbol declared with .symver as a +# non-default version does not get overridden by the version +# script and declared as a default version. +# (See PR gold/18703.) + +check() +{ + if ! grep -q "$2" "$1" + then + echo "Did not find expected symbol in $1:" + echo " $2" + echo "" + echo "Actual output below:" + cat "$1" + exit 1 + fi +} + +check_missing() +{ + if grep -q "$2" "$1" + then + echo "Found unexpected symbol in $1:" + echo " $2" + echo "" + echo "Actual output below:" + cat "$1" + exit 1 + fi +} + +check ver_test_13.syms "foo@VER_0$" +check_missing ver_test_13.syms "foo@@VER_0" + +exit 0 diff --git a/gold/testsuite/ver_test_4.cc b/gold/testsuite/ver_test_4.cc index 7a5544e..2fdba21 100644 --- a/gold/testsuite/ver_test_4.cc +++ b/gold/testsuite/ver_test_4.cc @@ -22,6 +22,16 @@ #include "ver_test.h" +__asm__(".symver t1_2_orig,t1_2@"); + +extern "C" +int +t1_2_orig() +{ + TRACE + return 12; +} + __asm__(".symver t1_2_a,t1_2@@VER2"); extern "C" diff --git a/gold/testsuite/ver_test_4.sh b/gold/testsuite/ver_test_4.sh index 05305b1..bc67ef9 100755 --- a/gold/testsuite/ver_test_4.sh +++ b/gold/testsuite/ver_test_4.sh @@ -24,17 +24,18 @@ check() { - if ! grep -q "$2" "$1" + if ! sed '/\.symtab/q' "$1" | grep -q "$2" then echo "Did not find expected symbol in $1:" echo " $2" echo "" echo "Actual output below:" - cat "$1" + sed '/\.symtab/q' "$1" exit 1 fi } +check ver_test_4.syms "t1_2\$" check ver_test_4.syms "t1_2@@VER2" check ver_test_4.syms "t2_2@VER1" check ver_test_4.syms "t2_2@@VER2" |