Set my_archive for thin archives
authorAlan Modra <amodra@gmail.com>
Tue, 14 Jun 2016 03:42:00 +0000 (13:12 +0930)
committerAlan Modra <amodra@gmail.com>
Tue, 14 Jun 2016 03:42:00 +0000 (13:12 +0930)
LTO plugin support in plugin_maybe_claim wants to close the IR bfd
after replacing it with the recompiled object, but can't do so for
archive elements due to various pointers that access the archive bfd.
Thin archives have the same problem.  They too cannot have their
element bfds closed.

PR ld/20241
bfd/
* archive.c (open_nested_file): Set my_archive.
* bfd.c (_bfd_default_error_handler <%B>): Exclude archive file name
for thin archives.
* bfdio.c (bfd_tell): Don't adjust origin for thin archives.
(bfd_seek): Likewise.
* bfdwin.c (bfd_get_file_window): Likewise.
* cache.c (cache_bmmap): Likewise.
(bfd_cache_lookup_worker): Don't look in my_archive for thin archives.
* mach-o.c (bfd_mach_o_follow_dsym): Don't open my_archive for
thin archives.
* plugin.c (try_claim): Likewise.
* xcofflink.c (xcoff_link_add_dynamic_symbols): Use import path of
file within thin archive, not the archive.
binutils/
* bucomm.c (bfd_get_archive_filename): Return file name within thin
archive.
ld/
* ldmain.c (add_archive_element): Just print file name of file within
thin archives.
* ldmisc.c (vfinfo): Likewise.
* plugin.c (plugin_object_p): Open file within thin archives.
(plugin_maybe_claim): Expand comment.

15 files changed:
bfd/ChangeLog
bfd/archive.c
bfd/bfd.c
bfd/bfdio.c
bfd/bfdwin.c
bfd/cache.c
bfd/mach-o.c
bfd/plugin.c
bfd/xcofflink.c
binutils/ChangeLog
binutils/bucomm.c
ld/ChangeLog
ld/ldmain.c
ld/ldmisc.c
ld/plugin.c

index 9cfd09e10cf061c2288b41c64273f717a29b700b..db25f2e241f379d73deffb7d9e684d544ebd757f 100644 (file)
@@ -1,3 +1,20 @@
+2016-06-14  Alan Modra  <amodra@gmail.com>
+
+       PR ld/20241
+       * archive.c (open_nested_file): Set my_archive.
+       * bfd.c (_bfd_default_error_handler <%B>): Exclude archive file name
+       for thin archives.
+       * bfdio.c (bfd_tell): Don't adjust origin for thin archives.
+       (bfd_seek): Likewise.
+       * bfdwin.c (bfd_get_file_window): Likewise.
+       * cache.c (cache_bmmap): Likewise.
+       (bfd_cache_lookup_worker): Don't look in my_archive for thin archives.
+       * mach-o.c (bfd_mach_o_follow_dsym): Don't open my_archive for
+       thin archives.
+       * plugin.c (try_claim): Likewise.
+       * xcofflink.c (xcoff_link_add_dynamic_symbols): Use import path of
+       file within thin archive, not the archive.
+
 2016-06-13  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ld/20244
index 6fc5f1d80f9ef8be456c45b35bcea42ff3436086..7f94376213378ecb3699badca0657d9db232721f 100644 (file)
@@ -392,6 +392,7 @@ open_nested_file (const char *filename, bfd *archive)
     {
       n_bfd->lto_output = archive->lto_output;
       n_bfd->no_export = archive->no_export;
+      n_bfd->my_archive = archive;
     }
   return n_bfd;
 }
index 7400c4ed5d24d69aba6c5f6a9e036b93f7c03915..26143f91debc21d886b4cf01e8fcf6ba1d46f418 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -703,7 +703,8 @@ _bfd_default_error_handler (const char *fmt, ...)
                  if (abfd == NULL)
                    /* Invoking %B with a null bfd pointer is an internal error.  */
                    abort ();
-                 else if (abfd->my_archive)
+                 else if (abfd->my_archive
+                          && !bfd_is_thin_archive (abfd->my_archive))
                    snprintf (bufp, avail, "%s(%s)",
                              abfd->my_archive->filename, abfd->filename);
                  else
index 55deb3b085a4103b557d13c579e9952be09f90a5..71991bd47eed3cbb1f08ea21eb3ab11b0d5d7ad3 100644 (file)
@@ -234,7 +234,8 @@ bfd_tell (bfd *abfd)
       bfd *parent_bfd = abfd;
       ptr = abfd->iovec->btell (abfd);
 
-      while (parent_bfd->my_archive != NULL)
+      while (parent_bfd->my_archive != NULL
+            && !bfd_is_thin_archive (parent_bfd->my_archive))
        {
          ptr -= parent_bfd->origin;
          parent_bfd = parent_bfd->my_archive;
@@ -289,7 +290,7 @@ bfd_seek (bfd *abfd, file_ptr position, int direction)
   if (direction == SEEK_CUR && position == 0)
     return 0;
 
-  if (abfd->format != bfd_archive && abfd->my_archive == 0)
+  if (abfd->my_archive == NULL || bfd_is_thin_archive (abfd->my_archive))
     {
       if (direction == SEEK_SET && (bfd_vma) position == abfd->where)
        return 0;
@@ -314,7 +315,8 @@ bfd_seek (bfd *abfd, file_ptr position, int direction)
     {
       bfd *parent_bfd = abfd;
 
-      while (parent_bfd->my_archive != NULL)
+      while (parent_bfd->my_archive != NULL
+            && !bfd_is_thin_archive (parent_bfd->my_archive))
         {
           file_position += parent_bfd->origin;
           parent_bfd = parent_bfd->my_archive;
index 1aaee2cd8577cef5412d646528a2b07be4f70818..f3faba48091f1595469ace79f84e926ade632b20 100644 (file)
@@ -144,7 +144,8 @@ bfd_get_file_window (bfd *abfd,
       int fd;
 
       /* Find the real file and the real offset into it.  */
-      while (abfd->my_archive != NULL)
+      while (abfd->my_archive != NULL
+            && !bfd_is_thin_archive (abfd->my_archive))
        {
          offset += abfd->origin;
          abfd = abfd->my_archive;
index 995cf1f9ebac02282ea87ef5c5d2ff1a76ea84c2..8efbcb9e22fda43b328620108b323871123fb70e 100644 (file)
@@ -241,7 +241,8 @@ bfd_cache_lookup_worker (bfd *abfd, enum cache_flag flag)
   if ((abfd->flags & BFD_IN_MEMORY) != 0)
     abort ();
 
-  while (abfd->my_archive)
+  while (abfd->my_archive != NULL
+        && !bfd_is_thin_archive (abfd->my_archive))
     abfd = abfd->my_archive;
 
   if (abfd->iostream != NULL)
@@ -466,7 +467,8 @@ cache_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED,
         pagesize_m1 = getpagesize () - 1;
 
       /* Handle archive members.  */
-      if (abfd->my_archive != NULL)
+      if (abfd->my_archive != NULL
+         && !bfd_is_thin_archive (abfd->my_archive))
         offset += abfd->origin;
 
       /* Align.  */
index 85ce8571769f7907478ed9c58b7d622a7b9ab505..16099803ff5e550ea769e4b1e7511d33042d3ff6 100644 (file)
@@ -5708,7 +5708,7 @@ bfd_mach_o_follow_dsym (bfd *abfd)
   if (abfd == NULL || bfd_get_flavour (abfd) != bfd_target_mach_o_flavour)
     return NULL;
 
-  if (abfd->my_archive)
+  if (abfd->my_archive && !bfd_is_thin_archive (abfd->my_archive))
     base_bfd = abfd->my_archive;
   /* BFD may have been opened from a stream. */
   if (base_bfd->filename == NULL)
index c81a2678256d0d5709c358bd5334b8cb91163c2d..559fcd4aa81bf9594a60dcdad6a72951371e4b91 100644 (file)
@@ -167,7 +167,7 @@ try_claim (bfd *abfd)
 
   file.name = abfd->filename;
 
-  if (abfd->my_archive)
+  if (abfd->my_archive && !bfd_is_thin_archive (abfd->my_archive))
     {
       iobfd = abfd->my_archive;
       file.offset = abfd->origin;
@@ -185,7 +185,7 @@ try_claim (bfd *abfd)
 
   file.fd = fileno ((FILE *) iobfd->iostream);
 
-  if (!abfd->my_archive)
+  if (!abfd->my_archive || bfd_is_thin_archive (abfd->my_archive))
     {
       struct stat stat_buf;
       if (fstat (file.fd, &stat_buf))
index de7a9928461ca24af833130d1ff8a96d7cf5ce50..d3653e3ba572922c8205b11c32b69d8d75f2ed9e 100644 (file)
@@ -997,7 +997,7 @@ xcoff_link_add_dynamic_symbols (bfd *abfd, struct bfd_link_info *info)
     return FALSE;
   n->next = NULL;
 
-  if (abfd->my_archive == NULL)
+  if (abfd->my_archive == NULL || bfd_is_thin_archive (abfd->my_archive))
     {
       if (!bfd_xcoff_split_import_path (abfd, abfd->filename,
                                        &n->path, &n->file))
index f8e7c769ebc801c887564eee1054bc7da31814e9..77a660448756915e71f3839efdd286d97c074e23 100644 (file)
@@ -1,3 +1,9 @@
+2016-06-14  Alan Modra  <amodra@gmail.com>
+
+       PR ld/20241
+       * bucomm.c (bfd_get_archive_filename): Return file name within thin
+       archive.
+
 2016-06-02  Nick Clifton  <nickc@redhat.com>
 
        PR 20089
index da7cfad41cca43bc54629cc9ddd7ddf00e2370a1..8ecd7f26dfc552655ca94b487633e3f28e5f9204 100644 (file)
@@ -605,7 +605,8 @@ bfd_get_archive_filename (const bfd *abfd)
 
   assert (abfd != NULL);
 
-  if (!abfd->my_archive)
+  if (abfd->my_archive == NULL
+      || bfd_is_thin_archive (abfd->my_archive))
     return bfd_get_filename (abfd);
 
   needed = (strlen (bfd_get_filename (abfd->my_archive))
index e5614ba2b9afd10534c7a0ca0cf5c36493bc6779..ac56c8f14c3dca102d97dcc2747a0d3bcd6f8e7c 100644 (file)
@@ -1,3 +1,12 @@
+2016-06-14  Alan Modra  <amodra@gmail.com>
+
+       PR ld/20241
+       * ldmain.c (add_archive_element): Just print file name of file within
+       thin archives.
+       * ldmisc.c (vfinfo): Likewise.
+       * plugin.c (plugin_object_p): Open file within thin archives.
+       (plugin_maybe_claim): Expand comment.
+
 2016-06-13  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ld/20244
index f16e33bfbf3b106a1b58135f9a4a5134cc266429..3c5065f9424e0aadbed4765a0c40210655ac80f5 100644 (file)
@@ -865,7 +865,8 @@ add_archive_element (struct bfd_link_info *info,
          header_printed = TRUE;
        }
 
-      if (bfd_my_archive (abfd) == NULL)
+      if (bfd_my_archive (abfd) == NULL
+         || bfd_is_thin_archive (bfd_my_archive (abfd)))
        {
          minfo ("%s", bfd_get_filename (abfd));
          len = strlen (bfd_get_filename (abfd));
index 70e12eaf7c68ae44004b1295ee8773dbe2fb2f93..321db9a21c59f2d85b74c29a4365c8eb1d364256 100644 (file)
@@ -201,7 +201,8 @@ vfinfo (FILE *fp, const char *fmt, va_list arg, bfd_boolean is_warning)
 
                if (abfd == NULL)
                  fprintf (fp, "%s generated", program_name);
-               else if (abfd->my_archive)
+               else if (abfd->my_archive != NULL
+                        && !bfd_is_thin_archive (abfd->my_archive))
                  fprintf (fp, "%s(%s)", abfd->my_archive->filename,
                           abfd->filename);
                else
@@ -230,11 +231,13 @@ vfinfo (FILE *fp, const char *fmt, va_list arg, bfd_boolean is_warning)
                lang_input_statement_type *i;
 
                i = va_arg (arg, lang_input_statement_type *);
-               if (bfd_my_archive (i->the_bfd) != NULL)
+               if (bfd_my_archive (i->the_bfd) != NULL
+                   && !bfd_is_thin_archive (bfd_my_archive (i->the_bfd)))
                  fprintf (fp, "(%s)",
                           bfd_get_filename (bfd_my_archive (i->the_bfd)));
                fprintf (fp, "%s", i->local_sym_name);
-               if (bfd_my_archive (i->the_bfd) == NULL
+               if ((bfd_my_archive (i->the_bfd) == NULL
+                    || bfd_is_thin_archive (bfd_my_archive (i->the_bfd)))
                    && filename_cmp (i->local_sym_name, i->filename) != 0)
                  fprintf (fp, " (%s)", i->filename);
              }
index c951995dccb3104b741925e3604c0311e37134d6..c347cfa61cc9484ccf4f68a149d91b41fa4b1883 100644 (file)
@@ -1089,7 +1089,8 @@ plugin_object_p (bfd *ibfd)
        return NULL;
     }
 
-  inarchive = bfd_my_archive (ibfd) != NULL;
+  inarchive = (bfd_my_archive (ibfd) != NULL
+              && !bfd_is_thin_archive (bfd_my_archive (ibfd)));
   name = inarchive ? bfd_my_archive (ibfd)->filename : ibfd->filename;
   fd = open (name, O_RDONLY | O_BINARY);
 
@@ -1201,8 +1202,10 @@ plugin_maybe_claim (lang_input_statement_type *entry)
 
       /* 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.  */
+      /* We can't call bfd_close on archives.  BFD archive handling
+        caches elements, and add_archive_element keeps pointers to
+        the_bfd and the_bfd->filename in a lang_input_statement_type
+        linker script statement.  */
       if (entry->the_bfd->my_archive == NULL)
        bfd_close (entry->the_bfd);
       entry->the_bfd = abfd;