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
next prev parent 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).