Fix problem where undef can fail to trigger archive rescan.
authorStephen Crane <sjc@immunant.com>
Fri, 1 Dec 2017 20:10:02 +0000 (12:10 -0800)
committerCary Coutant <ccoutant@gmail.com>
Fri, 1 Dec 2017 20:10:02 +0000 (12:10 -0800)
If a shared library contains an undefined symbol and LTO adds
a new reference to that same undefined symbol, the reference in the new
object added by the plugin would not trigger a rescan of the archive
containing the symbol.

2017-11-17  Stephen Crane  <sjc@immunant.com>

gold/
PR gold/22448
* symtab.cc (Symbol_table::add_from_object): Only rescan for
undefined symbols in regular, not dynamic, objects.

gold/ChangeLog
gold/symtab.cc

index 43a3d70e9f6845b6c3dc0a84dce8a6df9f0c7ab2..e4b890e5f3af13a7f1eb08733bc55a1e324a7bc2 100644 (file)
@@ -1,3 +1,9 @@
+2017-11-17  Stephen Crane  <sjc@immunant.com>
+
+       PR gold/22448
+       * symtab.cc (Symbol_table::add_from_object): Only rescan for
+       undefined symbols in regular, not dynamic, objects.
+
 2017-11-30  Peter Smith  <peter.smith@linaro.org>
 
        PR gold/20765
index d1f71e02d0edadb490b1b5fc51a46fba8bd56b35..e50b42c43b7f3049dd4fe21f5b69b3b9d98d3320 100644 (file)
@@ -990,7 +990,7 @@ Symbol_table::add_from_object(Object* object,
   // ins.second: true if new entry was inserted, false if not.
 
   Sized_symbol<size>* ret;
-  bool was_undefined;
+  bool was_undefined_in_reg;
   bool was_common;
   if (!ins.second)
     {
@@ -998,7 +998,7 @@ Symbol_table::add_from_object(Object* object,
       ret = this->get_sized_symbol<size>(ins.first->second);
       gold_assert(ret != NULL);
 
-      was_undefined = ret->is_undefined();
+      was_undefined_in_reg = ret->is_undefined() && ret->in_reg();
       // Commons from plugins are just placeholders.
       was_common = ret->is_common() && ret->object()->pluginobj() == NULL;
 
@@ -1049,7 +1049,7 @@ Symbol_table::add_from_object(Object* object,
          // it, then change it to NAME/VERSION.
          ret = this->get_sized_symbol<size>(insdefault.first->second);
 
-         was_undefined = ret->is_undefined();
+         was_undefined_in_reg = ret->is_undefined() && ret->in_reg();
          // Commons from plugins are just placeholders.
          was_common = ret->is_common() && ret->object()->pluginobj() == NULL;
 
@@ -1061,7 +1061,7 @@ Symbol_table::add_from_object(Object* object,
        }
       else
        {
-         was_undefined = false;
+         was_undefined_in_reg = false;
          was_common = false;
 
          Sized_target<size, big_endian>* target =
@@ -1105,9 +1105,10 @@ Symbol_table::add_from_object(Object* object,
        ret->set_is_default();
     }
 
-  // Record every time we see a new undefined symbol, to speed up
-  // archive groups.
-  if (!was_undefined && ret->is_undefined())
+  // Record every time we see a new undefined symbol, to speed up archive
+  // groups. We only care about symbols undefined in regular objects here
+  // because undefined symbols only in dynamic objects should't trigger rescans.
+  if (!was_undefined_in_reg && ret->is_undefined() && ret->in_reg())
     {
       ++this->saw_undefined_;
       if (parameters->options().has_plugins())