[GOLD] --as-needed change wrt undefined weak symbols
Alan Modra
amodra@gmail.com
Wed Mar 20 00:26:00 GMT 2013
On Tue, Mar 19, 2013 at 01:41:31PM -0700, Ian Lance Taylor wrote:
> On Mon, Mar 18, 2013 at 7:34 PM, Alan Modra <amodra@gmail.com> wrote:
> > On Mon, Mar 18, 2013 at 08:15:55AM -0700, Ian Lance Taylor wrote:
> >> We can build a
> >> temporary vector of symbols with version != NULL for which that
> >> condition is not true, and then walk that vector in the second loop.
> >> There won't be many entries in it.
> >
> > Well, OK, but I wonder whether it is really worth doing? Sometimes
> > having two small loops is much better than having one large one.
>
> Yes, but there are executables here with tens of thousands of dynamic
> symbols, none of which are weak.
>
> > * symtab.h (Symbol::override_version): Make public.
> > * 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 is OK.
When compiling with a different gcc and options (previously I used
-fno-inline), I hit
...symtab.cc:2426: undefined reference to `gold::Symbol::override_version(char const*)'
So I'm committing this slightly different patch.
* 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.
Index: gold/symtab.h
===================================================================
RCS file: /cvs/src/src/gold/symtab.h,v
retrieving revision 1.129
diff -u -p -r1.129 symtab.h
--- gold/symtab.h 10 Mar 2013 23:08:18 -0000 1.129
+++ gold/symtab.h 19 Mar 2013 22:33:39 -0000
@@ -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.
Index: gold/symtab.cc
===================================================================
RCS file: /cvs/src/src/gold/symtab.cc,v
retrieving revision 1.169
diff -u -p -r1.169 symtab.cc
--- gold/symtab.cc 10 Mar 2013 23:08:18 -0000 1.169
+++ gold/symtab.cc 19 Mar 2013 22:33:40 -0000
@@ -2368,6 +2368,8 @@ Symbol_table::set_dynsym_indexes(unsigne
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(unsigne
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);
--
Alan Modra
Australia Development Lab, IBM
More information about the Binutils
mailing list