From b0cffb47671ffbaac559c1f17a9f248256ea6c42 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 14 Jun 2016 13:12:00 +0930 Subject: [PATCH] Set my_archive for thin archives 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. --- bfd/ChangeLog | 17 +++++++++++++++++ bfd/archive.c | 1 + bfd/bfd.c | 3 ++- bfd/bfdio.c | 8 +++++--- bfd/bfdwin.c | 3 ++- bfd/cache.c | 6 ++++-- bfd/mach-o.c | 2 +- bfd/plugin.c | 4 ++-- bfd/xcofflink.c | 2 +- binutils/ChangeLog | 6 ++++++ binutils/bucomm.c | 3 ++- ld/ChangeLog | 9 +++++++++ ld/ldmain.c | 3 ++- ld/ldmisc.c | 9 ++++++--- ld/plugin.c | 9 ++++++--- 15 files changed, 66 insertions(+), 19 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 9cfd09e10cf..db25f2e241f 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,20 @@ +2016-06-14 Alan Modra + + 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 PR ld/20244 diff --git a/bfd/archive.c b/bfd/archive.c index 6fc5f1d80f9..7f943762133 100644 --- a/bfd/archive.c +++ b/bfd/archive.c @@ -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; } diff --git a/bfd/bfd.c b/bfd/bfd.c index 7400c4ed5d2..26143f91deb 100644 --- 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 diff --git a/bfd/bfdio.c b/bfd/bfdio.c index 55deb3b085a..71991bd47ee 100644 --- a/bfd/bfdio.c +++ b/bfd/bfdio.c @@ -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; diff --git a/bfd/bfdwin.c b/bfd/bfdwin.c index 1aaee2cd857..f3faba48091 100644 --- a/bfd/bfdwin.c +++ b/bfd/bfdwin.c @@ -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; diff --git a/bfd/cache.c b/bfd/cache.c index 995cf1f9eba..8efbcb9e22f 100644 --- a/bfd/cache.c +++ b/bfd/cache.c @@ -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. */ diff --git a/bfd/mach-o.c b/bfd/mach-o.c index 85ce8571769..16099803ff5 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -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) diff --git a/bfd/plugin.c b/bfd/plugin.c index c81a2678256..559fcd4aa81 100644 --- a/bfd/plugin.c +++ b/bfd/plugin.c @@ -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)) diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c index de7a9928461..d3653e3ba57 100644 --- a/bfd/xcofflink.c +++ b/bfd/xcofflink.c @@ -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)) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index f8e7c769ebc..77a66044875 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,9 @@ +2016-06-14 Alan Modra + + PR ld/20241 + * bucomm.c (bfd_get_archive_filename): Return file name within thin + archive. + 2016-06-02 Nick Clifton PR 20089 diff --git a/binutils/bucomm.c b/binutils/bucomm.c index da7cfad41cc..8ecd7f26dfc 100644 --- a/binutils/bucomm.c +++ b/binutils/bucomm.c @@ -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)) diff --git a/ld/ChangeLog b/ld/ChangeLog index e5614ba2b9a..ac56c8f14c3 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,12 @@ +2016-06-14 Alan Modra + + 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 PR ld/20244 diff --git a/ld/ldmain.c b/ld/ldmain.c index f16e33bfbf3..3c5065f9424 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -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)); diff --git a/ld/ldmisc.c b/ld/ldmisc.c index 70e12eaf7c6..321db9a21c5 100644 --- a/ld/ldmisc.c +++ b/ld/ldmisc.c @@ -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); } diff --git a/ld/plugin.c b/ld/plugin.c index c951995dccb..c347cfa61cc 100644 --- a/ld/plugin.c +++ b/ld/plugin.c @@ -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; -- 2.30.2