2009-10-16 Doug Kwan <dougkwan@google.com>

* dynobj.cc (Versions::Versions): Initialize version_script_.
	Only insert base version symbol definition for a shared object
	if version script defines any version versions.
	(Versions::define_base_version): New method definition.
	(Versions::add_def): Check that base version is not needed.
	(Versions::add_need): Define base version lazily.
	* dynobj.h (Versions::define_base_version): New method declaration.
	(Versions::needs_base_version_): New data member declaration.
	* testsuite/Makefile.am (check_SCRIPTS): Add no_version_test.sh
	(check_DATA): Add no_version_test.stdout.
	(libno_version_test.so, no_version_test.o no_version_test.stdout):
	New make rules.
	* testsuite/Makefile.in: Regenerate.
	* testsuite/no_version_test.c: New file.
	* testsuite/no_version_test.sh: Ditto.
This commit is contained in:
Doug Kwan 2009-10-16 19:11:32 +00:00
parent 0a8d1bde17
commit c5617f2fb6
7 changed files with 170 additions and 19 deletions

View File

@ -1,3 +1,21 @@
2009-10-16 Doug Kwan <dougkwan@google.com>
* dynobj.cc (Versions::Versions): Initialize version_script_.
Only insert base version symbol definition for a shared object
if version script defines any version versions.
(Versions::define_base_version): New method definition.
(Versions::add_def): Check that base version is not needed.
(Versions::add_need): Define base version lazily.
* dynobj.h (Versions::define_base_version): New method declaration.
(Versions::needs_base_version_): New data member declaration.
* testsuite/Makefile.am (check_SCRIPTS): Add no_version_test.sh
(check_DATA): Add no_version_test.stdout.
(libno_version_test.so, no_version_test.o no_version_test.stdout):
New make rules.
* testsuite/Makefile.in: Regenerate.
* testsuite/no_version_test.c: New file.
* testsuite/no_version_test.sh: Ditto.
2009-10-16 Doug Kwan <dougkwan@google.com>
* expression.cc (class Segment_start_expression): New class definition.

View File

@ -1300,27 +1300,18 @@ Verneed::write(const Stringpool* dynpool, bool is_last,
Versions::Versions(const Version_script_info& version_script,
Stringpool* dynpool)
: defs_(), needs_(), version_table_(),
is_finalized_(false), version_script_(version_script)
is_finalized_(false), version_script_(version_script),
needs_base_version_(parameters->options().shared())
{
// We always need a base version, so define that first. Nothing
// explicitly declares itself as part of base, so it doesn't need to
// be in version_table_.
if (parameters->options().shared())
{
const char* name = parameters->options().soname();
if (name == NULL)
name = parameters->options().output_file_name();
name = dynpool->add(name, false, NULL);
Verdef* vdbase = new Verdef(name, std::vector<std::string>(),
true, false, true);
this->defs_.push_back(vdbase);
}
if (!this->version_script_.empty())
{
// Parse the version script, and insert each declared version into
// defs_ and version_table_.
std::vector<std::string> versions = this->version_script_.get_versions();
if (this->needs_base_version_ && !versions.empty())
this->define_base_version(dynpool);
for (size_t k = 0; k < versions.size(); ++k)
{
Stringpool::Key version_key;
@ -1350,6 +1341,28 @@ Versions::~Versions()
delete *p;
}
// Define the base version of a shared library. The base version definition
// must be the first entry in defs_. We insert it lazily so that defs_ is
// empty if no symbol versioning is used. Then layout can just drop the
// version sections.
void
Versions::define_base_version(Stringpool* dynpool)
{
// If we do any versioning at all, we always need a base version, so
// define that first. Nothing explicitly declares itself as part of base,
// so it doesn't need to be in version_table_.
gold_assert(this->defs_.empty());
const char* name = parameters->options().soname();
if (name == NULL)
name = parameters->options().output_file_name();
name = dynpool->add(name, false, NULL);
Verdef* vdbase = new Verdef(name, std::vector<std::string>(),
true, false, true);
this->defs_.push_back(vdbase);
this->needs_base_version_ = false;
}
// Return the dynamic object which a symbol refers to.
Dynobj*
@ -1421,7 +1434,10 @@ Versions::add_def(const Symbol* sym, const char* version,
if (parameters->options().shared())
gold_error(_("symbol %s has undefined version %s"),
sym->demangled_name().c_str(), version);
else
// We only insert a base version for shared library.
gold_assert(!this->needs_base_version_);
// When creating a regular executable, automatically define
// a new version.
Verdef* vd = new Verdef(version, std::vector<std::string>(),
@ -1468,6 +1484,10 @@ Versions::add_need(Stringpool* dynpool, const char* filename, const char* name,
if (vn == NULL)
{
// Create base version definition lazily for shared library.
if (this->needs_base_version_)
this->define_base_version(dynpool);
// We have a new filename.
vn = new Verneed(filename);
this->needs_.push_back(vn);

View File

@ -584,6 +584,10 @@ class Versions
version_index(const Symbol_table*, const Stringpool*,
const Symbol* sym) const;
// Define the base version of a shared library.
void
define_base_version(Stringpool* dynpool);
// We keep a hash table mapping canonicalized name/version pairs to
// a version base.
typedef std::pair<Stringpool::Key, Stringpool::Key> Key;
@ -616,6 +620,9 @@ class Versions
bool is_finalized_;
// Contents of --version-script, if passed, or NULL.
const Version_script_info& version_script_;
// Whether we need to insert a base version. This is only used for
// shared libaries and is cleared when the base version is defined.
bool needs_base_version_;
};
} // End namespace gold.

View File

@ -1249,6 +1249,20 @@ alt/searched_file_test_lib.a: searched_file_test_lib.o
test -d alt || mkdir -p alt
$(TEST_AR) rc $@ $^
# Test that no .gnu.version sections are created when
# symbol versioning is not used.
check_SCRIPTS += no_version_test.sh
check_DATA += no_version_test.stdout
MOSTLYCLEANFILES += libno_version_test.so no_version_test.stdout
# We invoke the linker directly since gcc may include additional objects that
# uses symbol versioning.
libno_version_test.so: no_version_test.o gcctestdir/ld
gcctestdir/ld -shared -o $@ no_version_test.o
no_version_test.o: no_version_test.c
$(COMPILE) -o $@ -c -fPIC $<
no_version_test.stdout: libno_version_test.so
$(TEST_OBJDUMP) -h $< > $@
endif GCC
endif NATIVE_LINKER

View File

@ -354,14 +354,19 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
# referenced by a shared library.
# Test -retain-symbols-file.
# Test that no .gnu.version sections are created when
# symbol versioning is not used.
@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@ retain_symbols_file_test.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ no_version_test.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@ hidden_test.err \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ retain_symbols_file_test.stdout
@GCC_TRUE@@NATIVE_LINKER_TRUE@ retain_symbols_file_test.stdout \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ no_version_test.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 \
@ -373,7 +378,9 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ retain_symbols_file_test.stdout \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ searched_file_test \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ searched_file_test_lib.o \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ alt/searched_file_test_lib.a
@GCC_TRUE@@NATIVE_LINKER_TRUE@ alt/searched_file_test_lib.a \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ libno_version_test.so \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ no_version_test.stdout
@GCC_TRUE@@MCMODEL_MEDIUM_TRUE@@NATIVE_LINKER_TRUE@am__append_30 = large
@GCC_FALSE@large_DEPENDENCIES = libgoldtest.a ../libgold.a \
@GCC_FALSE@ ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \
@ -3104,6 +3111,14 @@ uninstall-am:
@GCC_TRUE@@NATIVE_LINKER_TRUE@alt/searched_file_test_lib.a: searched_file_test_lib.o
@GCC_TRUE@@NATIVE_LINKER_TRUE@ test -d alt || mkdir -p alt
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_AR) rc $@ $^
# We invoke the linker directly since gcc may include additional objects that
# uses symbol versioning.
@GCC_TRUE@@NATIVE_LINKER_TRUE@libno_version_test.so: no_version_test.o gcctestdir/ld
@GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir/ld -shared -o $@ no_version_test.o
@GCC_TRUE@@NATIVE_LINKER_TRUE@no_version_test.o: no_version_test.c
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(COMPILE) -o $@ -c -fPIC $<
@GCC_TRUE@@NATIVE_LINKER_TRUE@no_version_test.stdout: libno_version_test.so
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_OBJDUMP) -h $< > $@
@DEFAULT_TARGET_I386_TRUE@split_i386_1.o: split_i386_1.s
@DEFAULT_TARGET_I386_TRUE@ $(TEST_AS) -o $@ $<
@DEFAULT_TARGET_I386_TRUE@split_i386_2.o: split_i386_2.s

View File

@ -0,0 +1,32 @@
// ver_no_default.c -- a test case for gold
// Copyright 2009 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 should not create any .gnu.version sections if symbol versioning
// is not used.
extern int the_answer(void);
int
the_answer(void)
{
return 42;
}

View File

@ -0,0 +1,45 @@
#!/bin/sh
# no_version_test.sh -- test that .gnu.version* sections are not created
# in a shared object when symbol versioning is not used.
# Copyright 2009 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 file goes with no_version_test.c, a C source file
# linked with option -shared -nostdlib. We run objdump on
# the resulting executable and check that .gnu.version* sections
# are not created.
check()
{
file=$1
found=`egrep "\.gnu\.version.*" $file`
if test -n "$found"; then
echo "These section should not be in $file:"
echo "$found"
exit 1
fi
}
check "no_version_test.stdout"
exit 0