summaryrefslogtreecommitdiff
path: root/gold/resolve.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2008-05-08 18:44:33 +0000
committerIan Lance Taylor <ian@airs.com>2008-05-08 18:44:33 +0000
commit75517b77b595b05bd37bf337c1fb23557efbf4bc (patch)
treeb78003103d3e1f937d66719f1a8e2e1c18659af7 /gold/resolve.cc
parente7fc76dd0f612f4a10f36e14b3d576396bc3833f (diff)
* symtab.c (Symbol::init_base_output_data): Add version
parameter. Change all callers. (Symbol::init_base_output_segment): Likewise. (Symbol::init_base_constant): Likewise. (Symbol::init_base_undefined): Likewise. (Sized_symbol::init_output_data): Likewise. (Sized_symbol::init_output_segment): Likewise. (Sized_symbol::init_constant): Likewise. (Sized_symbol::init_undefined): Likewise. (Symbol_table::do_define_in_output_data): If the new symbol has a version, mark it as the default. (Symbol_table::do_define_in_output_segment): Likewise. (Symbol_table::do_define_as_constant): Likewise. * symtab.h (class Symbol): Update declarations. (class Sized_symbol): Likewise. * resolve.cc (Symbol::override_version): New function. (Symbol::override_base: Call override_version. (Symbol::override_base_with_special): Likewise. * testsuite/ver_script_8.script: New file. * testsuite/Makefile.am (check_PROGRAMS): Add ver_test_8. (ver_test_8_SOURCES, ver_test_8_DEPENDENCIES): Define. (ver_test_8_LDFLAGS, ver_test_8_LDADD): Define. (ver_test_8_1.so, ver_test_8_2.so): New targets.
Diffstat (limited to 'gold/resolve.cc')
-rw-r--r--gold/resolve.cc43
1 files changed, 32 insertions, 11 deletions
diff --git a/gold/resolve.cc b/gold/resolve.cc
index 291bca6967..d564aed19e 100644
--- a/gold/resolve.cc
+++ b/gold/resolve.cc
@@ -32,6 +32,36 @@ namespace gold
// Symbol methods used in this file.
+// This symbol is being overridden by another symbol whose version is
+// VERSION. Update the VERSION_ field accordingly.
+
+inline void
+Symbol::override_version(const char* version)
+{
+ if (version == NULL)
+ {
+ // This is the case where this symbol is NAME/VERSION, and the
+ // version was not marked as hidden. That makes it the default
+ // version, so we create NAME/NULL. Later we see another symbol
+ // NAME/NULL, and that symbol is overriding this one. In this
+ // case, since NAME/VERSION is the default, we make NAME/NULL
+ // override NAME/VERSION as well. They are already the same
+ // Symbol structure. Setting the VERSION_ field to NULL ensures
+ // that it will be output with the correct, empty, version.
+ this->version_ = version;
+ }
+ else
+ {
+ // This is the case where this symbol is NAME/VERSION_ONE, and
+ // now we see NAME/VERSION_TWO, and NAME/VERSION_TWO is
+ // overriding NAME. If VERSION_ONE and VERSION_TWO are
+ // different, then this can only happen when VERSION_ONE is NULL
+ // and VERSION_TWO is not hidden.
+ gold_assert(this->version_ == version || this->version_ == NULL);
+ this->version_ = version;
+ }
+}
+
// Override the fields in Symbol.
template<int size, bool big_endian>
@@ -42,11 +72,7 @@ Symbol::override_base(const elfcpp::Sym<size, big_endian>& sym,
{
gold_assert(this->source_ == FROM_OBJECT);
this->u_.from_object.object = object;
- if (version != NULL && this->version() != version)
- {
- gold_assert(this->version() == NULL);
- this->version_ = version;
- }
+ this->override_version(version);
this->u_.from_object.shndx = st_shndx;
this->is_ordinary_shndx_ = is_ordinary;
this->type_ = sym.get_st_type();
@@ -673,12 +699,7 @@ Symbol::override_base_with_special(const Symbol* from)
break;
}
- if (from->version_ != NULL && this->version_ != from->version_)
- {
- gold_assert(this->version_ == NULL);
- this->version_ = from->version_;
- }
-
+ this->override_version(from->version_);
this->type_ = from->type_;
this->binding_ = from->binding_;
this->visibility_ = from->visibility_;