From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1062) id 487493857350; Wed, 12 Apr 2023 01:34:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 487493857350 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Alan Modra To: bfd-cvs@sourceware.org Subject: [binutils-gdb] pe_ILF_object_p and bfd_check_format_matches X-Act-Checkin: binutils-gdb X-Git-Author: Alan Modra X-Git-Refname: refs/heads/master X-Git-Oldrev: dff05c9c82fd877cfba432e0f4f82b41bd0f5257 X-Git-Newrev: f656f9c77c27298c71f0c864d3e8a095a55cb594 Message-Id: <20230412013440.487493857350@sourceware.org> Date: Wed, 12 Apr 2023 01:34:40 +0000 (GMT) X-BeenThere: binutils-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 12 Apr 2023 01:34:40 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3Df656f9c77c27= 298c71f0c864d3e8a095a55cb594 commit f656f9c77c27298c71f0c864d3e8a095a55cb594 Author: Alan Modra Date: Tue Apr 11 22:11:26 2023 +0930 pe_ILF_object_p and bfd_check_format_matches =20 If pe_ILF_object_p succeeds, pe_ILF_build_a_bfd will have changed the bfd from being file backed to in-memory. This can have unfortunate results for targets checked by bfd_check_format_matches after that point as they will be matching against the created in-memory image rather than the file. bfd_preserve_restore also has a problem if it flips the BFD_IN_MEMORY flag, because the flag affects iostream meaning and should be set if using _bfd_memory_iovec. To fix these problems, save and restore iostream and iovec along with flags, and modify bfd_reinit to make the bfd file backed again. Restoring the iovec and iostream allows the hack in bfd_reinit keeping BFD_IN_MEMORY (part of BFD_FLAGS_SAVED) to be removed. One more detail: If restoring from file backed to in-memory then the bfd needs to be forcibly removed from the cache lru list, since after the bfd becomes in-memory a bfd_close will delete the bfd's memory leaving the lru list pointing into freed memory. =20 * cache.c (bfd_cache_init): Clear BFD_CLOSED_BY_CACHE here.. (bfd_cache_lookup_worker): ..rather than here. (bfd_cache_close): Comment. * format.c (struct bfd_preserve): Add iovec and iostream fields. (bfd_preserve_save): Save them.. (bfd_preserve_restore): ..and restore them, calling bfd_cache_close if the iovec differs. (bfd_reinit): Add preserve param. If the bfd has been flipped to in-memory, reopen the file. Restore flags. * peicode.h (pe_ILF_cleanup): New function. (pe_ILF_object_p): Return it. * bfd.c (BFD_FLAGS_SAVED): Delete. * bfd-in2.h: Regenerate. Diff: --- bfd/bfd-in2.h | 6 ------ bfd/bfd.c | 6 ------ bfd/cache.c | 7 +++---- bfd/format.c | 26 ++++++++++++++++++++++---- bfd/peicode.h | 13 ++++++++++++- 5 files changed, 37 insertions(+), 21 deletions(-) diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index b60ff960f08..a04e97eda67 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -6622,12 +6622,6 @@ struct bfd /* Compress sections in this BFD with SHF_COMPRESSED zstd. */ #define BFD_COMPRESS_ZSTD 0x400000 =20 - /* Flags bits to be saved in bfd_preserve_save. */ -#define BFD_FLAGS_SAVED \ - (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \ - | BFD_PLUGIN | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON \ - | BFD_USE_ELF_STT_COMMON | BFD_COMPRESS_ZSTD) - /* Flags bits which are for BFD use only. */ #define BFD_FLAGS_FOR_BFD_USE_MASK \ (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \ diff --git a/bfd/bfd.c b/bfd/bfd.c index 3624bfbc9a5..650df1c79ed 100644 --- a/bfd/bfd.c +++ b/bfd/bfd.c @@ -181,12 +181,6 @@ CODE_FRAGMENT . {* Compress sections in this BFD with SHF_COMPRESSED zstd. *} .#define BFD_COMPRESS_ZSTD 0x400000 . -. {* Flags bits to be saved in bfd_preserve_save. *} -.#define BFD_FLAGS_SAVED \ -. (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \ -. | BFD_PLUGIN | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON \ -. | BFD_USE_ELF_STT_COMMON | BFD_COMPRESS_ZSTD) -. . {* Flags bits which are for BFD use only. *} .#define BFD_FLAGS_FOR_BFD_USE_MASK \ . (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \ diff --git a/bfd/cache.c b/bfd/cache.c index ab36c8506bd..3b91cce2307 100644 --- a/bfd/cache.c +++ b/bfd/cache.c @@ -266,10 +266,7 @@ bfd_cache_lookup_worker (bfd *abfd, enum cache_flag fl= ag) && !(flag & CACHE_NO_SEEK_ERROR)) bfd_set_error (bfd_error_system_call); else - { - abfd->flags &=3D ~BFD_CLOSED_BY_CACHE; - return (FILE *) abfd->iostream; - } + return (FILE *) abfd->iostream; =20 /* xgettext:c-format */ _bfd_error_handler (_("reopening %pB: %s"), @@ -506,6 +503,7 @@ bfd_cache_init (bfd *abfd) } abfd->iovec =3D &cache_iovec; insert (abfd); + abfd->flags &=3D ~BFD_CLOSED_BY_CACHE; ++open_files; return true; } @@ -528,6 +526,7 @@ DESCRIPTION bool bfd_cache_close (bfd *abfd) { + /* Don't remove this test. bfd_reinit depends on it. */ if (abfd->iovec !=3D &cache_iovec) return true; =20 diff --git a/bfd/format.c b/bfd/format.c index 5ad4190d5c4..dd50b5e653a 100644 --- a/bfd/format.c +++ b/bfd/format.c @@ -99,6 +99,8 @@ struct bfd_preserve void *marker; void *tdata; flagword flags; + const struct bfd_iovec *iovec; + void *iostream; const struct bfd_arch_info *arch_info; struct bfd_section *sections; struct bfd_section *section_last; @@ -125,6 +127,8 @@ bfd_preserve_save (bfd *abfd, struct bfd_preserve *pres= erve, preserve->tdata =3D abfd->tdata.any; preserve->arch_info =3D abfd->arch_info; preserve->flags =3D abfd->flags; + preserve->iovec =3D abfd->iovec; + preserve->iostream =3D abfd->iostream; preserve->sections =3D abfd->sections; preserve->section_last =3D abfd->section_last; preserve->section_count =3D abfd->section_count; @@ -143,14 +147,24 @@ bfd_preserve_save (bfd *abfd, struct bfd_preserve *pr= eserve, /* Clear out a subset of BFD state. */ =20 static void -bfd_reinit (bfd *abfd, unsigned int section_id, bfd_cleanup cleanup) +bfd_reinit (bfd *abfd, unsigned int section_id, + struct bfd_preserve *preserve, bfd_cleanup cleanup) { _bfd_section_id =3D section_id; if (cleanup) cleanup (abfd); abfd->tdata.any =3D NULL; abfd->arch_info =3D &bfd_default_arch_struct; - abfd->flags &=3D BFD_FLAGS_SAVED; + if ((abfd->flags & BFD_CLOSED_BY_CACHE) !=3D 0 + && (abfd->flags & BFD_IN_MEMORY) !=3D 0 + && (preserve->flags & BFD_CLOSED_BY_CACHE) =3D=3D 0 + && (preserve->flags & BFD_IN_MEMORY) =3D=3D 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 =3D preserve->flags; abfd->build_id =3D NULL; bfd_section_list_clear (abfd); } @@ -164,7 +178,11 @@ bfd_preserve_restore (bfd *abfd, struct bfd_preserve *= preserve) =20 abfd->tdata.any =3D preserve->tdata; abfd->arch_info =3D preserve->arch_info; + if (abfd->iovec !=3D preserve->iovec) + bfd_cache_close (abfd); abfd->flags =3D preserve->flags; + abfd->iovec =3D preserve->iovec; + abfd->iostream =3D preserve->iostream; abfd->section_htab =3D preserve->section_htab; abfd->sections =3D preserve->sections; abfd->section_last =3D preserve->section_last; @@ -368,7 +386,7 @@ bfd_check_format_matches (bfd *abfd, bfd_format format,= char ***matching) /* If we already tried a match, the bfd is modified and may have sections attached, which will confuse the next _bfd_check_format call. */ - bfd_reinit (abfd, initial_section_id, cleanup); + bfd_reinit (abfd, initial_section_id, &preserve, cleanup); /* Free bfd_alloc memory too. If we have matched and preserved a target then the high water mark is that much higher. */ if (preserve_match.marker) @@ -527,7 +545,7 @@ bfd_check_format_matches (bfd *abfd, bfd_format format,= char ***matching) RIGHT_TARG again. */ if (match_targ !=3D right_targ) { - bfd_reinit (abfd, initial_section_id, cleanup); + bfd_reinit (abfd, initial_section_id, &preserve, cleanup); bfd_release (abfd, preserve.marker); if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) !=3D 0) goto err_ret; diff --git a/bfd/peicode.h b/bfd/peicode.h index f16aeca7a1b..e2e2be65b5d 100644 --- a/bfd/peicode.h +++ b/bfd/peicode.h @@ -1158,6 +1158,17 @@ pe_ILF_build_a_bfd (bfd * abfd, return false; } =20 +/* Cleanup function, returned from check_format hook. */ + +static void +pe_ILF_cleanup (bfd *abfd) +{ + struct bfd_in_memory *bim =3D abfd->iostream; + free (bim->buffer); + free (bim); + abfd->iostream =3D NULL; +} + /* We have detected an Import Library Format archive element. Decode the element and return the appropriate target. */ =20 @@ -1331,7 +1342,7 @@ pe_ILF_object_p (bfd * abfd) return NULL; } =20 - return _bfd_no_cleanup; + return pe_ILF_cleanup; } =20 static void