[binutils-gdb] Fix --no-as-needed when shared library is listed twice on the command line.

Cary Coutant ccoutant@sourceware.org
Wed Aug 26 01:39:00 GMT 2015


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4bfacfd359a1f8d026d1a350f56f2f5d70b6cb65

commit 4bfacfd359a1f8d026d1a350f56f2f5d70b6cb65
Author: Cary Coutant <ccoutant@gmail.com>
Date:   Fri Aug 21 12:32:33 2015 -0700

    Fix --no-as-needed when shared library is listed twice on the command line.
    
    When a shared library is listed twice on the command line, the linker
    ignores the second mention. If the first mention is in the scope of
    an --as-needed option, and the second one is under the scope of a
    --no-as-needed option, the --no-as-needed should take effect, but
    doesn't.  This patch keeps track of the objects we've already seen,
    and updates the --as-needed flag so that if a shared object is ever
    seen with --no-as-needed, it will be marked as such.
    
    gold/
    	PR gold/18859
    	* object.cc (Input_objects::add_object): Store objects in a map,
    	indexed by soname; update as-needed flag when necessary.
    	* object.h (Object::clear_as_needed): New method.
    	(Input_objects::so_names_): Change from set to map.

Diff:
---
 gold/ChangeLog |  8 ++++++++
 gold/object.cc | 13 +++++++++++--
 gold/object.h  |  7 ++++++-
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/gold/ChangeLog b/gold/ChangeLog
index ebed52b..fdc70155 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,5 +1,13 @@
 2015-08-25  Cary Coutant  <ccoutant@gmail.com>
 
+	PR gold/18859
+	* object.cc (Input_objects::add_object): Store objects in a map,
+	indexed by soname; update as-needed flag when necessary.
+	* object.h (Object::clear_as_needed): New method.
+	(Input_objects::so_names_): Change from set to map.
+
+2015-08-25  Cary Coutant  <ccoutant@gmail.com>
+
 	PR gold/14746
 	* expression.cc (Expression::Expression_eval_info): Add
 	is_valid_pointer field.
diff --git a/gold/object.cc b/gold/object.cc
index 316f8d4..76d4630 100644
--- a/gold/object.cc
+++ b/gold/object.cc
@@ -2973,11 +2973,20 @@ Input_objects::add_object(Object* obj)
       Dynobj* dynobj = static_cast<Dynobj*>(obj);
       const char* soname = dynobj->soname();
 
-      std::pair<Unordered_set<std::string>::iterator, bool> ins =
-	this->sonames_.insert(soname);
+      Unordered_map<std::string, Object*>::value_type val(soname, obj);
+      std::pair<Unordered_map<std::string, Object*>::iterator, bool> ins =
+	this->sonames_.insert(val);
       if (!ins.second)
 	{
 	  // We have already seen a dynamic object with this soname.
+	  // If any instances of this object on the command line have
+	  // the --no-as-needed flag, make sure the one we keep is
+	  // marked so.
+	  if (!obj->as_needed())
+	    {
+	      gold_assert(ins.first->second != NULL);
+	      ins.first->second->clear_as_needed();
+	    }
 	  return false;
 	}
 
diff --git a/gold/object.h b/gold/object.h
index e8f74ac..f796fb5 100644
--- a/gold/object.h
+++ b/gold/object.h
@@ -731,6 +731,11 @@ class Object
   set_as_needed()
   { this->as_needed_ = true; }
 
+  // Clear flag that this object was linked with --as-needed.
+  void
+  clear_as_needed()
+  { this->as_needed_ = false; }
+
   // Return whether this object was linked with --as-needed.
   bool
   as_needed() const
@@ -2836,7 +2841,7 @@ class Input_objects
   // The list of dynamic objects included in the link.
   Dynobj_list dynobj_list_;
   // SONAMEs that we have seen.
-  Unordered_set<std::string> sonames_;
+  Unordered_map<std::string, Object*> sonames_;
   // Manage cross-references if requested.
   Cref* cref_;
 };



More information about the Binutils-cvs mailing list