]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
PR24567, assertion failure in ldlang.c:6868 when compiling with -flto
authorAlan Modra <amodra@gmail.com>
Fri, 17 May 2019 09:39:42 +0000 (19:09 +0930)
committerAlan Modra <amodra@gmail.com>
Fri, 17 May 2019 14:21:23 +0000 (23:51 +0930)
As the existing comment said: "a common ought to be overridden by a
def in a -flto object".  This patch makes the code actually do that,
rather than allowing a normal object file common to override a -flto
defined symbol.

PR 24567
* plugin.c (plugin_notice): Do not let a common symbol override
a non-common definition in IR.

(cherry picked from commit af4fa23fba220c1b26bb3c8a7996b406dcc181cc)

ld/ChangeLog
ld/plugin.c

index 6add6bb0314bb0b1bf307d1a67e776ce76611ac8..5ac2362e1b207406ec8c77e75680cd0404c8e6b9 100644 (file)
@@ -1,3 +1,9 @@
+2019-05-17  Alan Modra  <amodra@gmail.com>
+
+       PR 24567
+       * plugin.c (plugin_notice): Do not let a common symbol override
+       a non-common definition in IR.
+
 2019-04-18  Tamar Christina  <tamar.christina@arm.com>
 
        Backport from mainline.
index ea1a7f70645d339d8346b365f4b2a20f2686519d..e4e781c2a89a25401da8ebbef3e583988968f381 100644 (file)
@@ -1316,30 +1316,36 @@ plugin_notice (struct bfd_link_info *info,
          ref = TRUE;
        }
 
-      /* Otherwise, it must be a new def.  */
-      else
+
+      /* A common symbol should be merged with other commons or
+        defs with the same name.  In particular, a common ought
+        to be overridden by a def in a -flto object.  In that
+        sense a common is also a ref.  */
+      else if (bfd_is_com_section (section))
        {
-         /* Ensure any symbol defined in an IR dummy BFD takes on a
-            new value from a real BFD.  Weak symbols are not normally
-            overridden by a new weak definition, and strong symbols
-            will normally cause multiple definition errors.  Avoid
-            this by making the symbol appear to be undefined.  */
-         if (((h->type == bfd_link_hash_defweak
-               || h->type == bfd_link_hash_defined)
-              && is_ir_dummy_bfd (sym_bfd = h->u.def.section->owner))
-             || (h->type == bfd_link_hash_common
-                 && is_ir_dummy_bfd (sym_bfd = h->u.c.p->section->owner)))
+         if (h->type == bfd_link_hash_common
+             && is_ir_dummy_bfd (sym_bfd = h->u.c.p->section->owner))
            {
              h->type = bfd_link_hash_undefweak;
              h->u.undef.abfd = sym_bfd;
            }
+         ref = TRUE;
+       }
 
-         /* A common symbol should be merged with other commons or
-            defs with the same name.  In particular, a common ought
-            to be overridden by a def in a -flto object.  In that
-            sense a common is also a ref.  */
-         if (bfd_is_com_section (section))
-           ref = TRUE;
+      /* Otherwise, it must be a new def.
+        Ensure any symbol defined in an IR dummy BFD takes on a
+        new value from a real BFD.  Weak symbols are not normally
+        overridden by a new weak definition, and strong symbols
+        will normally cause multiple definition errors.  Avoid
+        this by making the symbol appear to be undefined.  */
+      else if (((h->type == bfd_link_hash_defweak
+                || h->type == bfd_link_hash_defined)
+               && is_ir_dummy_bfd (sym_bfd = h->u.def.section->owner))
+              || (h->type == bfd_link_hash_common
+                  && is_ir_dummy_bfd (sym_bfd = h->u.c.p->section->owner)))
+       {
+         h->type = bfd_link_hash_undefweak;
+         h->u.undef.abfd = sym_bfd;
        }
 
       if (ref)