* symtab.h (Symbol::clear_version): New function.

* symtab.cc (Symbol_table::set_dynsym_indexes): Don't set object
	is_needed by weak references.  Clear version for symbols defined
	in as-needed objects that are not needed.
This commit is contained in:
Alan Modra 2013-03-20 00:25:28 +00:00
parent e5e21fa801
commit 32e2b61d0b
3 changed files with 45 additions and 7 deletions

View file

@ -1,3 +1,10 @@
2013-03-20 Alan Modra <amodra@gmail.com>
* symtab.h (Symbol::clear_version): New function.
* symtab.cc (Symbol_table::set_dynsym_indexes): Don't set object
is_needed by weak references. Clear version for symbols defined
in as-needed objects that are not needed.
2013-03-15 Alan Modra <amodra@gmail.com>
* powerpc.cc (Target_powerpc::Scan::reloc_needs_plt_for_ifunc): Make

View file

@ -2368,6 +2368,8 @@ Symbol_table::set_dynsym_indexes(unsigned int index,
Stringpool* dynpool,
Versions* versions)
{
std::vector<Symbol*> as_needed_sym;
for (Symbol_table_type::iterator p = this->table_.begin();
p != this->table_.end();
++p)
@ -2387,18 +2389,43 @@ Symbol_table::set_dynsym_indexes(unsigned int index,
syms->push_back(sym);
dynpool->add(sym->name(), false, NULL);
// Record any version information.
if (sym->version() != NULL)
versions->record_version(this, dynpool, sym);
// If the symbol is defined in a dynamic object and is
// referenced in a regular object, then mark the dynamic
// object as needed. This is used to implement --as-needed.
if (sym->is_from_dynobj() && sym->in_reg())
// referenced strongly in a regular object, then mark the
// dynamic object as needed. This is used to implement
// --as-needed.
if (sym->is_from_dynobj()
&& sym->in_reg()
&& !sym->is_undef_binding_weak())
sym->object()->set_is_needed();
// Record any version information, except those from
// as-needed libraries not seen to be needed. Note that the
// is_needed state for such libraries can change in this loop.
if (sym->version() != NULL)
{
if (!sym->is_from_dynobj()
|| !sym->object()->as_needed()
|| sym->object()->is_needed())
versions->record_version(this, dynpool, sym);
else
as_needed_sym.push_back(sym);
}
}
}
// Process version information for symbols from as-needed libraries.
for (std::vector<Symbol*>::iterator p = as_needed_sym.begin();
p != as_needed_sym.end();
++p)
{
Symbol* sym = *p;
if (sym->object()->is_needed())
versions->record_version(this, dynpool, sym);
else
sym->clear_version();
}
// Finish up the versions. In some cases this may add new dynamic
// symbols.
index = versions->finalize(this, index, syms);

View file

@ -121,6 +121,10 @@ class Symbol
version() const
{ return this->version_; }
void
clear_version()
{ this->version_ = NULL; }
// Return whether this version is the default for this symbol name
// (eg, "foo@@V2" is a default version; "foo@V1" is not). Only
// meaningful for versioned symbols.