public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Alan Modra <amodra@gmail.com>
To: binutils@sourceware.org
Subject: Re: pe_ILF_object_p and bfd_check_format_matches
Date: Thu, 13 Apr 2023 12:28:02 +0930	[thread overview]
Message-ID: <ZDdvur4hs0gJxEZp@squeak.grove.modra.org> (raw)
In-Reply-To: <ZDYKPKZ4fcn/AF6v@squeak.grove.modra.org>

The last patch wasn't quite correct.  bfd_preserve_restore also needs
to handle an in-memory to file backed transition, seen in a testcase
ILF object matching both pei-arm-little and pei-arm-wince-little.
There the first match is saved in preserve_match, and restored at the
end of the bfd_check_format_matches loop making the bfd in-memory.  On
finding more than one match the function wants to restore the bfd back
to its original state with another bfd_preserve_restore call before
exiting with a bfd_error_file_ambiguously_recognized error.

It is also not correct to restore abfd->iostream unless the iovec
changes.  abfd->iostream is a FILE* when using cache_iovec, and if
the file has been closed and reopened the iostream may have changed.

	* format.c (io_reinit): New function.
	(bfd_reinit, bfd_preserve_restore): Use it.

diff --git a/bfd/format.c b/bfd/format.c
index dd50b5e653a..66b45ae1979 100644
--- a/bfd/format.c
+++ b/bfd/format.c
@@ -144,6 +144,33 @@ bfd_preserve_save (bfd *abfd, struct bfd_preserve *preserve,
 			      sizeof (struct section_hash_entry));
 }
 
+/* A back-end object_p function may flip a bfd from file backed to
+   in-memory, eg. pe_ILF_object_p.  In that case to restore the
+   original IO state we need to reopen the file.  Conversely, if we
+   are restoring a previously matched pe ILF format and have been
+   checking further target matches using file IO then we need to close
+   the file and detach the bfd from the cache lru list.  */
+
+static void
+io_reinit (bfd *abfd, struct bfd_preserve *preserve)
+{
+  if (abfd->iovec != preserve->iovec)
+    {
+      /* Handle file backed to in-memory transition.  bfd_cache_close
+	 won't do anything unless abfd->iovec is the cache_iovec.  */
+      bfd_cache_close (abfd);
+      abfd->iovec = preserve->iovec;
+      abfd->iostream = preserve->iostream;
+      /* Handle in-memory to file backed transition.  */
+      if ((abfd->flags & BFD_CLOSED_BY_CACHE) != 0
+	  && (abfd->flags & BFD_IN_MEMORY) != 0
+	  && (preserve->flags & BFD_CLOSED_BY_CACHE) == 0
+	  && (preserve->flags & BFD_IN_MEMORY) == 0)
+	bfd_open_file (abfd);
+    }
+  abfd->flags = preserve->flags;
+}
+
 /* Clear out a subset of BFD state.  */
 
 static void
@@ -155,16 +182,7 @@ bfd_reinit (bfd *abfd, unsigned int section_id,
     cleanup (abfd);
   abfd->tdata.any = NULL;
   abfd->arch_info = &bfd_default_arch_struct;
-  if ((abfd->flags & BFD_CLOSED_BY_CACHE) != 0
-      && (abfd->flags & BFD_IN_MEMORY) != 0
-      && (preserve->flags & BFD_CLOSED_BY_CACHE) == 0
-      && (preserve->flags & BFD_IN_MEMORY) == 0)
-    {
-      /* This is to reverse pe_ILF_build_a_bfd, which closes the file
-	 and sets up a bfd in memory.  */
-      bfd_open_file (abfd);
-    }
-  abfd->flags = preserve->flags;
+  io_reinit (abfd, preserve);
   abfd->build_id = NULL;
   bfd_section_list_clear (abfd);
 }
@@ -178,11 +196,7 @@ bfd_preserve_restore (bfd *abfd, struct bfd_preserve *preserve)
 
   abfd->tdata.any = preserve->tdata;
   abfd->arch_info = preserve->arch_info;
-  if (abfd->iovec != preserve->iovec)
-    bfd_cache_close (abfd);
-  abfd->flags = preserve->flags;
-  abfd->iovec = preserve->iovec;
-  abfd->iostream = preserve->iostream;
+  io_reinit (abfd, preserve);
   abfd->section_htab = preserve->section_htab;
   abfd->sections = preserve->sections;
   abfd->section_last = preserve->section_last;

-- 
Alan Modra
Australia Development Lab, IBM

  reply	other threads:[~2023-04-13  2:58 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-12  1:32 Alan Modra
2023-04-13  2:58 ` Alan Modra [this message]
2023-04-13  9:55   ` Martin Liška
2023-04-13 10:58     ` Alan Modra
2023-04-13 12:53       ` Martin Liška

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZDdvur4hs0gJxEZp@squeak.grove.modra.org \
    --to=amodra@gmail.com \
    --cc=binutils@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).