Skip an archive element if not added by linker
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 25 May 2016 15:40:52 +0000 (08:40 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 25 May 2016 15:41:05 +0000 (08:41 -0700)
During archive rescan to resolve symbol references for files added by
LTO, linker add_archive_element callback is called to check if an
archive element should added.  After all IR symbols have been claimed,
linker won't claim new IR symbols and shouldn't add the LTO archive
element.  This patch updates linker add_archive_element callback to
return FALSE when seeing an LTO archive element during rescan and
changes ELF linker to skip such archive element.

bfd/

PR ld/20103
* cofflink.c (coff_link_check_archive_element): Return TRUE if
linker add_archive_element callback returns FALSE.
* ecoff.c (ecoff_link_check_archive_element): Likewise.
* elf64-ia64-vms.c (elf64_vms_link_add_archive_symbols): Skip
archive element if linker add_archive_element callback returns
FALSE.
* elflink.c (elf_link_add_archive_symbols): Likewise.
* pdp11.c (aout_link_check_ar_symbols): Likewise.
* vms-alpha.c (alpha_vms_link_add_archive_symbols): Likewise.
* xcofflink.c (xcoff_link_check_dynamic_ar_symbols): Likewise.
(xcoff_link_check_ar_symbols): Likewise.

ld/

PR ld/20103
* ldmain.c (add_archive_element): Don't claim new IR symbols
after all IR symbols have been claimed.
* plugin.c (plugin_call_claim_file): Remove no_more_claiming
check.
* testsuite/ld-plugin/lto.exp (pr20103): New proc.
Run PR ld/20103 tests.
* testsuite/ld-plugin/pr20103a.c: New file.
* testsuite/ld-plugin/pr20103b.c: Likewise.
* testsuite/ld-plugin/pr20103c.c: Likewise.

15 files changed:
bfd/ChangeLog
bfd/cofflink.c
bfd/ecoff.c
bfd/elf64-ia64-vms.c
bfd/elflink.c
bfd/pdp11.c
bfd/vms-alpha.c
bfd/xcofflink.c
ld/ChangeLog
ld/ldmain.c
ld/plugin.c
ld/testsuite/ld-plugin/lto.exp
ld/testsuite/ld-plugin/pr20103a.c [new file with mode: 0644]
ld/testsuite/ld-plugin/pr20103b.c [new file with mode: 0644]
ld/testsuite/ld-plugin/pr20103c.c [new file with mode: 0644]

index 1be092bc52f93928b8e1f743f3887ef3973248f0..f01cf1e469a4181815e52d2dbedf9d34aa5cc6b3 100644 (file)
@@ -1,3 +1,18 @@
+2016-05-25  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/20103
+       * cofflink.c (coff_link_check_archive_element): Return TRUE if
+       linker add_archive_element callback returns FALSE.
+       * ecoff.c (ecoff_link_check_archive_element): Likewise.
+       * elf64-ia64-vms.c (elf64_vms_link_add_archive_symbols): Skip
+       archive element if linker add_archive_element callback returns
+       FALSE.
+       * elflink.c (elf_link_add_archive_symbols): Likewise.
+       * pdp11.c (aout_link_check_ar_symbols): Likewise.
+       * vms-alpha.c (alpha_vms_link_add_archive_symbols): Likewise.
+       * xcofflink.c (xcoff_link_check_dynamic_ar_symbols): Likewise.
+       (xcoff_link_check_ar_symbols): Likewise.
+
 2016-05-24  Maciej W. Rozycki  <macro@imgtec.com>
 
        * elfxx-mips.c (_bfd_mips_elf_relocate_section)
index 4756fc3070f69bd202e59032ddeccd5ffd95a285..b8a85b0c4317f72dcbb9264caac51c9004c71c0c 100644 (file)
@@ -212,8 +212,9 @@ coff_link_check_archive_element (bfd *abfd,
   if (h->type != bfd_link_hash_undefined)
     return TRUE;
 
+  /* Include this element?  */
   if (!(*info->callbacks->add_archive_element) (info, abfd, name, &abfd))
-    return FALSE;
+    return TRUE;
   *pneeded = TRUE;
 
   return coff_link_add_object_symbols (abfd, info);
index 031abdfef1427de6ff814e7c3f34b9c0a977522f..d618572eaf7e4d6ccb80f86356e85a66b35a042b 100644 (file)
@@ -3544,9 +3544,9 @@ ecoff_link_check_archive_element (bfd *abfd,
   if (h->type != bfd_link_hash_undefined)
     return TRUE;
 
-  /* Include this element.  */
+  /* Include this element?  */
   if (!(*info->callbacks->add_archive_element) (info, abfd, name, &abfd))
-    return FALSE;
+    return TRUE;
   *pneeded = TRUE;
 
   return ecoff_link_add_object_symbols (abfd, info);
index 760e1dbb34877091eac5928a2bab70dcafa15f83..44826461adea6453781a13ea664a2a1f6814d884 100644 (file)
@@ -5361,7 +5361,7 @@ elf64_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
         to include it.  We don't need to check anything.  */
       if (! (*info->callbacks->add_archive_element) (info, element,
                                                      h->root.string, &element))
-       return FALSE;
+       continue;
       if (! elf64_vms_link_add_object_symbols (element, info))
        return FALSE;
 
index 1569e93c5b8f9b0c64d8c4b436e79a3ed4536e83..b4efd5aec20c99a75719f67f4949fce090357017 100644 (file)
@@ -5283,7 +5283,7 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
 
          if (!(*info->callbacks
                ->add_archive_element) (info, element, symdef->name, &element))
-           goto error_return;
+           continue;
          if (!bfd_link_add_symbols (element, info))
            goto error_return;
 
index bf0cfc36f503865137658ffbcf985c6480402951..1f40be59731d17b624075bd436e5f1a657d4d743 100644 (file)
@@ -2608,7 +2608,7 @@ aout_link_check_ar_symbols (bfd *abfd,
             However, it might be correct.  */
          if (!(*info->callbacks
                ->add_archive_element) (info, abfd, name, subsbfd))
-           return FALSE;
+           continue;
          *pneeded = TRUE;
          return TRUE;
        }
index e6cfc1fcf2905a568438bd4e3cc3e8ec412a84fd..449354d26e2c1f238b39c98d61b3767cabf01a7a 100644 (file)
@@ -8202,7 +8202,7 @@ alpha_vms_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
         to include it.  We don't need to check anything.  */
       if (!(*info->callbacks
            ->add_archive_element) (info, element, h->root.string, &element))
-       return FALSE;
+       continue;
       if (!alpha_vms_link_add_object_symbols (element, info))
        return FALSE;
 
index f6030f13f707c29270b08ef08c571f42e8c90415..ca400965c9a35904efef4cb631e555f48caf4a1f 100644 (file)
@@ -2291,7 +2291,7 @@ xcoff_link_check_dynamic_ar_symbols (bfd *abfd,
        {
          if (!(*info->callbacks
                ->add_archive_element) (info, abfd, name, subsbfd))
-           return FALSE;
+           continue;
          *pneeded = TRUE;
          return TRUE;
        }
@@ -2363,7 +2363,7 @@ xcoff_link_check_ar_symbols (bfd *abfd,
            {
              if (!(*info->callbacks
                    ->add_archive_element) (info, abfd, name, subsbfd))
-               return FALSE;
+               continue;
              *pneeded = TRUE;
              return TRUE;
            }
index aaab50d55e6f9c7306ccc2071b5768cbfa020d02..181eec8f3ab461038d37a19884b898010a77ad8d 100644 (file)
@@ -1,3 +1,16 @@
+2016-05-25  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR ld/20103
+       * ldmain.c (add_archive_element): Don't claim new IR symbols
+       after all IR symbols have been claimed.
+       * plugin.c (plugin_call_claim_file): Remove no_more_claiming
+       check.
+       * testsuite/ld-plugin/lto.exp (pr20103): New proc.
+       Run PR ld/20103 tests.
+       * testsuite/ld-plugin/pr20103a.c: New file.
+       * testsuite/ld-plugin/pr20103b.c: Likewise.
+       * testsuite/ld-plugin/pr20103c.c: Likewise.
+
 2016-05-24  Maciej W. Rozycki  <macro@imgtec.com>
     
        * testsuite/ld-mips-elf/jalx-local.d: New test.
index 21133ab72090a6e2f8fcb80a2c11f40f8fc12fb0..7d04be29bbcfb51077c2c43e904a211740d04b19 100644 (file)
@@ -796,12 +796,22 @@ add_archive_element (struct bfd_link_info *info,
      BFD, but we still want to output the original BFD filename.  */
   orig_input = *input;
 #ifdef ENABLE_PLUGINS
-  if (link_info.lto_plugin_active && !no_more_claiming)
+  if (link_info.lto_plugin_active)
     {
       /* We must offer this archive member to the plugins to claim.  */
       plugin_maybe_claim (input);
       if (input->flags.claimed)
        {
+         if (no_more_claiming)
+           {
+             /* Don't claim new IR symbols after all IR symbols have
+                been claimed.  */
+             if (trace_files || verbose)
+               info_msg ("%I: no new IR symbols to claimi\n",
+                         &orig_input);
+             input->flags.claimed = 0;
+             return FALSE;
+           }
          input->flags.claim_archive = TRUE;
          *subsbfd = input->the_bfd;
        }
index a60ffca70e93a92aff43acc15a78306b3993e81d..c951995dccb3104b741925e3604c0311e37134d6 100644 (file)
@@ -1033,8 +1033,6 @@ plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed)
 {
   plugin_t *curplug = plugins_list;
   *claimed = FALSE;
-  if (no_more_claiming)
-    return 0;
   while (curplug && !*claimed)
     {
       if (curplug->claim_file_handler)
index 6330a178abaa8e0ba4287fc8698d7acddc350393..7a13abbfdb60404d4bef4a8e7fea64c9207bc84c 100644 (file)
@@ -460,4 +460,89 @@ if { [is_elf_format] } {
     run_ld_link_exec_tests [] $lto_run_elf_tests
 }
 
+proc pr20103 {cflags libs} {
+    global CC
+
+    set testname "PR ld/20103 ($cflags $libs)"
+    set exec_output [run_host_cmd "$CC" "$cflags $libs"]
+    if { [ regexp "undefined reference to `dead'" $exec_output ] } {
+        pass "$testname (1)"
+    } {
+        fail "$testname (1)"
+    }
+    if { [ regexp "plugin needed to handle lto object" $exec_output ] } {
+        fail "$testname (2)"
+    } {
+        pass "$testname (2)"
+    }
+}
+
+if { [check_lto_fat_available] } {
+    run_cc_link_tests [list \
+       [list \
+           "Build fatpr20103a.a" \
+           "$plug_opt" "-flto -ffat-lto-objects" \
+           {pr20103a.c} {} "fatpr20103a.a"
+       ] \
+       [list \
+           "Build fatpr20103b.a" \
+           "$plug_opt" "-flto -ffat-lto-objects" \
+           {pr20103b.c} {} "fatpr20103b.a"
+       ] \
+       [list \
+           "Build fatpr20103c.a" \
+           "$plug_opt" "-flto -ffat-lto-objects" \
+           {pr20103c.c} {} "fatpr20103c.a" \
+       ] \
+       [list \
+           "Build thinpr20103a.a" \
+           "$plug_opt" "-flto -fno-fat-lto-objects" \
+           {pr20103a.c} {} "thinpr20103a.a"
+       ] \
+       [list \
+           "Build thinpr20103b.a" \
+           "$plug_opt" "-flto -fno-fat-lto-objects" \
+           {pr20103b.c} {} "thinpr20103b.a"
+       ] \
+       [list \
+           "Build thinpr20103c.a" \
+           "$plug_opt" "-flto -fno-fat-lto-objects" \
+           {pr20103c.c} {} "thinpr20103c.a" \
+       ] \
+       [list \
+           "Build pr20103a" \
+           "-O2 -flto -Wl,--start-group tmpdir/thinpr20103a.a tmpdir/thinpr20103b.a tmpdir/thinpr20103c.a -Wl,--end-group" \
+           "-O2 -flto" \
+           {dummy.c} {} "pr20103a" \
+       ] \
+       [list \
+           "Build pr20103b" \
+           "-O2 -flto -Wl,--start-group tmpdir/fatpr20103a.a tmpdir/fatpr20103b.a tmpdir/fatpr20103c.a -Wl,--end-group" \
+           "-O2 -flto" \
+           {dummy.c} {} "pr20103b" \
+       ] \
+       [list \
+           "Build pr20103c" \
+           "-O2 -Wl,--start-group tmpdir/fatpr20103a.a tmpdir/fatpr20103b.a tmpdir/fatpr20103c.a -Wl,--end-group" \
+           "-O2" \
+           {dummy.c} {} "pr20103c" \
+       ] \
+    ]
+    pr20103 "-O2 -flto" "tmpdir/thinpr20103a.a tmpdir/thinpr20103b.a tmpdir/thinpr20103c.a"
+    pr20103 "-O2 -flto" "tmpdir/fatpr20103a.a tmpdir/fatpr20103b.a tmpdir/fatpr20103c.a"
+    pr20103 "-O2" "tmpdir/fatpr20103a.a tmpdir/fatpr20103b.a tmpdir/fatpr20103c.a"
+
+    if { [at_least_gcc_version 4 9] } {
+       run_cc_link_tests [list \
+           [list \
+               "Build pr20103d" \
+               "-O2 -Wl,--start-group tmpdir/thinpr20103a.a tmpdir/thinpr20103b.a tmpdir/thinpr20103c.a -Wl,--end-group" \
+               "-O2" \
+               {dummy.c} {} "pr20103d" \
+           ] \
+       ]
+       pr20103 "-O2" "tmpdir/thinpr20103a.a tmpdir/thinpr20103b.a tmpdir/thinpr20103c.a"
+    }
+}
+
 restore_notify
diff --git a/ld/testsuite/ld-plugin/pr20103a.c b/ld/testsuite/ld-plugin/pr20103a.c
new file mode 100644 (file)
index 0000000..6ebfd2c
--- /dev/null
@@ -0,0 +1,8 @@
+void live();
+
+int
+main ()
+{
+    live();
+    return 0;
+}
diff --git a/ld/testsuite/ld-plugin/pr20103b.c b/ld/testsuite/ld-plugin/pr20103b.c
new file mode 100644 (file)
index 0000000..ead122d
--- /dev/null
@@ -0,0 +1,3 @@
+void dead()
+{
+}
diff --git a/ld/testsuite/ld-plugin/pr20103c.c b/ld/testsuite/ld-plugin/pr20103c.c
new file mode 100644 (file)
index 0000000..fb94e02
--- /dev/null
@@ -0,0 +1,6 @@
+extern void dead ();
+
+void live()
+{
+  dead ();
+}