From: Cary Coutant Date: Fri, 21 Aug 2015 19:32:33 +0000 (-0700) Subject: Fix --no-as-needed when shared library is listed twice on the command line. X-Git-Tag: users/ARM/embedded-binutils-2_26-branch-2016q1~835 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4bfacfd359a1f8d026d1a350f56f2f5d70b6cb65;p=external%2Fbinutils.git 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 --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 + 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 + 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(obj); const char* soname = dynobj->soname(); - std::pair::iterator, bool> ins = - this->sonames_.insert(soname); + Unordered_map::value_type val(soname, obj); + std::pair::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 sonames_; + Unordered_map sonames_; // Manage cross-references if requested. Cref* cref_; };