diff options
-rw-r--r-- | gold/ChangeLog | 10 | ||||
-rw-r--r-- | gold/resolve.cc | 11 | ||||
-rw-r--r-- | gold/testsuite/Makefile.am | 20 | ||||
-rw-r--r-- | gold/testsuite/Makefile.in | 28 | ||||
-rwxr-xr-x | gold/testsuite/dyn_weak_ref.sh | 42 | ||||
-rw-r--r-- | gold/testsuite/dyn_weak_ref_1.c | 39 | ||||
-rw-r--r-- | gold/testsuite/dyn_weak_ref_2.c | 32 |
7 files changed, 177 insertions, 5 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 87eb2eb..667caae 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,13 @@ +2010-08-27 Doug Kwan <dougkwan@google.com> + + * gold/resolve.cc (Symbol_table::should_override): Let a weak + reference override an existing dynamic weak reference. + * testsuite/Makefile.am: Add new test dyn_weak_ref. + * testsuite/Makefile.in: Regenerate. + * testsuite/dyn_weak_ref.sh: New file. + * testsuite/dyn_weak_ref_1.c: Ditto. + * testsuite/dyn_weak_ref_2.c: Ditto. + 2010-08-27 Ian Lance Taylor <iant@google.com> * incremental.h (class Incremental_input_entry): Add virtual diff --git a/gold/resolve.cc b/gold/resolve.cc index 29d9d79..4864f1e 100644 --- a/gold/resolve.cc +++ b/gold/resolve.cc @@ -630,14 +630,21 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits, case UNDEF * 16 + WEAK_UNDEF: case WEAK_UNDEF * 16 + WEAK_UNDEF: case DYN_UNDEF * 16 + WEAK_UNDEF: - case DYN_WEAK_UNDEF * 16 + WEAK_UNDEF: case COMMON * 16 + WEAK_UNDEF: case WEAK_COMMON * 16 + WEAK_UNDEF: case DYN_COMMON * 16 + WEAK_UNDEF: case DYN_WEAK_COMMON * 16 + WEAK_UNDEF: - // A new weak undefined reference tells us nothing. + // A new weak undefined reference tells us nothing unless the + // exisiting symbol is a dynamic weak reference. return false; + case DYN_WEAK_UNDEF * 16 + WEAK_UNDEF: + // A new weak reference overrides an existing dynamic weak reference. + // This is necessary because a dynamic weak reference remembers + // the old binding, which may not be weak. If we keeps the existing + // dynamic weak reference, the weakness may be dropped in the output. + return true; + case DYN_DEF * 16 + WEAK_UNDEF: case DYN_WEAK_DEF * 16 + WEAK_UNDEF: // For a dynamic def, we need to remember which kind of undef we see. diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index 875238f..bd8bfbd 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -1750,6 +1750,26 @@ strong_ref_weak_def_1.so: strong_ref_weak_def_1.o strong_ref_weak_def_2.so \ strong_ref_weak_def.stdout: strong_ref_weak_def_1.so $(TEST_READELF) -sWD $< > $@ +# Test that a strong weak reference remains strong if there is another +# weak reference in a DSO. +check_SCRIPTS += dyn_weak_ref.sh +check_DATA += dyn_weak_ref.stdout +MOSTLYCLEANFILES += dyn_weak_ref_1.so dyn_weak_ref_2.so \ + dyn_weak_ref.stdout +dyn_weak_ref_2.o: dyn_weak_ref_2.c + $(COMPILE) -o $@ -c -fPIC $< +dyn_weak_ref_2.so: dyn_weak_ref_2.o gcctestdir/ld + gcctestdir/ld -shared -o $@ dyn_weak_ref_2.o +dyn_weak_ref_1.o: dyn_weak_ref_1.c + $(COMPILE) -o $@ -c -fPIC $< +# We intentionally put dyn_weak_ref_2.so in front of dyn_weak_ref_1.o +# so that the weak ref there goes to gold's symbol table first. +dyn_weak_ref_1.so: dyn_weak_ref_1.o dyn_weak_ref_2.so gcctestdir/ld + gcctestdir/ld -shared -o $@ dyn_weak_ref_2.so dyn_weak_ref_1.o +dyn_weak_ref.stdout: dyn_weak_ref_1.so + $(TEST_READELF) -sWD $< > $@ + + # Test that --start-lib and --end-lib function correctly. check_PROGRAMS += start_lib_test start_lib_test: start_lib_test_main.o libstart_lib_test.a start_lib_test_2.o start_lib_test_3.o \ diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index 9405e27..29caa06 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -309,12 +309,16 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \ # symbol versioning is not used. # Test that strong reference to a weak symbol in a DSO remains strong. + +# Test that a strong weak reference remains strong if there is another +# weak reference in a DSO. @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_27 = exclude_libs_test.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ discard_locals_test.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ hidden_test.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ retain_symbols_file_test.sh \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ no_version_test.sh \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ strong_ref_weak_def.sh +@GCC_TRUE@@NATIVE_LINKER_TRUE@ strong_ref_weak_def.sh \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ dyn_weak_ref.sh @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_28 = exclude_libs_test.syms \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ discard_locals_test.syms \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ discard_locals_relocatable_test1.syms \ @@ -322,7 +326,8 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ hidden_test.err \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ retain_symbols_file_test.stdout \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ no_version_test.stdout \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ strong_ref_weak_def.stdout +@GCC_TRUE@@NATIVE_LINKER_TRUE@ strong_ref_weak_def.stdout \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ dyn_weak_ref.stdout @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_29 = exclude_libs_test.syms \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ libexclude_libs_test_1.a \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ libexclude_libs_test_2.a \ @@ -343,7 +348,10 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ no_version_test.stdout \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ strong_ref_weak_def_1.so \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ strong_ref_weak_def_2.so \ -@GCC_TRUE@@NATIVE_LINKER_TRUE@ strong_ref_weak_def.stdout +@GCC_TRUE@@NATIVE_LINKER_TRUE@ strong_ref_weak_def.stdout \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ dyn_weak_ref_1.so \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ dyn_weak_ref_2.so \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ dyn_weak_ref.stdout @GCC_TRUE@@MCMODEL_MEDIUM_TRUE@@NATIVE_LINKER_TRUE@am__append_30 = large @GCC_FALSE@large_DEPENDENCIES = @MCMODEL_MEDIUM_FALSE@large_DEPENDENCIES = @@ -3272,6 +3280,8 @@ no_version_test.sh.log: no_version_test.sh @p='no_version_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) strong_ref_weak_def.sh.log: strong_ref_weak_def.sh @p='strong_ref_weak_def.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) +dyn_weak_ref.sh.log: dyn_weak_ref.sh + @p='dyn_weak_ref.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) split_i386.sh.log: split_i386.sh @p='split_i386.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) split_x86_64.sh.log: split_x86_64.sh @@ -4448,6 +4458,18 @@ uninstall-am: @GCC_TRUE@@NATIVE_LINKER_TRUE@ strong_ref_weak_def_2.so @GCC_TRUE@@NATIVE_LINKER_TRUE@strong_ref_weak_def.stdout: strong_ref_weak_def_1.so @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -sWD $< > $@ +@GCC_TRUE@@NATIVE_LINKER_TRUE@dyn_weak_ref_2.o: dyn_weak_ref_2.c +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(COMPILE) -o $@ -c -fPIC $< +@GCC_TRUE@@NATIVE_LINKER_TRUE@dyn_weak_ref_2.so: dyn_weak_ref_2.o gcctestdir/ld +@GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir/ld -shared -o $@ dyn_weak_ref_2.o +@GCC_TRUE@@NATIVE_LINKER_TRUE@dyn_weak_ref_1.o: dyn_weak_ref_1.c +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(COMPILE) -o $@ -c -fPIC $< +# We intentionally put dyn_weak_ref_2.so in front of dyn_weak_ref_1.o +# so that the weak ref there goes to gold's symbol table first. +@GCC_TRUE@@NATIVE_LINKER_TRUE@dyn_weak_ref_1.so: dyn_weak_ref_1.o dyn_weak_ref_2.so gcctestdir/ld +@GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir/ld -shared -o $@ dyn_weak_ref_2.so dyn_weak_ref_1.o +@GCC_TRUE@@NATIVE_LINKER_TRUE@dyn_weak_ref.stdout: dyn_weak_ref_1.so +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -sWD $< > $@ @GCC_TRUE@@NATIVE_LINKER_TRUE@start_lib_test: start_lib_test_main.o libstart_lib_test.a start_lib_test_2.o start_lib_test_3.o \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir/ld @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(LINK) -Bgcctestdir/ -o $@ start_lib_test_main.o -L. -lstart_lib_test \ diff --git a/gold/testsuite/dyn_weak_ref.sh b/gold/testsuite/dyn_weak_ref.sh new file mode 100755 index 0000000..b52efac --- /dev/null +++ b/gold/testsuite/dyn_weak_ref.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +# dyn_weak_ref.sh -- test weak reference remains weak in output even if +# gold sees a dynamic weak reference before a static one. + +# Copyright 2010 Free Software Foundation, Inc. +# Written by Doug Kwan <dougkwan@google.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 checks that the reference to 'weak_ref' have WEAK binding. + +check() +{ + file=$1 + pattern=$2 + found=`grep "$pattern" $file` + if test -z "$found"; then + echo "pattern \"$pattern\" not found in file $file." + echo $found + exit 1 + fi +} + +check dyn_weak_ref.stdout ".* WEAK .* UND.* weak_ref" + +exit 0 diff --git a/gold/testsuite/dyn_weak_ref_1.c b/gold/testsuite/dyn_weak_ref_1.c new file mode 100644 index 0000000..fdd78dd --- /dev/null +++ b/gold/testsuite/dyn_weak_ref_1.c @@ -0,0 +1,39 @@ +// dyn_weak_ref_1.c -- test that a weak ref remains weak in output when +// there is a DSO with the same weak ref. + +// Copyright 2010 Free Software Foundation, Inc. +// Written by Doug Kwan <dougkwan@google.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. + +// We test that we correctly deal with a weak reference to from both +// a DSO and a weak reference to the same symbol in an executable. The +// symbol should remains weak. + +// This source is used to build an DSO that references the same weak +// symbol as in a dependent DSO. + +extern void weak_ref (void) __attribute__((weak)); + +void* ptr1 = weak_ref; + +int +main (void) +{ + return 0; +} diff --git a/gold/testsuite/dyn_weak_ref_2.c b/gold/testsuite/dyn_weak_ref_2.c new file mode 100644 index 0000000..8a087a1 --- /dev/null +++ b/gold/testsuite/dyn_weak_ref_2.c @@ -0,0 +1,32 @@ +// dyn_weak_ref_1.c -- test that a weak ref remains weak in output when +// there is a DSO with the same weak ref. + +// Copyright 2010 Free Software Foundation, Inc. +// Written by Doug Kwan <dougkwan@google.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. + +// We test that we correctly deal with a weak reference to from both +// a DSO and a weak reference to the same symbol in an executable. The +// symbol should remains weak. + +// This source is used to build a DSO that contains a weak reference. + +extern void weak_ref (void) __attribute__((weak)); + +void* ptr2 = weak_ref; |