diff options
author | Alan Modra <amodra@gmail.com> | 2013-03-20 00:25:28 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2013-03-20 00:25:28 +0000 |
commit | 32e2b61d0baceacdd0ae791adc12bf829499be96 (patch) | |
tree | 4575643f5e20face4fa00293ef4251cef3abee57 /gold | |
parent | e5e21fa801ffcbe8204f8287bb968bcf4af6b43d (diff) | |
download | gdb-32e2b61d0baceacdd0ae791adc12bf829499be96.zip gdb-32e2b61d0baceacdd0ae791adc12bf829499be96.tar.gz gdb-32e2b61d0baceacdd0ae791adc12bf829499be96.tar.bz2 |
* 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.
Diffstat (limited to 'gold')
-rw-r--r-- | gold/ChangeLog | 7 | ||||
-rw-r--r-- | gold/symtab.cc | 41 | ||||
-rw-r--r-- | gold/symtab.h | 4 |
3 files changed, 45 insertions, 7 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index ee6b268..8c3b1a2 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -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 diff --git a/gold/symtab.cc b/gold/symtab.cc index 1fad11e..17a0f55 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -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); diff --git a/gold/symtab.h b/gold/symtab.h index 040be95..689d99f 100644 --- a/gold/symtab.h +++ b/gold/symtab.h @@ -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. |