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.
This commit is contained in:
Cary Coutant
2015-08-21 12:32:33 -07:00
parent 1757d35c8a
commit 4bfacfd359
3 changed files with 25 additions and 3 deletions

View File

@@ -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;
}