From: Alan Modra Date: Sun, 7 Sep 2025 22:33:14 +0000 (+0930) Subject: PR 33385 vms archives X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a2298f23f2e23ff6f191e36540208a90fffd317b;p=thirdparty%2Fbinutils-gdb.git PR 33385 vms archives Commit 5c4ce239a3ab "Tidy bfdio to consistenly use containing archive" broke vms archive handling, which has some horrible hacks involving use of a special iovec for archive elements. Modify the generic archive handling code to not use the archive iovec when it differs from the element iovec. Also, various commits involving seek optimisation broke the vms archive handling, which needs to see a rewind on an archive element. * bfdio.c (bfd_read, bfd_write, bfd_tell, bfd_flush), (bfd_stat, bfd_seek, bfd_mmap): Do not use the archive bfd for IO when the archive and element iovec differ. * plugin.c (bfd_plugin_open_input), (bfd_plugin_close_file_descriptor): Likewise. * vms-lib.c (vms_lib_bopen): Force bfd_seek to call iovec seek. --- diff --git a/bfd/bfdio.c b/bfd/bfdio.c index 7063bcc1ae6..6788caf1917 100644 --- a/bfd/bfdio.c +++ b/bfd/bfdio.c @@ -328,6 +328,7 @@ bfd_read (void *ptr, bfd_size_type size, bfd *abfd) ufile_ptr offset = 0; while (abfd->my_archive != NULL + && abfd->my_archive->iovec == abfd->iovec && !bfd_is_thin_archive (abfd->my_archive)) { offset += abfd->origin; @@ -339,6 +340,7 @@ bfd_read (void *ptr, bfd_size_type size, bfd *abfd) this element. */ if (element_bfd->arelt_data != NULL && element_bfd->my_archive != NULL + && element_bfd->my_archive->iovec == element_bfd->iovec && !bfd_is_thin_archive (element_bfd->my_archive)) { bfd_size_type maxbytes = arelt_size (element_bfd); @@ -392,6 +394,7 @@ bfd_write (const void *ptr, bfd_size_type size, bfd *abfd) file_ptr nwrote; while (abfd->my_archive != NULL + && abfd->my_archive->iovec == abfd->iovec && !bfd_is_thin_archive (abfd->my_archive)) abfd = abfd->my_archive; @@ -440,6 +443,7 @@ bfd_tell (bfd *abfd) file_ptr ptr; while (abfd->my_archive != NULL + && abfd->my_archive->iovec == abfd->iovec && !bfd_is_thin_archive (abfd->my_archive)) { offset += abfd->origin; @@ -470,6 +474,7 @@ int bfd_flush (bfd *abfd) { while (abfd->my_archive != NULL + && abfd->my_archive->iovec == abfd->iovec && !bfd_is_thin_archive (abfd->my_archive)) abfd = abfd->my_archive; @@ -497,6 +502,7 @@ bfd_stat (bfd *abfd, struct stat *statbuf) int result; while (abfd->my_archive != NULL + && abfd->my_archive->iovec == abfd->iovec && !bfd_is_thin_archive (abfd->my_archive)) abfd = abfd->my_archive; @@ -531,6 +537,7 @@ bfd_seek (bfd *abfd, file_ptr position, int direction) ufile_ptr offset = 0; while (abfd->my_archive != NULL + && abfd->my_archive->iovec == abfd->iovec && !bfd_is_thin_archive (abfd->my_archive)) { offset += abfd->origin; @@ -734,6 +741,7 @@ bfd_mmap (bfd *abfd, void *addr, size_t len, void **map_addr, size_t *map_len) { while (abfd->my_archive != NULL + && abfd->my_archive->iovec == abfd->iovec && !bfd_is_thin_archive (abfd->my_archive)) { offset += abfd->origin; diff --git a/bfd/plugin.c b/bfd/plugin.c index 5e5a0b70a04..f8ddc616724 100644 --- a/bfd/plugin.c +++ b/bfd/plugin.c @@ -378,6 +378,7 @@ bfd_plugin_open_input (bfd *ibfd, struct ld_plugin_input_file *file) iobfd = ibfd; while (iobfd->my_archive + && iobfd->my_archive->iovec == iobfd->iovec && !bfd_is_thin_archive (iobfd->my_archive)) iobfd = iobfd->my_archive; file->name = bfd_get_filename (iobfd); @@ -470,6 +471,7 @@ bfd_plugin_close_file_descriptor (bfd *abfd, int fd) else { while (abfd->my_archive + && abfd->my_archive->iovec == abfd->iovec && !bfd_is_thin_archive (abfd->my_archive)) abfd = abfd->my_archive; diff --git a/bfd/vms-lib.c b/bfd/vms-lib.c index 659832cf322..1206d7e24d4 100644 --- a/bfd/vms-lib.c +++ b/bfd/vms-lib.c @@ -1304,6 +1304,10 @@ vms_lib_bopen (bfd *el, file_ptr filepos) el->iostream = vec; el->iovec = &vms_lib_iovec; + /* Force the next rewind to call vms_lib_bseek even though it will + appear to bfd_seek that the file position is already at 0. */ + el->last_io = bfd_io_force; + /* File length is not known. */ vec->file_len = -1;