aboutsummaryrefslogtreecommitdiff
path: root/gold/symtab.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2008-01-15 23:41:28 +0000
committerIan Lance Taylor <iant@google.com>2008-01-15 23:41:28 +0000
commit091244672e9cb571cb7272d491826f85de871ced (patch)
tree40be47b8e61a974e262595c7aa516f597970f285 /gold/symtab.cc
parent58da7b1b61de1ecfbcae3bf0050e8bb65d3ff547 (diff)
downloadfsf-binutils-gdb-091244672e9cb571cb7272d491826f85de871ced.zip
fsf-binutils-gdb-091244672e9cb571cb7272d491826f85de871ced.tar.gz
fsf-binutils-gdb-091244672e9cb571cb7272d491826f85de871ced.tar.bz2
From Andrew Chatham and Craig Silverstein: Add support for version
scripts.
Diffstat (limited to 'gold/symtab.cc')
-rw-r--r--gold/symtab.cc48
1 files changed, 33 insertions, 15 deletions
diff --git a/gold/symtab.cc b/gold/symtab.cc
index ae8e751..e49178a 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -295,9 +295,10 @@ Symbol::final_value_is_known() const
// Class Symbol_table.
-Symbol_table::Symbol_table(unsigned int count)
+Symbol_table::Symbol_table(unsigned int count,
+ const Version_script_info& version_script)
: saw_undefined_(0), offset_(0), table_(count), namepool_(),
- forwarders_(), commons_(), warnings_()
+ forwarders_(), commons_(), warnings_(), version_script_(version_script)
{
namepool_.reserve(count);
}
@@ -571,6 +572,7 @@ Symbol_table::add_from_object(Object* object,
if (!was_common && ret->is_common())
this->commons_.push_back(ret);
+ ret->set_is_default(def);
return ret;
}
@@ -626,6 +628,31 @@ Symbol_table::add_from_relobj(
// name from the version name. If there are two '@' characters,
// this is the default version.
const char* ver = strchr(name, '@');
+ int namelen = 0;
+ bool def = false;
+
+ if (ver != NULL)
+ {
+ // The symbol name is of the form foo@VERSION or foo@@VERSION
+ namelen = ver - name;
+ ++ver;
+ if (*ver == '@')
+ {
+ def = true;
+ ++ver;
+ }
+ }
+ else if (!version_script_.empty())
+ {
+ // The symbol name did not have a version, but
+ // the version script may assign a version anyway.
+ namelen = strlen(name);
+ def = true;
+ const std::string& version =
+ version_script_.get_symbol_version(name);
+ if (!version.empty())
+ ver = version.c_str();
+ }
Sized_symbol<size>* res;
if (ver == NULL)
@@ -638,17 +665,8 @@ Symbol_table::add_from_relobj(
else
{
Stringpool::Key name_key;
- name = this->namepool_.add_with_length(name, ver - name, true,
+ name = this->namepool_.add_with_length(name, namelen, true,
&name_key);
-
- bool def = false;
- ++ver;
- if (*ver == '@')
- {
- def = true;
- ++ver;
- }
-
Stringpool::Key ver_key;
ver = this->namepool_.add(ver, true, &ver_key);
@@ -1238,7 +1256,7 @@ Symbol_table::do_define_as_constant(
if (sym == NULL)
return NULL;
- gold_assert(version == NULL || oldsym != NULL);
+ gold_assert(version == NULL || version == name || oldsym != NULL);
sym->init(name, value, symsize, type, binding, visibility, nonvis);
if (oldsym == NULL)
@@ -1392,8 +1410,8 @@ Symbol_table::set_dynsym_indexes(const Target* target,
dynpool->add(sym->name(), false, NULL);
// Record any version information.
- if (sym->version() != NULL)
- versions->record_version(this, dynpool, sym);
+ if (sym->version() != NULL)
+ versions->record_version(this, dynpool, sym);
}
}