]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
PR ld/12696
authorAlan Modra <amodra@gmail.com>
Wed, 27 Apr 2011 07:17:45 +0000 (07:17 +0000)
committerAlan Modra <amodra@gmail.com>
Wed, 27 Apr 2011 07:17:45 +0000 (07:17 +0000)
PR ld/12672
PR ld/12507
PR ld/12365
PR 10549
Backport fixes for these PRs.

36 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/bfd.c
bfd/coff-aux.c
bfd/elf-bfd.h
bfd/elf.c
bfd/elf32-i386.c
bfd/elf32-ppc.c
bfd/elf32-sparc.c
bfd/elf64-ppc.c
bfd/elf64-sparc.c
bfd/elf64-x86-64.c
bfd/elfcode.h
bfd/elflink.c
bfd/linker.c
bfd/opncls.c
bfd/plugin.c
bfd/simple.c
bfd/xcofflink.c
gas/testsuite/ChangeLog
gas/testsuite/gas/elf/elf.exp
include/ChangeLog
include/bfdlink.h
ld/ChangeLog
ld/ld.texinfo
ld/ldfile.c
ld/ldlang.c
ld/ldlang.h
ld/ldmain.c
ld/lexsup.c
ld/plugin.c
ld/plugin.h
ld/testsuite/ChangeLog
ld/testsuite/ld-plugin/plugin-7.d
ld/testsuite/ld-plugin/plugin-8.d
ld/testsuite/ld-plugin/plugin.exp

index 6e8c81c7808032e79139b259646c7e48f281bfb0..b36b15b686dfc39f72efd71f78cc59e072eeada3 100644 (file)
@@ -1,3 +1,61 @@
+2011-04-27  Alan Modra  <amodra@gmail.com>
+
+       Backport from mainline
+       2011-04-24  Alan Modra  <amodra@gmail.com>
+       PR ld/12365
+       PR ld/12696
+       * coff-aux.c (coff_m68k_aux_link_add_one_symbol): Update "notice" call.
+       * linker.c (_bfd_link_hash_newfunc): Clear bitfields.
+       (_bfd_generic_link_add_one_symbol): Update "notice" call.
+       * elflink.c (_bfd_elf_merge_symbol): Don't skip weak redefs when
+       it is a redef of an IR symbol in a real BFD.
+
+       2011-04-20  Alan Modra  <amodra@gmail.com>
+       PR ld/12365
+       * elfcode.h (elf_slurp_symbol_table): Put common plugin IR symbols
+       in their own common section.
+       * elflink.c (elf_link_add_object_symbols): Likewise.
+       * linker.c (generic_link_check_archive_element): Don't lose flags
+       if common section is pre-existing.
+       (_bfd_generic_link_add_one_symbol): Likewise.
+
+       2011-04-20  Alan Modra  <amodra@gmail.com>
+       PR ld/12365
+       * elflink.c (_bfd_elf_merge_symbol): Update multiple_common calls.
+       * linker.c (_bfd_generic_link_add_one_symbol): Likewise.  Call
+       multiple_definition regardless of allow_multiple_definition.
+       * simple.c (simple_dummy_multiple_definition): Update.
+       * xcofflink.c (xcoff_link_add_symbols): Update multiple_definition
+       calls.
+
+       2011-04-18  Alan Modra  <amodra@gmail.com>
+       PR ld/12365
+       PR ld/12672
+       * bfd.c (BFD_PLUGIN): Define.
+       (BFD_FLAGS_SAVED, BFD_FLAGS_FOR_BFD_USE_MASK): Add BFD_PLUGIN.
+       * bfd-in2.h: Regenerate.
+       * elflink.c (elf_link_output_extsym): Strip undefined plugin syms.
+       * opncls.c (bfd_make_readable): Don't lose original bfd flags.
+
+       2011-04-11  Mark Wielaard  <mjw@redhat.com>
+       PR 10549
+       * elf-bfd.h (has_ifunc_symbols): Renamed to has_gnu_symbols.
+       (has_gnu_symbols): Renamed from has_ifunc_symbols.
+       * elf.c (_bfd_elf_set_osabi): Use new has_gnu_symbols name.
+       * elf32-i386.c (elf_i386_add_symbol_hook): Likewise.
+       * elf32-ppc.c (ppc_elf_add_symbol_hook): Likewise.
+       * elf32-sparc.c (elf32_sparc_add_symbol_hook): Likewise.
+       * elf64-ppc.c (ppc64_elf_add_symbol_hook): Likewise.
+       * elf64-sparc.c (elf64_sparc_add_symbol_hook): Likewise.
+       * elf64-x86-64.c (elf_x86_64_add_symbol_hook): Likewise.
+
+       2011-02-25  Rafael Ávila de Espíndola <respindola@mozilla.com>
+       * plugin.c (bfd_plugin_object_p): Correctly set the filesize
+       and handle claim_file seeking. Only try to load the plugin once.
+
+       2010-12-12  H.J. Lu  <hongjiu.lu@intel.com>
+       * elf.c (special_sections_g): Add ".gnu.lto_".
+
 2011-04-20  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * elf-bfd.h (RELOC_AGAINST_DISCARDED_SECTION): Fix +1 overrun of
index f3e2b457913fe2a4a045e3fd74871c14f4a614c2..0907784a409088909511901a89959eddaaf3f940 100644 (file)
@@ -5084,14 +5084,17 @@ struct bfd
   /* Decompress sections in this BFD.  */
 #define BFD_DECOMPRESS 0x10000
 
+  /* BFD is a dummy, for plugins.  */
+#define BFD_PLUGIN 0x20000
+
   /* Flags bits to be saved in bfd_preserve_save.  */
 #define BFD_FLAGS_SAVED \
-  (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS)
+  (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_PLUGIN)
 
   /* Flags bits which are for BFD use only.  */
 #define BFD_FLAGS_FOR_BFD_USE_MASK \
   (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \
-   | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT)
+   | BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT)
 
   /* Currently my_archive is tested before adding origin to
      anything. I believe that this can become always an add of
index 77582ec82fe8aedb106d2ce13d0287ab274937e0..c729d63170310aa2825acad8a7cd662231b26dad 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -157,14 +157,17 @@ CODE_FRAGMENT
 .  {* Decompress sections in this BFD.  *}
 .#define BFD_DECOMPRESS 0x10000
 .
+.  {* BFD is a dummy, for plugins.  *}
+.#define BFD_PLUGIN 0x20000
+.
 .  {* Flags bits to be saved in bfd_preserve_save.  *}
 .#define BFD_FLAGS_SAVED \
-.  (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS)
+.  (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_PLUGIN)
 .
 .  {* Flags bits which are for BFD use only.  *}
 .#define BFD_FLAGS_FOR_BFD_USE_MASK \
 .  (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \
-.   | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT)
+.   | BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT)
 .
 .  {* Currently my_archive is tested before adding origin to
 .     anything. I believe that this can become always an add of
index af1db03836dad232c08fba8837ee514216d69ce5..052892445b3f0febda8b98909f111946486b75ee 100644 (file)
@@ -105,7 +105,7 @@ coff_m68k_aux_link_add_one_symbol (info, abfd, name, flags, section, value,
          && (bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE)
              != (struct bfd_hash_entry *) NULL))
        {
-         if (! (*info->callbacks->notice) (info, name, abfd, section, value))
+         if (! (*info->callbacks->notice) (info, h, abfd, section, value))
            return FALSE;
        }
 
index 73806dd9110d1fc7eb99f31741dae461c0448358..0c5b0cbd3499bfd5d8cba0406b489be3bfc5b034 100644 (file)
@@ -1631,9 +1631,9 @@ struct elf_obj_tdata
   bfd_byte *build_id;
 
   /* True if the bfd contains symbols that have the STT_GNU_IFUNC
-     symbol type.  Used to set the osabi field in the ELF header
-     structure.  */
-  bfd_boolean has_ifunc_symbols;
+     symbol type or STB_GNU_UNIQUE binding.  Used to set the osabi
+     field in the ELF header structure.  */
+  bfd_boolean has_gnu_symbols;
 
   /* An identifier used to distinguish different target
      specific extensions to this structure.  */
index f54448659f0bb002efdb75f4876657cb46a03030..c0ffbd078b7a52cd9ce0d994e22df6f09f407448 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -2082,6 +2082,7 @@ static const struct bfd_elf_special_section special_sections_f[] =
 static const struct bfd_elf_special_section special_sections_g[] =
 {
   { STRING_COMMA_LEN (".gnu.linkonce.b"), -2, SHT_NOBITS,      SHF_ALLOC + SHF_WRITE },
+  { STRING_COMMA_LEN (".gnu.lto_"),       -1, SHT_PROGBITS,    SHF_EXCLUDE },
   { STRING_COMMA_LEN (".got"),             0, SHT_PROGBITS,    SHF_ALLOC + SHF_WRITE },
   { STRING_COMMA_LEN (".gnu.version"),     0, SHT_GNU_versym,  0 },
   { STRING_COMMA_LEN (".gnu.version_d"),   0, SHT_GNU_verdef,  0 },
@@ -9480,9 +9481,9 @@ _bfd_elf_set_osabi (bfd * abfd,
 
   /* To make things simpler for the loader on Linux systems we set the
      osabi field to ELFOSABI_LINUX if the binary contains symbols of
-     the STT_GNU_IFUNC type.  */
+     the STT_GNU_IFUNC type or STB_GNU_UNIQUE binding.  */
   if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE
-      && elf_tdata (abfd)->has_ifunc_symbols)
+      && elf_tdata (abfd)->has_gnu_symbols)
     i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_LINUX;
 }
 
index ae749c6b4e87cfdb89a6480b33cb2ffd41a7ee7e..1071f015d04e36d5c0e6d2a31ca15ab61fb1dc22 100644 (file)
@@ -4695,8 +4695,9 @@ elf_i386_add_symbol_hook (bfd * abfd,
                          bfd_vma * valp ATTRIBUTE_UNUSED)
 {
   if ((abfd->flags & DYNAMIC) == 0
-      && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
-    elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
+      && (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+         || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE))
+    elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
 
   return TRUE;
 }
index 9e097ad624dd4b4691b3a6edcb81826b74a5b8bf..c7363753d497ecb28c75b615aa76cb4cd0cb0ded 100644 (file)
@@ -3113,8 +3113,9 @@ ppc_elf_add_symbol_hook (bfd *abfd,
     }
 
   if ((abfd->flags & DYNAMIC) == 0
-      && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
-    elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
+      && (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+         || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE))
+    elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
 
   return TRUE;
 }
index 187d46698d54f5fbd55192553f05711921e7348a..2d9deabb60398043ec9345032ca3cc8aa18ed949 100644 (file)
@@ -180,8 +180,9 @@ elf32_sparc_add_symbol_hook (bfd * abfd,
                             bfd_vma * valp ATTRIBUTE_UNUSED)
 {
   if ((abfd->flags & DYNAMIC) == 0
-      && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
-    elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
+      && (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+         || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE))
+    elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
   return TRUE;
 }
 
index 4cbd941baa2f1272e4baff9f8d448ec0ac0747ca..eb07b1fb7c7bf19690c32dc2cf6326a313f846a0 100644 (file)
@@ -4569,10 +4569,14 @@ ppc64_elf_add_symbol_hook (bfd *ibfd,
                           asection **sec,
                           bfd_vma *value ATTRIBUTE_UNUSED)
 {
+  if ((ibfd->flags & DYNAMIC) == 0
+      && ELF_ST_BIND (isym->st_info) == STB_GNU_UNIQUE)
+    elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
+
   if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
     {
       if ((ibfd->flags & DYNAMIC) == 0)
-       elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
+       elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
     }
   else if (ELF_ST_TYPE (isym->st_info) == STT_FUNC)
     ;
index 9f05b85fa576415af32044c3ea3dc50bb448d2bd..4d093984b5759fd3081b6797cf92a8c80a348f1f 100644 (file)
@@ -426,8 +426,9 @@ elf64_sparc_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
   static const char *const stt_types[] = { "NOTYPE", "OBJECT", "FUNCTION" };
 
   if ((abfd->flags & DYNAMIC) == 0
-      && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
-    elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
+      && (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+         || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE))
+    elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
 
   if (ELF_ST_TYPE (sym->st_info) == STT_REGISTER)
     {
index 83656aead16327b6f49746ee9c3341b78ed3443a..09af249dfeb261cca156ba33e87142dddcc97080 100644 (file)
@@ -4303,8 +4303,9 @@ elf64_x86_64_add_symbol_hook (bfd *abfd,
     }
 
   if ((abfd->flags & DYNAMIC) == 0
-      && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
-    elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
+      && (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+         || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE))
+    elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
 
   return TRUE;
 }
index 5ef461018d97bbc8e08d9150a894ae26e60e50f8..29cd22845e5c41805610f1308b894e68f4ea58b3 100644 (file)
@@ -1281,6 +1281,20 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
          else if (isym->st_shndx == SHN_COMMON)
            {
              sym->symbol.section = bfd_com_section_ptr;
+             if ((abfd->flags & BFD_PLUGIN) != 0)
+               {
+                 asection *xc = bfd_get_section_by_name (abfd, "COMMON");
+
+                 if (xc == NULL)
+                   {
+                     flagword flags = (SEC_ALLOC | SEC_IS_COMMON | SEC_KEEP
+                                       | SEC_EXCLUDE);
+                     xc = bfd_make_section_with_flags (abfd, "COMMON", flags);
+                     if (xc == NULL)
+                       goto error_return;
+                   }
+                 sym->symbol.section = xc;
+               }
              /* Elf puts the alignment into the `value' field, and
                 the size into the `size' field.  BFD wants to see the
                 size in the value field, and doesn't care (at the
index 6136a94cfdf32e1f9ac9d03cffe276c5425ee565..5a9d457d38e0c90cf01dcd0e80347029c2218489 100644 (file)
@@ -1361,8 +1361,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
         symbols defined in dynamic objects.  */
 
       if (! ((*info->callbacks->multiple_common)
-            (info, h->root.root.string, oldbfd, bfd_link_hash_common,
-             h->size, abfd, bfd_link_hash_common, sym->st_size)))
+            (info, &h->root, abfd, bfd_link_hash_common, sym->st_size)))
        return FALSE;
 
       if (sym->st_size > h->size)
@@ -1428,7 +1427,10 @@ _bfd_elf_merge_symbol (bfd *abfd,
   /* Skip weak definitions of symbols that are already defined.  */
   if (newdef && olddef && newweak)
     {
-      *skip = TRUE;
+      /* Don't skip new non-IR weak syms.  */
+      if (!((oldbfd->flags & BFD_PLUGIN) != 0
+           && (abfd->flags & BFD_PLUGIN) == 0))
+       *skip = TRUE;
 
       /* Merge st_other.  If the symbol already has a dynamic index,
         but visibility says it should not be visible, turn it into a
@@ -1513,8 +1515,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
         common symbol, but we don't know what to use for the section
         or the alignment.  */
       if (! ((*info->callbacks->multiple_common)
-            (info, h->root.root.string, oldbfd, bfd_link_hash_common,
-             h->size, abfd, bfd_link_hash_common, sym->st_size)))
+            (info, &h->root, abfd, bfd_link_hash_common, sym->st_size)))
        return FALSE;
 
       /* If the presumed common symbol in the dynamic object is
@@ -3939,18 +3940,31 @@ error_free_dyn:
        goto error_free_vers;
 
       if (isym->st_shndx == SHN_COMMON
-         && ELF_ST_TYPE (isym->st_info) == STT_TLS
-         && !info->relocatable)
+         && (abfd->flags & BFD_PLUGIN) != 0)
+       {
+         asection *xc = bfd_get_section_by_name (abfd, "COMMON");
+
+         if (xc == NULL)
+           {
+             flagword sflags = (SEC_ALLOC | SEC_IS_COMMON | SEC_KEEP
+                                | SEC_EXCLUDE);
+             xc = bfd_make_section_with_flags (abfd, "COMMON", sflags);
+             if (xc == NULL)
+               goto error_free_vers;
+           }
+         sec = xc;
+       }
+      else if (isym->st_shndx == SHN_COMMON
+              && ELF_ST_TYPE (isym->st_info) == STT_TLS
+              && !info->relocatable)
        {
          asection *tcomm = bfd_get_section_by_name (abfd, ".tcommon");
 
          if (tcomm == NULL)
            {
-             tcomm = bfd_make_section_with_flags (abfd, ".tcommon",
-                                                  (SEC_ALLOC
-                                                   | SEC_IS_COMMON
-                                                   | SEC_LINKER_CREATED
-                                                   | SEC_THREAD_LOCAL));
+             flagword sflags = (SEC_ALLOC | SEC_THREAD_LOCAL | SEC_IS_COMMON
+                                | SEC_LINKER_CREATED);
+             tcomm = bfd_make_section_with_flags (abfd, ".tcommon", sflags);
              if (tcomm == NULL)
                goto error_free_vers;
            }
@@ -8699,6 +8713,11 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data)
               || h->root.type == bfd_link_hash_defweak)
           && elf_discarded_section (h->root.u.def.section))
     strip = TRUE;
+  else if ((h->root.type == bfd_link_hash_undefined
+           || h->root.type == bfd_link_hash_undefweak)
+          && h->root.u.undef.abfd != NULL
+          && (h->root.u.undef.abfd->flags & BFD_PLUGIN) != 0)
+    strip = TRUE;
   else
     strip = FALSE;
 
index 2b52ba965105930a4db2aa149a88d0181e0511f6..1f02cbab545cf64d663a4d23f6f2c65f1d8d7bea 100644 (file)
@@ -465,10 +465,8 @@ _bfd_link_hash_newfunc (struct bfd_hash_entry *entry,
       struct bfd_link_hash_entry *h = (struct bfd_link_hash_entry *) entry;
 
       /* Initialize the local fields.  */
-      h->type = bfd_link_hash_new;
-      memset (&h->u.undef.next, 0,
-             (sizeof (struct bfd_link_hash_entry)
-              - offsetof (struct bfd_link_hash_entry, u.undef.next)));
+      memset ((char *) &h->root + sizeof (h->root), 0,
+             sizeof (*h) - sizeof (h->root));
     }
 
   return entry;
@@ -1296,7 +1294,7 @@ generic_link_check_archive_element (bfd *abfd,
          else
            h->u.c.p->section = bfd_make_section_old_way (symbfd,
                                                          p->section->name);
-         h->u.c.p->section->flags = SEC_ALLOC;
+         h->u.c.p->section->flags |= SEC_ALLOC;
        }
       else
        {
@@ -1609,8 +1607,7 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
       || (info->notice_hash != NULL
          && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL))
     {
-      if (! (*info->callbacks->notice) (info, h->root.string, abfd, section,
-                                       value))
+      if (! (*info->callbacks->notice) (info, h, abfd, section, value))
        return FALSE;
     }
 
@@ -1651,9 +1648,7 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
             previously common.  */
          BFD_ASSERT (h->type == bfd_link_hash_common);
          if (! ((*info->callbacks->multiple_common)
-                (info, h->root.string,
-                 h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size,
-                 abfd, bfd_link_hash_defined, 0)))
+                (info, h, abfd, bfd_link_hash_defined, 0)))
            return FALSE;
          /* Fall through.  */
        case DEF:
@@ -1758,13 +1753,13 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
          if (section == bfd_com_section_ptr)
            {
              h->u.c.p->section = bfd_make_section_old_way (abfd, "COMMON");
-             h->u.c.p->section->flags = SEC_ALLOC;
+             h->u.c.p->section->flags |= SEC_ALLOC;
            }
          else if (section->owner != abfd)
            {
              h->u.c.p->section = bfd_make_section_old_way (abfd,
                                                            section->name);
-             h->u.c.p->section->flags = SEC_ALLOC;
+             h->u.c.p->section->flags |= SEC_ALLOC;
            }
          else
            h->u.c.p->section = section;
@@ -1782,9 +1777,7 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
             two sizes, and use the section required by the larger symbol.  */
          BFD_ASSERT (h->type == bfd_link_hash_common);
          if (! ((*info->callbacks->multiple_common)
-                (info, h->root.string,
-                 h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size,
-                 abfd, bfd_link_hash_common, value)))
+                (info, h, abfd, bfd_link_hash_common, value)))
            return FALSE;
          if (value > h->u.c.size)
            {
@@ -1807,13 +1800,13 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
                {
                  h->u.c.p->section
                    = bfd_make_section_old_way (abfd, "COMMON");
-                 h->u.c.p->section->flags = SEC_ALLOC;
+                 h->u.c.p->section->flags |= SEC_ALLOC;
                }
              else if (section->owner != abfd)
                {
                  h->u.c.p->section
                    = bfd_make_section_old_way (abfd, section->name);
-                 h->u.c.p->section->flags = SEC_ALLOC;
+                 h->u.c.p->section->flags |= SEC_ALLOC;
                }
              else
                h->u.c.p->section = section;
@@ -1821,23 +1814,11 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
          break;
 
        case CREF:
-         {
-           bfd *obfd;
-
-           /* We have found a common definition for a symbol which
-              was already defined.  FIXME: It would nice if we could
-              report the BFD which defined an indirect symbol, but we
-              don't have anywhere to store the information.  */
-           if (h->type == bfd_link_hash_defined
-               || h->type == bfd_link_hash_defweak)
-             obfd = h->u.def.section->owner;
-           else
-             obfd = NULL;
-           if (! ((*info->callbacks->multiple_common)
-                  (info, h->root.string, obfd, h->type, 0,
-                   abfd, bfd_link_hash_common, value)))
-             return FALSE;
-         }
+         /* We have found a common definition for a symbol which
+            was already defined.  */
+         if (! ((*info->callbacks->multiple_common)
+                (info, h, abfd, bfd_link_hash_common, value)))
+           return FALSE;
          break;
 
        case MIND:
@@ -1848,47 +1829,16 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
          /* Fall through.  */
        case MDEF:
          /* Handle a multiple definition.  */
-         if (!info->allow_multiple_definition)
-           {
-             asection *msec = NULL;
-             bfd_vma mval = 0;
-
-             switch (h->type)
-               {
-               case bfd_link_hash_defined:
-                 msec = h->u.def.section;
-                 mval = h->u.def.value;
-                 break;
-               case bfd_link_hash_indirect:
-                 msec = bfd_ind_section_ptr;
-                 mval = 0;
-                 break;
-               default:
-                 abort ();
-               }
-
-             /* Ignore a redefinition of an absolute symbol to the
-                same value; it's harmless.  */
-             if (h->type == bfd_link_hash_defined
-                 && bfd_is_abs_section (msec)
-                 && bfd_is_abs_section (section)
-                 && value == mval)
-               break;
-
-             if (! ((*info->callbacks->multiple_definition)
-                    (info, h->root.string, msec->owner, msec, mval,
-                     abfd, section, value)))
-               return FALSE;
-           }
+         if (! ((*info->callbacks->multiple_definition)
+                (info, h, abfd, section, value)))
+           return FALSE;
          break;
 
        case CIND:
          /* Create an indirect symbol from an existing common symbol.  */
          BFD_ASSERT (h->type == bfd_link_hash_common);
          if (! ((*info->callbacks->multiple_common)
-                (info, h->root.string,
-                 h->u.c.p->section->owner, bfd_link_hash_common, h->u.c.size,
-                 abfd, bfd_link_hash_indirect, 0)))
+                (info, h, abfd, bfd_link_hash_indirect, 0)))
            return FALSE;
          /* Fall through.  */
        case IND:
index 3597daee01f73abeb803529cb51757fc01fc6f43..40432000c0abc3cb3984cbc022206efd9f7ab236 100644 (file)
@@ -875,7 +875,7 @@ bfd_make_readable (bfd *abfd)
   abfd->section_count = 0;
   abfd->usrdata = NULL;
   abfd->cacheable = FALSE;
-  abfd->flags = BFD_IN_MEMORY;
+  abfd->flags |= BFD_IN_MEMORY;
   abfd->mtime_set = FALSE;
 
   abfd->target_defaulted = TRUE;
index 61cd6873361d12d14293e8ef51eb2b01413db117..bc36f1fac792b832ff0cecfc576f95b37bd8ffd5 100644 (file)
@@ -232,11 +232,17 @@ static const bfd_target *
 bfd_plugin_object_p (bfd *abfd)
 {
   int claimed = 0;
-  int t = load_plugin ();
   struct ld_plugin_input_file file;
   bfd *iobfd;
+  static int have_loaded = 0;
+  static int have_plugin = 0;
 
-  if (!t)
+  if (!have_loaded)
+    {
+      have_loaded = 1;
+      have_plugin = load_plugin ();
+    }
+  if (!have_plugin)
     return NULL;
 
   file.name = abfd->filename;
@@ -251,7 +257,7 @@ bfd_plugin_object_p (bfd *abfd)
     {
       iobfd = abfd;
       file.offset = 0;
-      file.filesize = 0; /*FIXME*/
+      file.filesize = 0;
     }
 
   if (!iobfd->iostream && !bfd_open_file (iobfd))
@@ -259,8 +265,18 @@ bfd_plugin_object_p (bfd *abfd)
 
   file.fd = fileno ((FILE *) iobfd->iostream);
 
+  if (!abfd->my_archive)
+    {
+      struct stat stat_buf;
+      if (fstat (file.fd, &stat_buf))
+        return NULL;
+      file.filesize = stat_buf.st_size;
+    }
+
   file.handle = abfd;
+  off_t cur_offset = lseek(file.fd, 0, SEEK_CUR);
   claim_file (&file, &claimed);
+  lseek(file.fd, cur_offset, SEEK_SET);
   if (!claimed)
     return NULL;
 
index 03d1a158859576bec746ec23d4d71c8170df1db4..1f4d72d8f3fe1d1f116549122672b48d6432fb12 100644 (file)
@@ -82,10 +82,7 @@ simple_dummy_unattached_reloc (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
 
 static bfd_boolean
 simple_dummy_multiple_definition (struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
-                                 const char *name ATTRIBUTE_UNUSED,
-                                 bfd *obfd ATTRIBUTE_UNUSED,
-                                 asection *osec ATTRIBUTE_UNUSED,
-                                 bfd_vma oval ATTRIBUTE_UNUSED,
+                                 struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
                                  bfd *nbfd ATTRIBUTE_UNUSED,
                                  asection *nsec ATTRIBUTE_UNUSED,
                                  bfd_vma nval ATTRIBUTE_UNUSED)
index d3e9043dc3f147b869aaae7ffb2236e92381a131..ad2f4cd4b00baec10349e8952c68cb7c5e4a9762 100644 (file)
@@ -1996,11 +1996,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
                     handle them, and that would only be a warning,
                     not an error.  */
                  if (! ((*info->callbacks->multiple_definition)
-                        (info, (*sym_hash)->root.root.string,
-                         NULL, NULL, (bfd_vma) 0,
-                         (*sym_hash)->root.u.def.section->owner,
-                         (*sym_hash)->root.u.def.section,
-                         (*sym_hash)->root.u.def.value)))
+                        (info, &(*sym_hash)->root, NULL, NULL, (bfd_vma) 0)))
                    goto error_return;
                  /* Try not to give this error too many times.  */
                  (*sym_hash)->flags &= ~XCOFF_MULTIPLY_DEFINED;
@@ -3119,9 +3115,7 @@ bfd_xcoff_import_symbol (bfd *output_bfd,
              || h->root.u.def.value != val))
        {
          if (! ((*info->callbacks->multiple_definition)
-                (info, h->root.root.string, h->root.u.def.section->owner,
-                 h->root.u.def.section, h->root.u.def.value,
-                 output_bfd, bfd_abs_section_ptr, val)))
+                (info, &h->root, output_bfd, bfd_abs_section_ptr, val)))
            return FALSE;
        }
 
index 06bf4453b3c847d8f796a4b5cea4b1922fe1f564..be592237710a2612c44096a40962b19db2ae9754 100644 (file)
@@ -1,3 +1,11 @@
+2011-04-27  Alan Modra  <amodra@gmail.com>
+
+       Apply from mainline.
+       2010-12-12  H.J. Lu  <hongjiu.lu@intel.com>
+       * gas/elf/elf.exp: Run section9.
+       * gas/elf/section9.d: New.
+       * gas/elf/section9.s: Likewise.
+
 2011-02-10  Vincent Rivière  <vincent.riviere@freesbee.fr>
 
        PR gas/6957
index 3babe0b1cb4948f8d7cca1b66027c2c60c5e0a60..7f86266e11cd17d5b95431b56b322ff94d39acba 100644 (file)
@@ -174,6 +174,7 @@ if { ([istarget "*-*-*elf*"]
     run_dump_test "section6"
     run_dump_test "section7"
     run_dump_test "section8"
+    run_dump_test "section9"
     run_dump_test "dwarf2-1"
     run_dump_test "dwarf2-2"
     run_dump_test "dwarf2-3"
index aa8e29e4a44ab38167e49d5e7e9a7b05799fc339..684e7b5d99f65e7409f809e96ae78da53348b455 100644 (file)
@@ -1,3 +1,20 @@
+2011-04-27  Alan Modra  <amodra@gmail.com>
+
+       Backport from mainline.
+       2011-04-24  Alan Modra  <amodra@gmail.com>
+       PR ld/12365
+       PR ld/12696
+       * bfdlink.h (ENUM_BITFIELD): Define.
+       (struct bfd_link_hash_entry): Make "type" a bitfield.  Add "non_ir_ref".
+       (struct bfd_link_callbacks <notice>): Pass bfd_link_hash_entry pointer
+       rather than "name".
+
+       2011-04-20  Alan Modra  <amodra@gmail.com>
+       PR ld/12365
+       * bfdlink.h (struct bfd_link_callbacks): Modify multiple_definition
+       and multiple_common parameters to pass in a bfd_link_hash_entry
+       pointer rather than name,bfd etc. found in the hash entry.
+
 2010-11-25  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
 
        * opcode/s390.h (enum s390_opcode_cpu_val): Add S390_OPCODE_MAXCPU.
 
        * simple-object.h: New file.
 
-2010-10-15  Dave Korn  <dave.korn.cygwin@gmail.com> 
+2010-10-15  Dave Korn  <dave.korn.cygwin@gmail.com>
 
        Sync LD plugin patch series (part 1/6) with src/include/.
        * plugin-api.h (LDPT_GNU_LD_VERSION): New ld_plugin_tag enum member.
 
-2010-10-14  Dave Korn  <dave.korn.cygwin@gmail.com> 
+2010-10-14  Dave Korn  <dave.korn.cygwin@gmail.com>
 
        Apply LD plugin patch series (part 6/6).
        * bfdlink.h (struct_bfd_link_callbacks): Document new argument
        to add_archive_element callback used to return a replacement bfd which
        is to be added to the hash table in place of the original element.
 
-2010-10-14  Dave Korn  <dave.korn.cygwin@gmail.com> 
+2010-10-14  Dave Korn  <dave.korn.cygwin@gmail.com>
 
        Apply LD plugin patch series (part 1/6).
        * plugin-api.h (LDPT_GNU_LD_VERSION): New ld_plugin_tag enum member.
index 0d6e9f8aeb0d0b775f6f2cd9cc307ccf76b77f97..66f76455b19ed66de60ba6f536b163d829f8569d 100644 (file)
 #ifndef BFDLINK_H
 #define BFDLINK_H
 
+#if (__GNUC__ * 1000 + __GNUC_MINOR__ > 2000)
+#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE
+#else
+#define ENUM_BITFIELD(TYPE) unsigned int
+#endif
+
 /* Which symbols to strip during a link.  */
 enum bfd_link_strip
 {
@@ -90,7 +96,9 @@ struct bfd_link_hash_entry
   struct bfd_hash_entry root;
 
   /* Type of this entry.  */
-  enum bfd_link_hash_type type;
+  ENUM_BITFIELD (bfd_link_hash_type) type : 8;
+
+  unsigned int non_ir_ref : 1;
 
   /* A union of information depending upon the type.  */
   union
@@ -487,29 +495,20 @@ struct bfd_link_callbacks
   bfd_boolean (*add_archive_element)
     (struct bfd_link_info *, bfd *abfd, const char *name, bfd **subsbfd);
   /* A function which is called when a symbol is found with multiple
-     definitions.  NAME is the symbol which is defined multiple times.
-     OBFD is the old BFD, OSEC is the old section, OVAL is the old
-     value, NBFD is the new BFD, NSEC is the new section, and NVAL is
-     the new value.  OBFD may be NULL.  OSEC and NSEC may be
-     bfd_com_section or bfd_ind_section.  */
+     definitions.  H is the symbol which is defined multiple times.
+     NBFD is the new BFD, NSEC is the new section, and NVAL is the new
+     value.  NSEC may be bfd_com_section or bfd_ind_section.  */
   bfd_boolean (*multiple_definition)
-    (struct bfd_link_info *, const char *name,
-     bfd *obfd, asection *osec, bfd_vma oval,
+    (struct bfd_link_info *, struct bfd_link_hash_entry *h,
      bfd *nbfd, asection *nsec, bfd_vma nval);
   /* A function which is called when a common symbol is defined
-     multiple times.  NAME is the symbol appearing multiple times.
-     OBFD is the BFD of the existing symbol; it may be NULL if this is
-     not known.  OTYPE is the type of the existing symbol, which may
-     be bfd_link_hash_defined, bfd_link_hash_defweak,
-     bfd_link_hash_common, or bfd_link_hash_indirect.  If OTYPE is
-     bfd_link_hash_common, OSIZE is the size of the existing symbol.
+     multiple times.  H is the symbol appearing multiple times.
      NBFD is the BFD of the new symbol.  NTYPE is the type of the new
      symbol, one of bfd_link_hash_defined, bfd_link_hash_common, or
      bfd_link_hash_indirect.  If NTYPE is bfd_link_hash_common, NSIZE
      is the size of the new symbol.  */
   bfd_boolean (*multiple_common)
-    (struct bfd_link_info *, const char *name,
-     bfd *obfd, enum bfd_link_hash_type otype, bfd_vma osize,
+    (struct bfd_link_info *, struct bfd_link_hash_entry *h,
      bfd *nbfd, enum bfd_link_hash_type ntype, bfd_vma nsize);
   /* A function which is called to add a symbol to a set.  ENTRY is
      the link hash table entry for the set itself (e.g.,
@@ -578,11 +577,11 @@ struct bfd_link_callbacks
     (struct bfd_link_info *, const char *name,
      bfd *abfd, asection *section, bfd_vma address);
   /* A function which is called when a symbol in notice_hash is
-     defined or referenced.  NAME is the symbol.  ABFD, SECTION and
-     ADDRESS are the value of the symbol.  If SECTION is
+     defined or referenced.  H is the symbol.  ABFD, SECTION and
+     ADDRESS are the (new) value of the symbol.  If SECTION is
      bfd_und_section, this is a reference.  */
   bfd_boolean (*notice)
-    (struct bfd_link_info *, const char *name,
+    (struct bfd_link_info *, struct bfd_link_hash_entry *h,
      bfd *abfd, asection *section, bfd_vma address);
   /* Error or warning link info message.  */
   void (*einfo)
index 2a1ede179d6a68d15c4c9e559436bca88922a1b0..c1218b5ac5b53a052b1760b9d10ac748d2741024 100644 (file)
@@ -1,3 +1,140 @@
+2011-04-27  Alan Modra  <amodra@gmail.com>
+
+       Backport from mainline.
+       2011-04-24  Alan Modra  <amodra@gmail.com>
+       PR ld/12365
+       PR ld/12696
+       * ldmain.c (notice): Delete "name" param, add "h".
+       * plugin.c (plugin_notice): Likewise.  Set non_ir_ref.  Handle
+       redefinitions of IR symbols in real BFDs.
+       (plugin_multiple_definition, plugin_multiple_common): Delete.
+       (non_ironly_hash, init_non_ironly_hash): Delete.
+       (is_visible_from_outside): Traverse entry_symbol chain.
+       (get_symbols): Use non_ir_ref flag rather than hash lookup.
+
+       2011-04-20  Alan Modra  <amodra@gmail.com>
+       PR ld/12365
+       * ldfile.c (ldfile_try_open_bfd): Move code creating and switching
+       to plugin IR BFD..
+       * ldmain.c (add_archive_element): ..and similar code here..
+       * plugin.c (plugin_maybe_claim): ..to here.  New function.
+       (plugin_call_claim_file): Make static.
+       (asymbol_from_plugin_symbol): Set ELF st_shndx for common syms.
+       (plugin_multiple_common): New function.
+       (plugin_call_all_symbols_read): Hook in plugin_multiple_common.
+       * plugin.h (plugin_call_claim_file): Don't declare.
+       (plugin_maybe_claim): Declare.
+
+       2011-04-20  Alan Modra  <amodra@gmail.com>
+       PR ld/12365
+       * ldmain.c (multiple_definition): Take a bfd_link_hash_entry
+       pointer arg rather than "name", "obfd", "osec", "oval".  Add code
+       removed from linker.c.  Hack around xcofflink.c oddity in
+       passing NULL nbfd.
+       (multiple_common): Similarly.
+       * plugin.c (orig_allow_multiple_defs): Delete.
+       (plugin_call_all_symbols_read): Don't twiddle allow_multiple_definition.
+       (plugin_multiple_definition): Update.
+
+       2011-04-18  Alan Modra  <amodra@gmail.com>
+       PR ld/12365
+       PR ld/12672
+       * ldfile.c (ldfile_try_open_bfd): Don't attempt any plugin action
+       when no_more_claiming.
+       * ldmain.c (add_archive_element): Likewise.
+       (multiple_definition): Remove plugin_multiple_definition call.
+       (notice): Remove plugin_notice call.
+       * ldlang.c (lang_list_insert_after, void lang_list_remove_tail): Move.
+       Delete prototype.
+       (plugin_insert): New static var.
+       (open_input_bfds): Only rescan libs after plugin insert point.
+       (lang_gc_sections): Omit plugin claimed files.
+       (lang_process): Set plugin_insert.  Only rescan when plugin adds
+       objects.
+       * plugin.h (no_more_claiming): Declare.
+       (plugin_notice, plugin_multiple_definition): Don't declare.
+       * plugin.c: Formatting.
+       (orig_notice_all, orig_allow_multiple_defs, orig_callbacks,
+       plugin_callbacks): New static vars.
+       (no_more_claiming): Make global.
+       (plugin_cached_allow_multiple_defs): Delete.
+       (plugin_get_ir_dummy_bfd): Set SEC_EXCLUDE on dummy .text section,
+       use newer bfd_make_section variant.  Make COMMON section too.
+       Error handling.  Correct setting of gp size.
+       (asymbol_from_plugin_symbol): Properly cast last arg of concat.
+       (message): Likewise for ACONCAT.
+       (asymbol_from_plugin_symbol): Use our COMMON section.
+       (get_symbols): When report_plugin_symbols, show visibility too.
+       (init_non_ironly_hash): Move.  Don't test non_ironly_hash.
+       (plugin_load_plugins): Save state of linker callbacks, set up to
+       call plugin_notice instead.  Call init_non_ironly_hash here.
+       (plugin_call_all_symbols_read): Set plugin_multiple_definition in
+       plugin callbacks.
+       (plugin_notice): Rewrite.
+       (plugin_multiple_definition): Make static, call original callback.
+
+       2011-04-15  Alan Modra  <amodra@gmail.com>
+       PR ld/12672
+       * ldlang.c (enum open_bfd_mode): New.
+       (open_input_bfds): Replace "force" param with "mode".  Reload
+       archives for rescan.  Update all callers.
+       (lang_process): Make another open_input_bfds pass for plugins.
+
+       2011-03-23  Joseph Myers  <joseph@codesourcery.com>
+       * lexsup.c (parse_args): Only set report_plugin_symbols if plugins
+       are enabled.  Mark level as possibly unused.
+
+       2011-03-10  Dave Korn  <dave.korn.cygwin@gmail.com>
+       * plugin.c (get_symbols): Use wrapped lookup for undefined symbols.
+
+       2011-03-10  Dave Korn  <dave.korn.cygwin@gmail.com>
+       * ldlang.c (lang_check): Don't run checks on dummy IR BFDs.
+
+       2011-03-10  Dave Korn  <dave.korn.cygwin@gmail.com>
+       * ldlang.h (lang_input_statement_type): Add new 'claim_archive' flag,
+       wrapping both it and 'claim' flag in #ifdef ENABLE_PLUGINS.
+       * ldmain.c (add_archive_element): Set it if the member is claimed.
+       * ldlang.c (new_afile): Initialise claim_archive and claimed members.
+       (find_replacements_insert_point): New helper function.
+       (lang_process): After adding and opening replacement files passed
+       from plugin, splice them into correct place in statement list and
+       file chains to preserve critical link order.
+       (lang_list_insert_after): New helper function.
+       (lang_list_remove_tail): Likewise.
+
+       2011-03-10  Dave Korn  <dave.korn.cygwin@gmail.com>
+       * plugin.c (IRONLY_SUFFIX): Revise to nicely human-readable form.
+       (IRONLY_SUFFIX_LEN): Delete.
+       (plugin_get_ir_dummy_bfd): Don't append IRONLY_SUFFIX.
+       (is_ir_dummy_bfd): Don't look for suffix; check claimed flag of
+       enclosing lang input statement instead.
+
+       2011-03-04  H.J. Lu  <hongjiu.lu@intel.com>
+       * ld.texinfo: Document --verbose[=NUMBER].
+       * lexsup.c (ld_options): Update --verbose.
+       (parse_args): Set report_plugin_symbols.
+       * plugin.c (report_plugin_symbols): New.
+       (get_symbols): Report plugin symbols if report_plugin_symbols
+       is TRUE.
+       * plugin.h (report_plugin_symbols): New.
+
+       2011-02-24  H.J. Lu  <hongjiu.lu@intel.com>
+       PR ld/12507
+       * plugin.c (get_symbols): Don't check entry symbol here.
+       (init_non_ironly_hash): Add entry_symbol chain into
+       non_ironly_hash.
+
+       2011-02-24  H.J. Lu  <hongjiu.lu@intel.com>
+       PR ld/12507
+       * plugin.c (get_symbols): Don't mark entry symbol IR only.
+
+       2010-12-06  H.J. Lu  <hongjiu.lu@intel.com>
+       * lexsup.c (ld_options): Add -flto and -flto-partition= for
+       GCC LTO option compatibility.
+
+       2010-12-01  H.J. Lu  <hongjiu.lu@intel.com>
+       * plugin.h: Re-indent.
+
 2011-04-20  Tristan Gingold  <gingold@adacore.com>
 
        * emultempl/aix.em (_add_options): Ignore -bbigtoc switch.
index 1a9862acc62f30c09afbeda07f72d2a5f40139f8..879bcfcd19b490d12df7f802317ca8bfeb925cfd 100644 (file)
@@ -1851,13 +1851,14 @@ Normally the linker will generate an error message for each reported
 unresolved symbol but the option @option{--warn-unresolved-symbols}
 can change this to a warning.
 
-@kindex --verbose
-@cindex verbose
+@kindex --verbose[=@var{NUMBER}]
+@cindex verbose[=@var{NUMBER}]
 @item --dll-verbose
-@itemx --verbose
+@itemx --verbose[=@var{NUMBER}]
 Display the version number for @command{ld} and list the linker emulations
 supported.  Display which input files can and cannot be opened.  Display
-the linker script being used by the linker.
+the linker script being used by the linker. If the optional @var{NUMBER}
+argument > 1, plugin symbol status will also be displayed.
 
 @kindex --version-script=@var{version-scriptfile}
 @cindex version script, symbol versions
index a9a69544d33cd9f8b38c3298d7fac28bb9041db7..7cd501c98b4a69ca8a1407a3d0a414740b4dcb06 100644 (file)
@@ -313,41 +313,19 @@ success:
      will be needed when and if we want to bfd_create a new
      one using this one as a template.  */
   if (bfd_check_format (entry->the_bfd, bfd_object)
-      && plugin_active_plugins_p ())
+      && plugin_active_plugins_p ()
+      && !no_more_claiming)
     {
       int fd = open (attempt, O_RDONLY | O_BINARY);
       if (fd >= 0)
        {
          struct ld_plugin_input_file file;
-         int claimed = 0;
 
          file.name = attempt;
          file.offset = 0;
          file.filesize = lseek (fd, 0, SEEK_END);
          file.fd = fd;
-         /* We create a dummy BFD, initially empty, to house
-            whatever symbols the plugin may want to add.  */
-         file.handle = plugin_get_ir_dummy_bfd (attempt, entry->the_bfd);
-         if (plugin_call_claim_file (&file, &claimed))
-           einfo (_("%P%F: %s: plugin reported error claiming file\n"),
-                  plugin_error_plugin ());
-         /* fd belongs to us, not the plugin; but we don't need it.  */
-         close (fd);
-         if (claimed)
-           {
-             /* Discard the real file's BFD and substitute the dummy one.  */
-             bfd_close (entry->the_bfd);
-             entry->the_bfd = file.handle;
-             entry->claimed = TRUE;
-             bfd_make_readable (entry->the_bfd);
-           }
-         else
-           {
-             /* If plugin didn't claim the file, we don't need the dummy
-                bfd.  Can't avoid speculatively creating it, alas.  */
-             bfd_close_all_done (file.handle);
-             entry->claimed = FALSE;
-           }
+         plugin_maybe_claim (&file, entry);
        }
     }
 #endif /* ENABLE_PLUGINS */
index 72564953590451e21fe696bf719e774e5753178a..2885743a982f96a2f4570e0745ac4f1d54e711c0 100644 (file)
@@ -1074,6 +1074,10 @@ new_afile (const char *name,
   p->whole_archive = whole_archive;
   p->loaded = FALSE;
   p->missing_file = FALSE;
+#ifdef ENABLE_PLUGINS
+  p->claimed = FALSE;
+  p->claim_archive = FALSE;
+#endif /* ENABLE_PLUGINS */
 
   lang_statement_append (&input_file_chain,
                         (lang_statement_union_type *) p,
@@ -3110,26 +3114,37 @@ init_opb (void)
 
 /* Open all the input files.  */
 
+enum open_bfd_mode
+  {
+    OPEN_BFD_NORMAL = 0,
+    OPEN_BFD_FORCE = 1,
+    OPEN_BFD_RESCAN = 2
+  };
+#ifdef ENABLE_PLUGINS
+static lang_input_statement_type *plugin_insert = NULL;
+#endif
+
 static void
-open_input_bfds (lang_statement_union_type *s, bfd_boolean force)
+open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode)
 {
   for (; s != NULL; s = s->header.next)
     {
       switch (s->header.type)
        {
        case lang_constructors_statement_enum:
-         open_input_bfds (constructor_list.head, force);
+         open_input_bfds (constructor_list.head, mode);
          break;
        case lang_output_section_statement_enum:
-         open_input_bfds (s->output_section_statement.children.head, force);
+         open_input_bfds (s->output_section_statement.children.head, mode);
          break;
        case lang_wild_statement_enum:
          /* Maybe we should load the file's symbols.  */
-         if (s->wild_statement.filename
+         if ((mode & OPEN_BFD_RESCAN) == 0
+             && s->wild_statement.filename
              && !wildcardp (s->wild_statement.filename)
              && !archive_path (s->wild_statement.filename))
            lookup_name (s->wild_statement.filename);
-         open_input_bfds (s->wild_statement.children.head, force);
+         open_input_bfds (s->wild_statement.children.head, mode);
          break;
        case lang_group_statement_enum:
          {
@@ -3142,7 +3157,8 @@ open_input_bfds (lang_statement_union_type *s, bfd_boolean force)
            do
              {
                undefs = link_info.hash->undefs_tail;
-               open_input_bfds (s->group_statement.children.head, TRUE);
+               open_input_bfds (s->group_statement.children.head,
+                                mode | OPEN_BFD_FORCE);
              }
            while (undefs != link_info.hash->undefs_tail);
          }
@@ -3161,8 +3177,12 @@ open_input_bfds (lang_statement_union_type *s, bfd_boolean force)
              /* If we are being called from within a group, and this
                 is an archive which has already been searched, then
                 force it to be researched unless the whole archive
-                has been loaded already.  */
-             if (force
+                has been loaded already.  Do the same for a rescan.  */
+             if (mode != OPEN_BFD_NORMAL
+#ifdef ENABLE_PLUGINS
+                 && ((mode & OPEN_BFD_RESCAN) == 0
+                     || plugin_insert == NULL)
+#endif
                  && !s->input_statement.whole_archive
                  && s->input_statement.loaded
                  && bfd_check_format (s->input_statement.the_bfd,
@@ -3198,6 +3218,12 @@ open_input_bfds (lang_statement_union_type *s, bfd_boolean force)
                    }
                }
            }
+#ifdef ENABLE_PLUGINS
+         /* If we have found the point at which a plugin added new
+            files, clear plugin_insert to enable archive rescan.  */
+         if (&s->input_statement == plugin_insert)
+           plugin_insert = NULL;
+#endif
          break;
        case lang_assignment_statement_enum:
          if (s->assignment_statement.exp->assign.hidden)
@@ -5690,6 +5716,11 @@ lang_check (void)
 
   for (file = file_chain.head; file != NULL; file = file->input_statement.next)
     {
+#ifdef ENABLE_PLUGINS
+      /* Don't check format of files claimed by plugin.  */
+      if (file->input_statement.claimed)
+       continue;
+#endif /* ENABLE_PLUGINS */
       input_bfd = file->input_statement.the_bfd;
       compatible
        = bfd_arch_get_compatible (input_bfd, link_info.output_bfd,
@@ -6201,6 +6232,10 @@ lang_gc_sections (void)
       LANG_FOR_EACH_INPUT_STATEMENT (f)
        {
          asection *sec;
+#ifdef ENABLE_PLUGINS
+         if (f->claimed)
+           continue;
+#endif
          for (sec = f->the_bfd->sections; sec != NULL; sec = sec->next)
            if ((sec->flags & SEC_DEBUGGING) == 0)
              sec->flags &= ~SEC_EXCLUDE;
@@ -6342,6 +6377,72 @@ lang_relax_sections (bfd_boolean need_layout)
     }
 }
 
+#ifdef ENABLE_PLUGINS
+/* Find the insert point for the plugin's replacement files.  We
+   place them after the first claimed real object file, or if the
+   first claimed object is an archive member, after the last real
+   object file immediately preceding the archive.  In the event
+   no objects have been claimed at all, we return the first dummy
+   object file on the list as the insert point; that works, but
+   the callee must be careful when relinking the file_chain as it
+   is not actually on that chain, only the statement_list and the
+   input_file list; in that case, the replacement files must be
+   inserted at the head of the file_chain.  */
+
+static lang_input_statement_type *
+find_replacements_insert_point (void)
+{
+  lang_input_statement_type *claim1, *lastobject;
+  lastobject = &input_file_chain.head->input_statement;
+  for (claim1 = &file_chain.head->input_statement;
+       claim1 != NULL;
+       claim1 = &claim1->next->input_statement)
+    {
+      if (claim1->claimed)
+       return claim1->claim_archive ? lastobject : claim1;
+      /* Update lastobject if this is a real object file.  */
+      if (claim1->the_bfd && (claim1->the_bfd->my_archive == NULL))
+       lastobject = claim1;
+    }
+  /* No files were claimed by the plugin.  Choose the last object
+     file found on the list (maybe the first, dummy entry) as the
+     insert point.  */
+  return lastobject;
+}
+
+/* Insert SRCLIST into DESTLIST after given element by chaining
+   on FIELD as the next-pointer.  (Counterintuitively does not need
+   a pointer to the actual after-node itself, just its chain field.)  */
+
+static void
+lang_list_insert_after (lang_statement_list_type *destlist,
+                       lang_statement_list_type *srclist,
+                       lang_statement_union_type **field)
+{
+  *(srclist->tail) = *field;
+  *field = srclist->head;
+  if (destlist->tail == field)
+    destlist->tail = srclist->tail;
+}
+
+/* Detach new nodes added to DESTLIST since the time ORIGLIST
+   was taken as a copy of it and leave them in ORIGLIST.  */
+
+static void
+lang_list_remove_tail (lang_statement_list_type *destlist,
+                      lang_statement_list_type *origlist)
+{
+  union lang_statement_union **savetail;
+  /* Check that ORIGLIST really is an earlier state of DESTLIST.  */
+  ASSERT (origlist->head == destlist->head);
+  savetail = origlist->tail;
+  origlist->head = *(savetail);
+  origlist->tail = destlist->tail;
+  destlist->tail = savetail;
+  *savetail = NULL;
+}
+#endif /* ENABLE_PLUGINS */
+
 void
 lang_process (void)
 {
@@ -6365,24 +6466,62 @@ lang_process (void)
 
   /* Create a bfd for each input file.  */
   current_target = default_target;
-  open_input_bfds (statement_list.head, FALSE);
+  open_input_bfds (statement_list.head, OPEN_BFD_NORMAL);
 
 #ifdef ENABLE_PLUGINS
+  if (plugin_active_plugins_p ())
     {
-      union lang_statement_union **listend;
+      lang_statement_list_type added;
+      lang_statement_list_type files, inputfiles;
+
       /* Now all files are read, let the plugin(s) decide if there
         are any more to be added to the link before we call the
-        emulation's after_open hook.  */
-      listend = statement_list.tail;
-      ASSERT (!*listend);
+        emulation's after_open hook.  We create a private list of
+        input statements for this purpose, which we will eventually
+        insert into the global statment list after the first claimed
+        file.  */
+      added = *stat_ptr;
+      /* We need to manipulate all three chains in synchrony.  */
+      files = file_chain;
+      inputfiles = input_file_chain;
       if (plugin_call_all_symbols_read ())
        einfo (_("%P%F: %s: plugin reported error after all symbols read\n"),
               plugin_error_plugin ());
-      /* If any new files were added, they will be on the end of the
-        statement list, and we can open them now by getting open_input_bfds
-        to carry on from where it ended last time.  */
-      if (*listend)
-       open_input_bfds (*listend, FALSE);
+      /* Open any newly added files, updating the file chains.  */
+      open_input_bfds (added.head, OPEN_BFD_NORMAL);
+      /* Restore the global list pointer now they have all been added.  */
+      lang_list_remove_tail (stat_ptr, &added);
+      /* And detach the fresh ends of the file lists.  */
+      lang_list_remove_tail (&file_chain, &files);
+      lang_list_remove_tail (&input_file_chain, &inputfiles);
+      /* Were any new files added?  */
+      if (added.head != NULL)
+       {
+         /* If so, we will insert them into the statement list immediately
+            after the first input file that was claimed by the plugin.  */
+         plugin_insert = find_replacements_insert_point ();
+         /* If a plugin adds input files without having claimed any, we
+            don't really have a good idea where to place them.  Just putting
+            them at the start or end of the list is liable to leave them
+            outside the crtbegin...crtend range.  */
+         ASSERT (plugin_insert != NULL);
+         /* Splice the new statement list into the old one.  */
+         lang_list_insert_after (stat_ptr, &added,
+                                 &plugin_insert->header.next);
+         /* Likewise for the file chains.  */
+         lang_list_insert_after (&input_file_chain, &inputfiles,
+                                 &plugin_insert->next_real_file);
+         /* We must be careful when relinking file_chain; we may need to
+            insert the new files at the head of the list if the insert
+            point chosen is the dummy first input file.  */
+         if (plugin_insert->filename)
+           lang_list_insert_after (&file_chain, &files, &plugin_insert->next);
+         else
+           lang_list_insert_after (&file_chain, &files, &file_chain.head);
+
+         /* Rescan archives in case new undefined symbols have appeared.  */
+         open_input_bfds (statement_list.head, OPEN_BFD_RESCAN);
+       }
     }
 #endif /* ENABLE_PLUGINS */
 
index 9d4d41f44311ff76c88953a4533d766a93c0bb8b..cff4f252c562bdd3853efb9e9a8096c011a61268 100644 (file)
@@ -287,9 +287,14 @@ typedef struct lang_input_statement_struct
   /* Set if the file does not exist.  */
   unsigned int missing_file : 1;
 
+#ifdef ENABLE_PLUGINS
   /* Set if the file was claimed by a plugin.  */
   unsigned int claimed : 1;
 
+  /* Set if the file was claimed from an archive.  */
+  unsigned int claim_archive : 1;
+#endif /* ENABLE_PLUGINS */
+
 } lang_input_statement_type;
 
 typedef struct
index 6e86c3d996fa763fedf2e489501d0366f63ace43..bfa6066b097a93b4ac63bd00219be96c6b0dd8cd 100644 (file)
@@ -123,11 +123,11 @@ static char *get_emulation
 static bfd_boolean add_archive_element
   (struct bfd_link_info *, bfd *, const char *, bfd **);
 static bfd_boolean multiple_definition
-  (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma,
+  (struct bfd_link_info *, struct bfd_link_hash_entry *,
    bfd *, asection *, bfd_vma);
 static bfd_boolean multiple_common
-  (struct bfd_link_info *, const char *, bfd *, enum bfd_link_hash_type,
-   bfd_vma, bfd *, enum bfd_link_hash_type, bfd_vma);
+  (struct bfd_link_info *, struct bfd_link_hash_entry *,
+   bfd *, enum bfd_link_hash_type, bfd_vma);
 static bfd_boolean add_to_set
   (struct bfd_link_info *, struct bfd_link_hash_entry *,
    bfd_reloc_code_real_type, bfd *, asection *, bfd_vma);
@@ -150,7 +150,8 @@ static bfd_boolean reloc_dangerous
 static bfd_boolean unattached_reloc
   (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma);
 static bfd_boolean notice
-  (struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma);
+  (struct bfd_link_info *, struct bfd_link_hash_entry *,
+   bfd *, asection *, bfd_vma);
 
 static struct bfd_link_callbacks link_callbacks =
 {
@@ -804,14 +805,16 @@ 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 (bfd_my_archive (abfd) != NULL && plugin_active_plugins_p ())
+  if (bfd_my_archive (abfd) != NULL
+      && plugin_active_plugins_p ()
+      && !no_more_claiming)
     {
       /* We must offer this archive member to the plugins to claim.  */
       int fd = open (bfd_my_archive (abfd)->filename, O_RDONLY | O_BINARY);
       if (fd >= 0)
        {
          struct ld_plugin_input_file file;
-         int claimed = 0;
+
          /* Offset and filesize must refer to the individual archive
             member, not the whole file, and must exclude the header.
             Fortunately for us, that is how the data is stored in the
@@ -820,28 +823,12 @@ add_archive_element (struct bfd_link_info *info,
          file.offset = abfd->origin;
          file.filesize = arelt_size (abfd);
          file.fd = fd;
-         /* We create a dummy BFD, initially empty, to house
-            whatever symbols the plugin may want to add.  */
-         file.handle = plugin_get_ir_dummy_bfd (abfd->filename, abfd);
-         if (plugin_call_claim_file (&file, &claimed))
-           einfo (_("%P%F: %s: plugin reported error claiming file\n"),
-                  plugin_error_plugin ());
-         /* fd belongs to us, not the plugin; but we don't need it.  */
-         close (fd);
-         if (claimed)
+         plugin_maybe_claim (&file, input);
+         if (input->claimed)
            {
-             /* Substitute the dummy BFD.  */
-             input->the_bfd = file.handle;
-             input->claimed = TRUE;
-             bfd_make_readable (input->the_bfd);
+             input->claim_archive = TRUE;
              *subsbfd = input->the_bfd;
            }
-         else
-           {
-             /* Abandon the dummy BFD.  */
-             bfd_close_all_done (file.handle);
-             input->claimed = FALSE;
-           }
        }
     }
 #endif /* ENABLE_PLUGINS */
@@ -934,31 +921,49 @@ add_archive_element (struct bfd_link_info *info,
    multiple times.  */
 
 static bfd_boolean
-multiple_definition (struct bfd_link_info *info ATTRIBUTE_UNUSED,
-                    const char *name,
-                    bfd *obfd,
-                    asection *osec,
-                    bfd_vma oval,
+multiple_definition (struct bfd_link_info *info,
+                    struct bfd_link_hash_entry *h,
                     bfd *nbfd,
                     asection *nsec,
                     bfd_vma nval)
 {
-#ifdef ENABLE_PLUGINS
-  /* We may get called back even when --allow-multiple-definition is in
-     effect, as the plugin infrastructure needs to use this hook in
-     order to swap out IR-only symbols for real ones.  In that case,
-     it will let us know not to continue by returning TRUE even if this
-     is not an IR-only vs. non-IR symbol conflict.  */
-  if (plugin_multiple_definition (info, name, obfd, osec, oval, nbfd,
-                                 nsec, nval))
+  const char *name;
+  bfd *obfd;
+  asection *osec;
+  bfd_vma oval;
+
+  if (info->allow_multiple_definition)
+    return TRUE;
+
+  switch (h->type)
+    {
+    case bfd_link_hash_defined:
+      osec = h->u.def.section;
+      oval = h->u.def.value;
+      obfd = h->u.def.section->owner;
+      break;
+    case bfd_link_hash_indirect:
+      osec = bfd_ind_section_ptr;
+      oval = 0;
+      obfd = NULL;
+      break;
+    default:
+      abort ();
+    }
+
+  /* Ignore a redefinition of an absolute symbol to the
+     same value; it's harmless.  */
+  if (h->type == bfd_link_hash_defined
+      && bfd_is_abs_section (osec)
+      && bfd_is_abs_section (nsec)
+      && nval == oval)
     return TRUE;
-#endif /* ENABLE_PLUGINS */
 
   /* If either section has the output_section field set to
      bfd_abs_section_ptr, it means that the section is being
      discarded, and this is not really a multiple definition at all.
-FIXME: It would be cleaner to somehow ignore symbols defined in
-sections which are being discarded.  */
+     FIXME: It would be cleaner to somehow ignore symbols defined in
+     sections which are being discarded.  */
   if ((osec->output_section != NULL
        && ! bfd_is_abs_section (osec)
        && bfd_is_abs_section (osec->output_section))
@@ -967,6 +972,14 @@ sections which are being discarded.  */
          && bfd_is_abs_section (nsec->output_section)))
     return TRUE;
 
+  name = h->root.string;
+  if (nbfd == NULL)
+    {
+      nbfd = obfd;
+      nsec = osec;
+      nval = oval;
+      obfd = NULL;
+    }
   einfo (_("%X%C: multiple definition of `%T'\n"),
         nbfd, nsec, nval, name);
   if (obfd != NULL)
@@ -988,17 +1001,41 @@ sections which are being discarded.  */
 
 static bfd_boolean
 multiple_common (struct bfd_link_info *info ATTRIBUTE_UNUSED,
-                const char *name,
-                bfd *obfd,
-                enum bfd_link_hash_type otype,
-                bfd_vma osize,
+                struct bfd_link_hash_entry *h,
                 bfd *nbfd,
                 enum bfd_link_hash_type ntype,
                 bfd_vma nsize)
 {
-  if (! config.warn_common)
+  const char *name;
+  bfd *obfd;
+  enum bfd_link_hash_type otype;
+  bfd_vma osize;
+
+  if (!config.warn_common)
     return TRUE;
 
+  name = h->root.string;
+  otype = h->type;
+  if (otype == bfd_link_hash_common)
+    {
+      obfd = h->u.c.p->section->owner;
+      osize = h->u.c.size;
+    }
+  else if (otype == bfd_link_hash_defined
+          || otype == bfd_link_hash_defweak)
+    {
+      obfd = h->u.def.section->owner;
+      osize = 0;
+    }
+  else
+    {
+      /* FIXME: It would nice if we could report the BFD which defined
+        an indirect symbol, but we don't have anywhere to store the
+        information.  */
+      obfd = NULL;
+      osize = 0;
+    }
+
   if (ntype == bfd_link_hash_defined
       || ntype == bfd_link_hash_defweak
       || ntype == bfd_link_hash_indirect)
@@ -1443,29 +1480,23 @@ unattached_reloc (struct bfd_link_info *info ATTRIBUTE_UNUSED,
 
 static bfd_boolean
 notice (struct bfd_link_info *info,
-       const char *name,
+       struct bfd_link_hash_entry *h,
        bfd *abfd,
        asection *section,
        bfd_vma value)
 {
-  if (name == NULL)
+  const char *name;
+
+  if (h == NULL)
     {
       if (command_line.cref || nocrossref_list != NULL)
        return handle_asneeded_cref (abfd, (enum notice_asneeded_action) value);
       return TRUE;
     }
 
-#ifdef ENABLE_PLUGINS
-  /* We should hide symbols in the dummy IR BFDs from the nocrossrefs list
-     and let the real object files that are generated and added later trip
-     the error instead.  Similarly would be better to trace the real symbol
-     from the real file than the temporary dummy.  */
-  if (!plugin_notice (info, name, abfd, section, value))
-    return TRUE;
-#endif /* ENABLE_PLUGINS */
-
+  name = h->root.string;
   if (info->notice_hash != NULL
-       && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL)
+      && bfd_hash_lookup (info->notice_hash, name, FALSE, FALSE) != NULL)
     {
       if (bfd_is_und_section (section))
        einfo ("%B: reference to %s\n", abfd, name);
index b6274f89217df3f1da3d8f922da381e33f9d4035..e9e89be193ffbd903c78ef2f2fb5dde30bae508c 100644 (file)
@@ -283,6 +283,12 @@ static const struct ld_option ld_options[] =
     '\0', N_("PLUGIN"), N_("Load named plugin"), ONE_DASH },
   { {"plugin-opt", required_argument, NULL, OPTION_PLUGIN_OPT},
     '\0', N_("ARG"), N_("Send arg to last-loaded plugin"), ONE_DASH },
+  { {"flto", optional_argument, NULL, OPTION_IGNORE},
+    '\0', NULL, N_("Ignored for GCC LTO option compatibility"),
+    ONE_DASH },
+  { {"flto-partition=", required_argument, NULL, OPTION_IGNORE},
+    '\0', NULL, N_("Ignored for GCC LTO option compatibility"),
+    ONE_DASH },
 #endif /* ENABLE_PLUGINS */
   { {"Qy", no_argument, NULL, OPTION_IGNORE},
     '\0', NULL, N_("Ignored for SVR4 compatibility"), ONE_DASH },
@@ -555,8 +561,9 @@ static const struct ld_option ld_options[] =
                   "                                ignore-all, report-all, ignore-in-object-files,\n"
                   "                                ignore-in-shared-libs"),
     TWO_DASHES },
-  { {"verbose", no_argument, NULL, OPTION_VERBOSE},
-    '\0', NULL, N_("Output lots of information during link"), TWO_DASHES },
+  { {"verbose", optional_argument, NULL, OPTION_VERBOSE},
+    '\0', N_("[=NUMBER]"),
+    N_("Output lots of information during link"), TWO_DASHES },
   { {"dll-verbose", no_argument, NULL, OPTION_VERBOSE}, /* Linux.  */
     '\0', NULL, NULL, NO_HELP },
   { {"version-script", required_argument, NULL, OPTION_VERSION_SCRIPT },
@@ -1321,6 +1328,16 @@ parse_args (unsigned argc, char **argv)
          version_printed = TRUE;
          trace_file_tries = TRUE;
          overflow_cutoff_limit = -2;
+         if (optarg != NULL)
+           {
+             char *end;
+             int level ATTRIBUTE_UNUSED = strtoul (optarg, &end, 0);
+             if (*end)
+               einfo (_("%P%F: invalid number `%s'\n"), optarg);
+#ifdef ENABLE_PLUGINS
+             report_plugin_symbols = level > 1;
+#endif /* ENABLE_PLUGINS */
+           }
          break;
        case 'v':
          ldversion (0);
index 86d80ca4a15e83e783d66b1987eb4e403fb6fba9..42c737025b14deb9901663ec74814b3d0637dae5 100644 (file)
 #include <Windows.h>
 #endif
 
+/* Report plugin symbols.  */
+bfd_boolean report_plugin_symbols;
+
 /* The suffix to append to the name of the real (claimed) object file
    when generating a dummy BFD to hold the IR symbols sent from the
-   plugin.  */
-#define IRONLY_SUFFIX          ".ironly\004"
-
-/* This is sizeof an array of chars, not sizeof a const char *.  We
-   also have to avoid inadvertently counting the trailing NUL.  */
-#define IRONLY_SUFFIX_LEN      (sizeof (IRONLY_SUFFIX) - 1)
+   plugin.  For cosmetic use only; appears in maps, crefs etc.  */
+#define IRONLY_SUFFIX " (symbol from plugin)"
 
 /* Stores a single argument passed to a plugin.  */
 typedef struct plugin_arg
@@ -91,22 +90,16 @@ static plugin_t *called_plugin = NULL;
 /* Last plugin to cause an error, if any.  */
 static const char *error_plugin = NULL;
 
-/* A hash table that records symbols referenced by non-IR files.  Used
-   at get_symbols time to determine whether any prevailing defs from
-   IR files are referenced only from other IR files, so tthat we can
-   we can distinguish the LDPR_PREVAILING_DEF and LDPR_PREVAILING_DEF_IRONLY
-   cases when establishing symbol resolutions.  */
-static struct bfd_hash_table *non_ironly_hash = NULL;
+/* State of linker "notice" interface before we poked at it.  */
+static bfd_boolean orig_notice_all;
+
+/* Original linker callbacks, and the plugin version.  */
+static const struct bfd_link_callbacks *orig_callbacks;
+static struct bfd_link_callbacks plugin_callbacks;
 
 /* Set at all symbols read time, to avoid recursively offering the plugin
    its own newly-added input files and libs to claim.  */
-static bfd_boolean no_more_claiming = FALSE;
-
-/* If the --allow-multiple-definition command-line option is active, we
-   have to disable it so that BFD always calls our hook, and simulate the
-   effect (when not resolving IR vs. real symbols) ourselves by ensuring
-   TRUE is returned from the hook.  */
-static bfd_boolean plugin_cached_allow_multiple_defs = FALSE;
+bfd_boolean no_more_claiming = FALSE;
 
 /* List of tags to set in the constant leading part of the tv array. */
 static const enum ld_plugin_tag tv_header_tags[] =
@@ -131,6 +124,11 @@ static const enum ld_plugin_tag tv_header_tags[] =
 /* How many entries in the constant leading part of the tv array.  */
 static const size_t tv_header_size = ARRAY_SIZE (tv_header_tags);
 
+/* Forward references.  */
+static bfd_boolean plugin_notice (struct bfd_link_info *info,
+                                 struct bfd_link_hash_entry *h, bfd *abfd,
+                                 asection *section, bfd_vma value);
+
 #if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
 
 #define RTLD_NOW 0     /* Dummy value.  */
@@ -226,38 +224,44 @@ plugin_opt_plugin_arg (const char *arg)
 bfd *
 plugin_get_ir_dummy_bfd (const char *name, bfd *srctemplate)
 {
-  asection *sec;
   bfd *abfd;
 
   bfd_use_reserved_id = 1;
-  abfd = bfd_create (concat (name, IRONLY_SUFFIX, (const char *)NULL),
+  abfd = bfd_create (concat (name, IRONLY_SUFFIX, (const char *) NULL),
                     srctemplate);
-  bfd_set_arch_info (abfd, bfd_get_arch_info (srctemplate));
-  bfd_make_writable (abfd);
-  bfd_copy_private_bfd_data (srctemplate, abfd);
-  bfd_set_gp_size (abfd, bfd_get_gp_size (abfd));
-  /* Create a minimal set of sections to own the symbols.  */
-  sec = bfd_make_section_old_way (abfd, ".text");
-  bfd_set_section_flags (abfd, sec,
-                        (SEC_CODE | SEC_HAS_CONTENTS | SEC_READONLY
-                         | SEC_ALLOC | SEC_LOAD | SEC_KEEP));
-  sec->output_section = sec;
-  sec->output_offset = 0;
-  return abfd;
+  if (abfd != NULL)
+    {
+      abfd->flags |= BFD_LINKER_CREATED | BFD_PLUGIN;
+      bfd_set_arch_info (abfd, bfd_get_arch_info (srctemplate));
+      bfd_set_gp_size (abfd, bfd_get_gp_size (srctemplate));
+      if (bfd_make_writable (abfd)
+         && bfd_copy_private_bfd_data (srctemplate, abfd))
+       {
+         flagword flags;
+
+         /* Create sections to own the symbols.  */
+         flags = (SEC_CODE | SEC_HAS_CONTENTS | SEC_READONLY
+                  | SEC_ALLOC | SEC_LOAD | SEC_KEEP | SEC_EXCLUDE);
+         if (bfd_make_section_anyway_with_flags (abfd, ".text", flags))
+           return abfd;
+       }
+    }
+  einfo (_("could not create dummy IR bfd: %F%E\n"));
+  return NULL;
 }
 
 /* Check if the BFD passed in is an IR dummy object file.  */
 static bfd_boolean
 is_ir_dummy_bfd (const bfd *abfd)
 {
-  size_t namlen;
-
-  if (abfd == NULL)
-    return FALSE;
-  namlen = strlen (abfd->filename);
-  if (namlen < IRONLY_SUFFIX_LEN)
-    return FALSE;
-  return !strcmp (abfd->filename + namlen - IRONLY_SUFFIX_LEN, IRONLY_SUFFIX);
+  /* ABFD can sometimes legitimately be NULL, e.g. when called from one
+     of the linker callbacks for a symbol in the *ABS* or *UND* sections.
+     Likewise, the usrdata field may be NULL if ABFD was added by the
+     backend without a corresponding input statement, as happens e.g.
+     when processing DT_NEEDED dependencies.  */
+  return (abfd
+         && abfd->usrdata
+         && ((lang_input_statement_type *)(abfd->usrdata))->claimed);
 }
 
 /* Helpers to convert between BFD and GOLD symbol formats.  */
@@ -270,7 +274,7 @@ asymbol_from_plugin_symbol (bfd *abfd, asymbol *asym,
 
   asym->the_bfd = abfd;
   asym->name = (ldsym->version
-               ? concat (ldsym->name, "@", ldsym->version, NULL)
+               ? concat (ldsym->name, "@", ldsym->version, (const char *) NULL)
                : ldsym->name);
   asym->value = 0;
   switch (ldsym->def)
@@ -296,7 +300,10 @@ asymbol_from_plugin_symbol (bfd *abfd, asymbol *asym,
       asym->value = ldsym->size;
       /* For ELF targets, set alignment of common symbol to 1.  */
       if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
-       ((elf_symbol_type *) asym)->internal_elf_sym.st_value = 1;
+       {
+         ((elf_symbol_type *) asym)->internal_elf_sym.st_shndx = SHN_COMMON;
+         ((elf_symbol_type *) asym)->internal_elf_sym.st_value = 1;
+       }
       break;
 
     default:
@@ -414,6 +421,8 @@ static inline bfd_boolean
 is_visible_from_outside (struct ld_plugin_symbol *lsym, asection *section,
                         struct bfd_link_hash_entry *blhe)
 {
+  struct bfd_sym_chain *sym;
+
   /* Section's owner may be NULL if it is the absolute
      section, fortunately is_ir_dummy_bfd handles that.  */
   if (!is_ir_dummy_bfd (section->owner))
@@ -442,6 +451,12 @@ is_visible_from_outside (struct ld_plugin_symbol *lsym, asection *section,
       return (lsym->visibility == LDPV_DEFAULT
              || lsym->visibility == LDPV_PROTECTED);
     }
+
+  for (sym = &entry_symbol; sym != NULL; sym = sym->next)
+    if (sym->name
+       && strcmp (sym->name, blhe->root.string) == 0)
+      return TRUE;
+
   return FALSE;
 }
 
@@ -457,13 +472,16 @@ get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms)
       struct bfd_link_hash_entry *blhe;
       bfd_boolean ironly;
       asection *owner_sec;
-
-      blhe = bfd_link_hash_lookup (link_info.hash, syms[n].name,
-                                  FALSE, FALSE, TRUE);
+      if (syms[n].def != LDPK_UNDEF)
+       blhe = bfd_link_hash_lookup (link_info.hash, syms[n].name,
+                                    FALSE, FALSE, TRUE);
+      else
+       blhe = bfd_wrapped_link_hash_lookup (link_info.output_bfd, &link_info,
+                                            syms[n].name, FALSE, FALSE, TRUE);
       if (!blhe)
        {
          syms[n].resolution = LDPR_UNKNOWN;
-         continue;
+         goto report_symbol;
        }
 
       /* Determine resolution from blhe type and symbol's original type.  */
@@ -471,7 +489,7 @@ get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms)
          || blhe->type == bfd_link_hash_undefweak)
        {
          syms[n].resolution = LDPR_UNDEF;
-         continue;
+         goto report_symbol;
        }
       if (blhe->type != bfd_link_hash_defined
          && blhe->type != bfd_link_hash_defweak
@@ -485,16 +503,16 @@ get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms)
       /* Find out which section owns the symbol.  Since it's not undef,
         it must have an owner; if it's not a common symbol, both defs
         and weakdefs keep it in the same place. */
-      owner_sec = (blhe->type == bfd_link_hash_common)
-       ? blhe->u.c.p->section
-       : blhe->u.def.section;
+      owner_sec = (blhe->type == bfd_link_hash_common
+                  ? blhe->u.c.p->section
+                  : blhe->u.def.section);
 
       /* We need to know if the sym is referenced from non-IR files.  Or
         even potentially-referenced, perhaps in a future final link if
         this is a partial one, perhaps dynamically at load-time if the
         symbol is externally visible.  */
-      ironly = !is_visible_from_outside (&syms[n], owner_sec, blhe)
-       && !bfd_hash_lookup (non_ironly_hash, syms[n].name, FALSE, FALSE);
+      ironly = !(blhe->non_ir_ref
+                || is_visible_from_outside (&syms[n], owner_sec, blhe));
 
       /* If it was originally undefined or common, then it has been
         resolved; determine how.  */
@@ -515,7 +533,7 @@ get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms)
            syms[n].resolution =  LDPR_RESOLVED_DYN;
          else
            syms[n].resolution = LDPR_RESOLVED_EXEC;
-         continue;
+         goto report_symbol;
        }
 
       /* Was originally def, or weakdef.  Does it prevail?  If the
@@ -528,13 +546,20 @@ get_symbols (const void *handle, int nsyms, struct ld_plugin_symbol *syms)
          syms[n].resolution = (ironly
                                ? LDPR_PREVAILING_DEF_IRONLY
                                : LDPR_PREVAILING_DEF);
-         continue;
+         goto report_symbol;
        }
 
       /* Was originally def, weakdef, or common, but has been pre-empted.  */
-      syms[n].resolution = is_ir_dummy_bfd (owner_sec->owner)
-       ? LDPR_PREEMPTED_IR
-       : LDPR_PREEMPTED_REG;
+      syms[n].resolution = (is_ir_dummy_bfd (owner_sec->owner)
+                           ? LDPR_PREEMPTED_IR
+                           : LDPR_PREEMPTED_REG);
+
+    report_symbol:
+      if (report_plugin_symbols)
+       einfo (_("%P: %B: symbol `%s' "
+                "definition: %d, visibility: %d, resolution: %d\n"),
+              abfd, syms[n].name,
+              syms[n].def, syms[n].visibility, syms[n].resolution);
     }
   return LDPS_OK;
 }
@@ -591,14 +616,13 @@ message (int level, const char *format, ...)
     case LDPL_FATAL:
     case LDPL_ERROR:
     default:
-       {
-         char *newfmt = ACONCAT ((level == LDPL_FATAL
-                                  ? "%P%F: " : "%P%X: ",
-                                  format, "\n", NULL));
-         fflush (stdout);
-         vfinfo (stderr, newfmt, args, TRUE);
-         fflush (stderr);
-       }
+      {
+       char *newfmt = ACONCAT ((level == LDPL_FATAL ? "%P%F: " : "%P%X: ",
+                                format, "\n", (const char *) NULL));
+       fflush (stdout);
+       vfinfo (stderr, newfmt, args, TRUE);
+       fflush (stderr);
+      }
       break;
     }
 
@@ -753,13 +777,18 @@ plugin_load_plugins (void)
   /* Since plugin(s) inited ok, assume they're going to want symbol
      resolutions, which needs us to track which symbols are referenced
      by non-IR files using the linker's notice callback.  */
+  orig_notice_all = link_info.notice_all;
+  orig_callbacks = link_info.callbacks;
+  plugin_callbacks = *orig_callbacks;
+  plugin_callbacks.notice = &plugin_notice;
   link_info.notice_all = TRUE;
+  link_info.callbacks = &plugin_callbacks;
 
   return 0;
 }
 
 /* Call 'claim file' hook for all plugins.  */
-int
+static int
 plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed)
 {
   plugin_t *curplug = plugins_list;
@@ -782,6 +811,42 @@ plugin_call_claim_file (const struct ld_plugin_input_file *file, int *claimed)
   return plugin_error_p () ? -1 : 0;
 }
 
+void
+plugin_maybe_claim (struct ld_plugin_input_file *file,
+                   lang_input_statement_type *entry)
+{
+  int claimed = 0;
+
+  /* We create a dummy BFD, initially empty, to house whatever symbols
+     the plugin may want to add.  */
+  file->handle = plugin_get_ir_dummy_bfd (entry->the_bfd->filename,
+                                         entry->the_bfd);
+  if (plugin_call_claim_file (file, &claimed))
+    einfo (_("%P%F: %s: plugin reported error claiming file\n"),
+          plugin_error_plugin ());
+  /* fd belongs to us, not the plugin; but we don't need it.  */
+  close (file->fd);
+  if (claimed)
+    {
+      /* Discard the real file's BFD and substitute the dummy one.  */
+
+      /* BFD archive handling caches elements so we can't call
+        bfd_close for archives.  */
+      if (entry->the_bfd->my_archive == NULL)
+       bfd_close (entry->the_bfd);
+      entry->the_bfd = file->handle;
+      entry->claimed = TRUE;
+      bfd_make_readable (entry->the_bfd);
+    }
+  else
+    {
+      /* If plugin didn't claim the file, we don't need the dummy bfd.
+        Can't avoid speculatively creating it, alas.  */
+      bfd_close_all_done (file->handle);
+      entry->claimed = FALSE;
+    }
+}
+
 /* Call 'all symbols read' hook for all plugins.  */
 int
 plugin_call_all_symbols_read (void)
@@ -791,13 +856,6 @@ plugin_call_all_symbols_read (void)
   /* Disable any further file-claiming.  */
   no_more_claiming = TRUE;
 
-  /* If --allow-multiple-definition is in effect, we need to disable it,
-     as the plugin infrastructure relies on the multiple_definition
-     callback to swap out the dummy IR-only BFDs for new real ones
-     when it starts opening the files added during this callback.  */
-  plugin_cached_allow_multiple_defs = link_info.allow_multiple_definition;
-  link_info.allow_multiple_definition = FALSE;
-
   while (curplug)
     {
       if (curplug->all_symbols_read_handler)
@@ -839,87 +897,49 @@ plugin_call_cleanup (void)
              plugin_error_plugin ());
 }
 
-/* Lazily init the non_ironly hash table.  */
-static void
-init_non_ironly_hash (void)
-{
-  if (non_ironly_hash == NULL)
-    {
-      non_ironly_hash =
-       (struct bfd_hash_table *) xmalloc (sizeof (struct bfd_hash_table));
-      if (!bfd_hash_table_init_n (non_ironly_hash,
-                                 bfd_hash_newfunc,
-                                 sizeof (struct bfd_hash_entry),
-                                 61))
-       einfo (_("%P%F: bfd_hash_table_init failed: %E\n"));
-    }
-}
-
 /* To determine which symbols should be resolved LDPR_PREVAILING_DEF
    and which LDPR_PREVAILING_DEF_IRONLY, we notice all the symbols as
-   the linker adds them to the linker hash table.  If we see a symbol
-   being referenced from a non-IR file, we add it to the non_ironly hash
-   table.  If we can't find it there at get_symbols time, we know that
-   it was referenced only by IR files.  We have to notice_all symbols,
-   because we won't necessarily know until later which ones will be
-   contributed by IR files.  */
-bfd_boolean
-plugin_notice (struct bfd_link_info *info ATTRIBUTE_UNUSED,
-              const char *name, bfd *abfd,
-              asection *section, bfd_vma value ATTRIBUTE_UNUSED)
-{
-  bfd_boolean is_ref = bfd_is_und_section (section);
-  bfd_boolean is_dummy = is_ir_dummy_bfd (abfd);
-  init_non_ironly_hash ();
-  /* We only care about refs, not defs, indicated by section pointing
-     to the undefined section (according to the bfd linker notice callback
-     interface definition).  */
-  if (is_ref && !is_dummy)
-    {
-      /* This is a ref from a non-IR file, so note the ref'd symbol
-        in the non-IR-only hash.  */
-      if (!bfd_hash_lookup (non_ironly_hash, name, TRUE, TRUE))
-       einfo (_("%P%X: %s: hash table failure adding symbol %s\n"),
-              abfd->filename, name);
-    }
-  else if (!is_ref && is_dummy)
+   the linker adds them to the linker hash table.  Mark those
+   referenced from a non-IR file with non_ir_ref.  We have to
+   notice_all symbols, because we won't necessarily know until later
+   which ones will be contributed by IR files.  */
+static bfd_boolean
+plugin_notice (struct bfd_link_info *info,
+              struct bfd_link_hash_entry *h,
+              bfd *abfd,
+              asection *section,
+              bfd_vma value)
+{
+  if (h != NULL)
     {
-      /* No further processing since this is a def from an IR dummy BFD.  */
-      return FALSE;
+      /* No further processing if this def/ref is from an IR dummy BFD.  */
+      if (is_ir_dummy_bfd (abfd))
+       return TRUE;
+
+      /* If this is a ref, set non_ir_ref.  */
+      if (bfd_is_und_section (section))
+       h->non_ir_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 (h->u.def.section->owner))
+              || (h->type == bfd_link_hash_common
+                  && is_ir_dummy_bfd (h->u.c.p->section->owner)))
+       h->type = bfd_link_hash_undefweak;
     }
 
   /* Continue with cref/nocrossref/trace-sym processing.  */
+  if (h == NULL
+      || orig_notice_all
+      || (info->notice_hash != NULL
+         && bfd_hash_lookup (info->notice_hash, h->root.string,
+                             FALSE, FALSE) != NULL))
+    return (*orig_callbacks->notice) (info, h, abfd, section, value);
   return TRUE;
 }
-
-/* When we add new object files to the link at all symbols read time,
-   these contain the real code and symbols generated from the IR files,
-   and so duplicate all the definitions already supplied by the dummy
-   IR-only BFDs that we created at claim files time.  We use the linker's
-   multiple-definitions callback hook to fix up the clash, discarding
-   the symbol from the IR-only BFD in favour of the symbol from the
-   real BFD.  We return true if this was not-really-a-clash because
-   we've fixed it up, or anyway if --allow-multiple-definition was in
-   effect (before we disabled it to ensure we got called back).  */
-bfd_boolean
-plugin_multiple_definition (struct bfd_link_info *info, const char *name,
-                           bfd *obfd, asection *osec ATTRIBUTE_UNUSED,
-                           bfd_vma oval ATTRIBUTE_UNUSED,
-                           bfd *nbfd, asection *nsec, bfd_vma nval)
-{
-  if (is_ir_dummy_bfd (obfd))
-    {
-      struct bfd_link_hash_entry *blhe
-       = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, FALSE);
-      if (!blhe)
-       einfo (_("%P%X: %s: can't find IR symbol '%s'\n"), nbfd->filename,
-              name);
-      else if (blhe->type != bfd_link_hash_defined)
-       einfo (_("%P%x: %s: bad IR symbol type %d\n"), name, blhe->type);
-      /* Replace it with new details.  */
-      blhe->u.def.section = nsec;
-      blhe->u.def.value = nval;
-      return TRUE;
-    }
-  return plugin_cached_allow_multiple_defs;
-}
index 49a27f9ca43eb0dc3bd6dc36e899a4d4834de5ee..ee29b7ce1c9908c840b6c975d1868f1cd71c30d0 100644 (file)
 #ifndef GLD_PLUGIN_H
 #define GLD_PLUGIN_H
 
+/* Report plugin symbols.  */
+extern bfd_boolean report_plugin_symbols;
+
+/* Set at all symbols read time, to avoid recursively offering the plugin
+   its own newly-added input files and libs to claim.  */
+extern bfd_boolean no_more_claiming;
 
 /* This is the only forward declaration we need to avoid having
    to include the plugin-api.h header in order to use this file.  */
@@ -44,8 +50,8 @@ extern int plugin_load_plugins (void);
 extern const char *plugin_error_plugin (void);
 
 /* Call 'claim file' hook for all plugins.  */
-extern int plugin_call_claim_file (const struct ld_plugin_input_file *file,
-               int *claimed);
+extern void plugin_maybe_claim (struct ld_plugin_input_file *,
+                               lang_input_statement_type *);
 
 /* Call 'all symbols read' hook for all plugins.  */
 extern int plugin_call_all_symbols_read (void);
@@ -60,15 +66,4 @@ extern void plugin_call_cleanup (void);
    add_symbols hook has been called so that it can be read when linking.  */
 extern bfd *plugin_get_ir_dummy_bfd (const char *name, bfd *template);
 
-/* Notice-symbol bfd linker callback hook.  */
-extern bfd_boolean plugin_notice (struct bfd_link_info *info,
-               const char *name, bfd *abfd, asection *section,
-               bfd_vma value);
-
-/* Multiple-definition bfd linker callback hook.  */
-extern bfd_boolean plugin_multiple_definition (struct bfd_link_info *info,
-               const char *name,
-               bfd *obfd, asection *osec, bfd_vma oval,
-               bfd *nbfd, asection *nsec, bfd_vma nval);
-
 #endif /* !def GLD_PLUGIN_H */
index 11507d44b86d901ee8d60c11cc5946722a5941dd..aa44f2f2c7dce9a5e9098f773dede62e004df3ea 100644 (file)
@@ -1,3 +1,29 @@
+2011-04-27  Alan Modra  <amodra@gmail.com>
+
+       Backport from mainline.
+       2011-04-19  H.J. Lu  <hongjiu.lu@intel.com>
+       * ld-plugin/plugin-ignore.d: Removed.
+
+       2011-04-18  H.J. Lu  <hongjiu.lu@intel.com>
+       * ld-plugin/plugin-7.d: Update expected LTO linker errors for
+       GCC 4.6.
+       * ld-plugin/plugin-8.d: Likewise.
+
+       2011-04-18  Alan Modra  <amodra@gmail.com>
+       * ld-plugin/plugin-7.d: Adjust for plugin changes.
+       * ld-plugin/plugin-8.d: Likewise.
+       * ld-plugin/plugin.exp: Pass --verbose=2 for visibility test, and
+       compare ld output to..
+       * ld-plugin/plugin-12.d: New.
+
+       2011-04-11  Mark Wielaard  <mjw@redhat.com>
+       PR 10549
+       * ld-unique: New directory.
+       * ld-unique/unique.exp: New file: Run the UNIQUE tests.
+       * ld-unique/unique.s: New test file.
+       * ld-unique/unique_empty.s: Likewise.
+       * ld-unique/unique_shared.s: Likewise.
+
 2011-04-11  Alan Modra  <amodra@gmail.com>
 
        * ld-elf/eh-frame-hdr.d: xfail avr.
index 75f25e01b27e2e979399b2bfc102381207da382e..04f41392ca64b49199214701e144b7f14681ea18 100644 (file)
@@ -26,5 +26,6 @@ hook called: claim_file tmpdir/func.o \[@0/.* CLAIMED
 hook called: claim_file tmpdir/text.o \[@0/.* not claimed
 #...
 hook called: all symbols read.
+`func' referenced in section `\.text.*' of tmpdir/main.o: defined in discarded section .*
 hook called: cleanup.
 #...
index e72b0392c037798a4c13d9da7abf2a03f5f2db4a..003537c94f465048858b196f29c15311512b2a92 100644 (file)
@@ -30,5 +30,6 @@ hook called: claim_file tmpdir/text.o \[@0/.* not claimed
 hook called: all symbols read.
 Sym: '_?func' Resolution: LDPR_PREVAILING_DEF
 Sym: '_?func2' Resolution: LDPR_PREVAILING_DEF_IRONLY
+`func' referenced in section `\.text.*' of tmpdir/main.o: defined in discarded section .*
 hook called: cleanup.
 #...
index 3b5e077eb9976ce05be6050bef0241fc2138be9b..02319bfb1a0df9f7ff370a059ebe2f42bc84fd6b 100644 (file)
@@ -87,7 +87,7 @@ set testobjfiles "tmpdir/main.o tmpdir/func.o tmpdir/text.o"
 set testobjfiles_notext "tmpdir/main.o tmpdir/func.o"
 # Rather than having libs we just define dummy values for anything
 # we may need to link a target exe; we aren't going to run it anyway.
-set libs "[ld_simple_link_defsyms] --defsym ${_}printf=0 --defsym ${_}puts=0"
+set libs "[ld_simple_link_defsyms] --defsym ${_}printf=${_}main --defsym ${_}puts=${_}main"
 
 set plugin_tests [list \
     [list "load plugin" "-plugin $plugin_path \
@@ -152,8 +152,8 @@ set plugin_extra_elf_tests [list \
                        -plugin-opt sym:${_}func2::0:2:0 \
                        -plugin-opt sym:${_}func3::0:3:0 \
                        -plugin-opt dumpresolutions \
-    $testobjfiles $libs" "" "" {{ld plugin-ignore.d} \
-                               {readelf -s plugin-vis-1.d}} "main.x" ] \
+                       -plugin-opt add:tmpdir/func.o \
+    $testobjfiles $libs --verbose=2" "" "" {{ld plugin-12.d}} "main.x" ] \
 ]
 
 if { !$can_compile || $failed_compile } {