From: Torbjörn SVENSSON Date: Fri, 18 Jul 2025 15:04:09 +0000 (+0200) Subject: ld: Rename a file on Windows fails if target already exists X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=233cd5946413108bf4902b22a9cb23ad0a468f5e;p=thirdparty%2Fbinutils-gdb.git ld: Rename a file on Windows fails if target already exists To rename a file on Windows, the target name cannot exist. Removing file prior to renaming ensures this is handled. To remove a file on Windows, the file cannot be open. Closing the bfd handle ensures this is handled. Moved call to free on isympp / osympp to after bfd is closed to align with comment earlier in the cmdline_add_object_only_section function. Signed-off-by: Torbjörn SVENSSON --- diff --git a/ld/ldlang.c b/ld/ldlang.c index d4b4ef2f29b..6e31c359c9d 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -43,6 +43,7 @@ #include "hashtab.h" #include "elf-bfd.h" #include "bfdver.h" +#include #if BFD_SUPPORTS_PLUGINS #include "plugin.h" @@ -10840,10 +10841,19 @@ cmdline_add_object_only_section (bfd_byte *contents, size_t size) fatal (_("%P: failed to finish output with object-only section\n")); } + /* ibfd needs to be closed *after* obfd, otherwise ld may crash with a + segmentation fault. */ + if (!bfd_close (ibfd)) + einfo (_("%P%F: failed to close input\n")); + /* Must be freed after bfd_close (). */ free (isympp); free (osympp); + /* Must unlink to ensure rename works on Windows. */ + if (unlink (output_filename) && errno != ENOENT) + einfo (_("%P%F: failed to unlink %s\n"), output_filename); + if (rename (ofilename, output_filename)) { unlink (ofilename); @@ -10854,10 +10864,14 @@ cmdline_add_object_only_section (bfd_byte *contents, size_t size) return; loser: - free (isympp); - free (osympp); if (obfd) bfd_close (obfd); + /* ibfd needs to be closed *after* obfd, otherwise ld may crash with a + segmentation fault. */ + if (ibfd) + bfd_close (ibfd); + free (isympp); + free (osympp); if (ofilename) { unlink (ofilename);