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 7063bcc..6788caf 100644
--- a/bfd/bfdio.c
+++ b/bfd/bfdio.c
@@ -328,6 +328,7 @@
   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 @@
      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 @@
   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 @@
   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 @@
 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 @@
   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 @@
   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 @@
 	  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 5e5a0b7..f8ddc61 100644
--- a/bfd/plugin.c
+++ b/bfd/plugin.c
@@ -378,6 +378,7 @@
 
   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 @@
   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 659832c..1206d7e 100644
--- a/bfd/vms-lib.c
+++ b/bfd/vms-lib.c
@@ -1304,6 +1304,10 @@
   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;