[GOLD] --as-needed change wrt undefined weak symbols

Alan Modra amodra@gmail.com
Mon Mar 18 08:16:00 GMT 2013


On Mon, Mar 18, 2013 at 06:24:17PM +1030, Alan Modra wrote:
> On Mon, Mar 18, 2013 at 01:11:30PM +1030, Alan Modra wrote:
> > http://sourceware.org/ml/binutils/2013-01/msg00188.html
> 
> The corresponding gold change.  Not quite so simple as just testing
> whether the reference is strong before setting is_needed, since we
> can't have symbol versions coming from a non-loaded shared lib.  If
> you do, ld.so segfaults.  OK to apply?

That was silly, we've just made a vector of dynamic symbols, so no
need to traverse the whole symbol table.

	* 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.

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	18 Mar 2013 08:13:00 -0000
@@ -121,6 +121,10 @@ class Symbol
   version() const
   { return this->version_; }
 
+  // Override symbol version.
+  void
+  override_version(const char* version);
+
   // 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.
@@ -872,10 +876,6 @@ class Symbol
   void
   override_base_with_special(const Symbol* from);
 
-  // Override symbol version.
-  void
-  override_version(const char* version);
-
   // Allocate a common symbol by giving it a location in the output
   // file.
   void
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	18 Mar 2013 08:13:01 -0000
@@ -2387,18 +2387,35 @@ 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.
+  for (std::vector<Symbol*>::iterator p = syms->begin();
+       p != syms->end();
+       ++p)
+    {
+      Symbol* sym = *p;
+
+      if (sym->version() != NULL)
+	{
+	  if (!sym->is_from_dynobj()
+	      || !sym->object()->as_needed()
+	      || sym->object()->is_needed())
+	    versions->record_version(this, dynpool, sym);
+	  else
+	    sym->override_version(NULL);
+	}
+    }
+
   // 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