From 6395a1021020671dd205d332b2879e3e733e8024 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 24 Dec 2021 16:04:03 -0800 Subject: [PATCH] ld: Improve thin archive member error message Improve thin archive member error message with: ld: libbar.a(bar.o): error opening thin archive member: No such file or directory instead of ld: libbar.a: error adding symbols: No such file or directory PR ld/28722 * archive.c (_bfd_get_elt_at_filepos): Add a pointer argument for struct bfd_link_info. Call linker callback when failing to open thin archive member. (_bfd_generic_get_elt_at_index): Pass NULL to _bfd_get_elt_at_filepos. (bfd_generic_openr_next_archived_file): Likewise. * coff-alpha.c (alpha_ecoff_get_elt_at_filepos): Add a pointer argument for struct bfd_link_info and pass it to _bfd_get_elt_at_filepos. (alpha_ecoff_openr_next_archived_file): Pass NULL to _bfd_get_elt_at_filepos. (alpha_ecoff_get_elt_at_index): Likewise. * coff-rs6000.c (_bfd_xcoff_openr_next_archived_file): Likewise. * ecoff.c (ecoff_link_add_archive_symbols): Pass info to backend->get_elt_at_filepos. * elflink.c (elf_link_is_defined_archive_symbol): info to _bfd_get_elt_at_filepos. * libbfd-in.h (_bfd_get_elt_at_filepos): Add a pointer argument for struct bfd_link_info. * libbfd.h: Regenerate. * libecoff.h (ecoff_backend_data): Add a pointer argument for struct bfd_link_info to get_elt_at_filepos. * linker.c (_bfd_generic_link_add_archive_symbols): Pass info to _bfd_get_elt_at_filepos. --- bfd/archive.c | 32 ++++++++++++++++++++++++++------ bfd/coff-alpha.c | 10 ++++++---- bfd/coff-rs6000.c | 2 +- bfd/ecoff.c | 4 +++- bfd/elflink.c | 5 +++-- bfd/libbfd-in.h | 2 +- bfd/libbfd.h | 2 +- bfd/libecoff.h | 2 +- bfd/linker.c | 3 ++- 9 files changed, 44 insertions(+), 18 deletions(-) diff --git a/bfd/archive.c b/bfd/archive.c index f9b8b14a34f..9ad61adc615 100644 --- a/bfd/archive.c +++ b/bfd/archive.c @@ -651,7 +651,8 @@ _bfd_append_relative_path (bfd *arch, char *elt_name) element, since it handles the bookkeeping so nicely for us. */ bfd * -_bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos) +_bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos, + struct bfd_link_info *info) { struct areltdata *new_areldata; bfd *n_bfd; @@ -694,7 +695,8 @@ _bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos) free (new_areldata); return NULL; } - n_bfd = _bfd_get_elt_at_filepos (ext_arch, new_areldata->origin); + n_bfd = _bfd_get_elt_at_filepos (ext_arch, + new_areldata->origin, info); if (n_bfd == NULL) { free (new_areldata); @@ -715,8 +717,26 @@ _bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos) open the external file as a bfd. */ bfd_set_error (bfd_error_no_error); n_bfd = open_nested_file (filename, archive); - if (n_bfd == NULL && bfd_get_error () == bfd_error_no_error) - bfd_set_error (bfd_error_malformed_archive); + if (n_bfd == NULL) + { + switch (bfd_get_error ()) + { + default: + break; + case bfd_error_no_error: + bfd_set_error (bfd_error_malformed_archive); + break; + case bfd_error_system_call: + if (info != NULL) + { + info->callbacks->einfo + (_("%F%P: %pB(%s): error opening thin archive member: %E\n"), + archive, filename); + break; + } + break; + } + } } else { @@ -772,7 +792,7 @@ _bfd_generic_get_elt_at_index (bfd *abfd, symindex sym_index) carsym *entry; entry = bfd_ardata (abfd)->symdefs + sym_index; - return _bfd_get_elt_at_filepos (abfd, entry->file_offset); + return _bfd_get_elt_at_filepos (abfd, entry->file_offset, NULL); } bfd * @@ -841,7 +861,7 @@ bfd_generic_openr_next_archived_file (bfd *archive, bfd *last_file) } } - return _bfd_get_elt_at_filepos (archive, filestart); + return _bfd_get_elt_at_filepos (archive, filestart, NULL); } bfd * diff --git a/bfd/coff-alpha.c b/bfd/coff-alpha.c index aadcc8f5a74..7cf51a59110 100644 --- a/bfd/coff-alpha.c +++ b/bfd/coff-alpha.c @@ -2045,7 +2045,8 @@ alpha_ecoff_read_ar_hdr (bfd *abfd) we uncompress the archive element if necessary. */ static bfd * -alpha_ecoff_get_elt_at_filepos (bfd *archive, file_ptr filepos) +alpha_ecoff_get_elt_at_filepos (bfd *archive, file_ptr filepos, + struct bfd_link_info *info) { bfd *nbfd = NULL; struct areltdata *tdata; @@ -2057,7 +2058,7 @@ alpha_ecoff_get_elt_at_filepos (bfd *archive, file_ptr filepos) ufile_ptr filesize; buf = NULL; - nbfd = _bfd_get_elt_at_filepos (archive, filepos); + nbfd = _bfd_get_elt_at_filepos (archive, filepos, info); if (nbfd == NULL) goto error_return; @@ -2215,7 +2216,7 @@ alpha_ecoff_openr_next_archived_file (bfd *archive, bfd *last_file) } } - return alpha_ecoff_get_elt_at_filepos (archive, filestart); + return alpha_ecoff_get_elt_at_filepos (archive, filestart, NULL); } /* Open the archive file given an index into the armap. */ @@ -2226,7 +2227,8 @@ alpha_ecoff_get_elt_at_index (bfd *abfd, symindex sym_index) carsym *entry; entry = bfd_ardata (abfd)->symdefs + sym_index; - return alpha_ecoff_get_elt_at_filepos (abfd, entry->file_offset); + return alpha_ecoff_get_elt_at_filepos (abfd, entry->file_offset, + NULL); } static void diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index 61a655726e7..3248670db27 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -1763,7 +1763,7 @@ _bfd_xcoff_openr_next_archived_file (bfd *archive, bfd *last_file) } } - return _bfd_get_elt_at_filepos (archive, filestart); + return _bfd_get_elt_at_filepos (archive, filestart, NULL); } /* Stat an element in an XCOFF archive. */ diff --git a/bfd/ecoff.c b/bfd/ecoff.c index 9132b13e5fa..d2081055835 100644 --- a/bfd/ecoff.c +++ b/bfd/ecoff.c @@ -3639,7 +3639,9 @@ ecoff_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) hash = srch; } - element = (*backend->get_elt_at_filepos) (abfd, (file_ptr) file_offset); + element = (*backend->get_elt_at_filepos) (abfd, + (file_ptr) file_offset, + info); if (element == NULL) return false; diff --git a/bfd/elflink.c b/bfd/elflink.c index 24acb37925c..553efa26232 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -3470,7 +3470,7 @@ elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef) Elf_Internal_Sym *isymend; bool result; - abfd = _bfd_get_elt_at_filepos (abfd, symdef->file_offset); + abfd = _bfd_get_elt_at_filepos (abfd, symdef->file_offset, NULL); if (abfd == NULL) return false; @@ -5948,7 +5948,8 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) } /* We need to include this archive member. */ - element = _bfd_get_elt_at_filepos (abfd, symdef->file_offset); + element = _bfd_get_elt_at_filepos (abfd, symdef->file_offset, + info); if (element == NULL) goto error_return; diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h index ace28df0162..2905de8ef92 100644 --- a/bfd/libbfd-in.h +++ b/bfd/libbfd-in.h @@ -172,7 +172,7 @@ extern bool _bfd_write_archive_contents extern bool _bfd_compute_and_write_armap (bfd *, unsigned int) ATTRIBUTE_HIDDEN; extern bfd *_bfd_get_elt_at_filepos - (bfd *, file_ptr) ATTRIBUTE_HIDDEN; + (bfd *, file_ptr, struct bfd_link_info *) ATTRIBUTE_HIDDEN; extern bfd *_bfd_generic_get_elt_at_index (bfd *, symindex) ATTRIBUTE_HIDDEN; extern bfd * _bfd_new_bfd diff --git a/bfd/libbfd.h b/bfd/libbfd.h index c4eed1df093..6e62e556962 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -177,7 +177,7 @@ extern bool _bfd_write_archive_contents extern bool _bfd_compute_and_write_armap (bfd *, unsigned int) ATTRIBUTE_HIDDEN; extern bfd *_bfd_get_elt_at_filepos - (bfd *, file_ptr) ATTRIBUTE_HIDDEN; + (bfd *, file_ptr, struct bfd_link_info *) ATTRIBUTE_HIDDEN; extern bfd *_bfd_generic_get_elt_at_index (bfd *, symindex) ATTRIBUTE_HIDDEN; extern bfd * _bfd_new_bfd diff --git a/bfd/libecoff.h b/bfd/libecoff.h index 5a55073f8d8..b6c694873e7 100644 --- a/bfd/libecoff.h +++ b/bfd/libecoff.h @@ -72,7 +72,7 @@ struct ecoff_backend_data (bfd *, struct internal_filehdr *, struct internal_aouthdr *); /* Read an element from an archive at a given file position. This is needed because OSF/1 3.2 uses a weird archive format. */ - bfd *(*get_elt_at_filepos) (bfd *, file_ptr); + bfd *(*get_elt_at_filepos) (bfd *, file_ptr, struct bfd_link_info *); }; /* ECOFF targets don't support COFF long section names, so this diff --git a/bfd/linker.c b/bfd/linker.c index 4465594b156..088c1d06f3d 100644 --- a/bfd/linker.c +++ b/bfd/linker.c @@ -981,7 +981,8 @@ _bfd_generic_link_add_archive_symbols if (last_ar_offset != arsym->file_offset) { last_ar_offset = arsym->file_offset; - element = _bfd_get_elt_at_filepos (abfd, last_ar_offset); + element = _bfd_get_elt_at_filepos (abfd, last_ar_offset, + info); if (element == NULL || !bfd_check_format (element, bfd_object)) goto error_return; -- 2.30.2