Index: lto-symtab.c
===================================================================
--- lto-symtab.c        (revision 160529)
+++ lto-symtab.c        (working copy)
@@ -530,11 +530,21 @@
     return;

 found:
-  if (TREE_CODE (prevailing->decl) == VAR_DECL
-      && TREE_READONLY (prevailing->decl))
+  /* If current lto files represent the whole program,
+    it is correct to use LDPR_PREVALING_DEF_IRONLY.
+    If current lto files are part of whole program, internal
+    resolver doesn't know if it is LDPR_PREVAILING_DEF
+    or LDPR_PREVAILING_DEF_IRONLY. Use IRONLY conforms to
+    using -fwhole-program. Otherwise, it doesn't
+    matter using either LDPR_PREVAILING_DEF or
+    LDPR_PREVAILING_DEF_IRONLY
+
+    FIXME: above workaround due to gold plugin makes some
+    variables IRONLY, which are indeed PREVAILING_DEF in
+    resolution file. These variables still need manual
+    externally_visible attribute
+    */
     prevailing->resolution = LDPR_PREVAILING_DEF_IRONLY;
-  else
-    prevailing->resolution = LDPR_PREVAILING_DEF;
 }

 /* Merge all decls in the symbol table chain to the prevailing decl and
@@ -698,6 +708,25 @@
       && TREE_CODE (prevailing->decl) != VAR_DECL)
     prevailing->next = NULL;

+
+  /* Add externally_visible attribute for declaration of LDPR_PREVAILING_DEF */
+  if (flag_whole_program)
+    {
+      if (prevailing->resolution == LDPR_PREVAILING_DEF)
+        {
+          if (TREE_CODE (prevailing->decl) == FUNCTION_DECL)
+            prevailing->node->local.externally_visible = true;
+          else
+            prevailing->vnode->externally_visible = true;
+        }
+      else if (prevailing->resolution == LDPR_PREVAILING_DEF_IRONLY)
+        {
+          if (TREE_CODE (prevailing->decl) == FUNCTION_DECL)
+            prevailing->node->local.externally_visible = false;
+          else
+            prevailing->vnode->externally_visible = false;
+        }
+    }
   return 1;
 }

Index: ipa.c
===================================================================
--- ipa.c       (revision 160529)
+++ ipa.c       (working copy)
@@ -665,13 +665,12 @@
        }
       gcc_assert ((!DECL_WEAK (node->decl) && !DECL_COMDAT (node->decl))
                  || TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl));
-      if (cgraph_externally_visible_p (node, whole_program))
+      if (!node->local.externally_visible
+          && cgraph_externally_visible_p (node, whole_program))
         {
          gcc_assert (!node->global.inlined_to);
          node->local.externally_visible = true;
        }
-      else
-       node->local.externally_visible = false;
       if (!node->local.externally_visible && node->analyzed
          && !DECL_EXTERNAL (node->decl))
        {
@@ -721,7 +720,8 @@
     {
       if (!vnode->finalized)
         continue;
-      if (vnode->needed
+      if (!vnode->externally_visible
+          && vnode->needed
          && (DECL_COMDAT (vnode->decl) || TREE_PUBLIC (vnode->decl))
          && (!whole_program
              /* We can privatize comdat readonly variables whose address is not taken,
@@ -732,8 +732,6 @@
              || lookup_attribute ("externally_visible",
                                   DECL_ATTRIBUTES (vnode->decl))))
        vnode->externally_visible = true;
-      else
-        vnode->externally_visible = false;
       if (!vnode->externally_visible)
        {
          gcc_assert (whole_program || !TREE_PUBLIC (vnode->decl));
