[PATCH v4] ld: Rename a file on Windows fails if target already exists

Torbjörn SVENSSON torbjorn.svensson@foss.st.com
Tue Jul 22 14:14:29 GMT 2025


Changes since v3:

- Moved free of isympp/osympp to after bfd_close ().
- Added comment that ibfd needs to be closed *after* obfd. 

Changes since v2:

- Fixed regression reported by Linaro CI by reversing the
  order of bfd_close calls.

Changes since v1:

- Apparently, the include of errno was never committed before.
  I've rebuilt and rechecked that this works on Windows again.


Without this patch, the GCC testsuite gives errors like:

Testing gcc.dg/lto/20091027-1, -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin
doing compile
Executing on host: arm-none-eabi-gcc.exe   -mthumb -march=armv6s-m -mcpu=cortex-m0 -mfloat-abi=soft   -fdiagnostics-plain-output  -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin   -c     -o c_lto_20091027-1_0.o /build/src/gcc/gcc/testsuite/gcc.dg/lto/20091027-1_0.c    (timeout = 800)
spawn -ignore SIGHUP arm-none-eabi-gcc.exe -mthumb -march=armv6s-m -mcpu=cortex-m0 -mfloat-abi=soft -fdiagnostics-plain-output -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin -c -o c_lto_20091027-1_0.o /build/src/gcc/gcc/testsuite/gcc.dg/lto/20091027-1_0.c
pid is 52421 -52421
pid is -1
output is  status 0
PASS: gcc.dg/lto/20091027-1 c_lto_20091027-1_0.o assemble, -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin
doing compile
Executing on host: arm-none-eabi-gcc.exe   -mthumb -march=armv6s-m -mcpu=cortex-m0 -mfloat-abi=soft   -fdiagnostics-plain-output  -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin   -c     -o c_lto_20091027-1_1.o /build/src/gcc/gcc/testsuite/gcc.dg/lto/20091027-1_1.c    (timeout = 800)
spawn -ignore SIGHUP arm-none-eabi-gcc.exe -mthumb -march=armv6s-m -mcpu=cortex-m0 -mfloat-abi=soft -fdiagnostics-plain-output -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin -c -o c_lto_20091027-1_1.o /build/src/gcc/gcc/testsuite/gcc.dg/lto/20091027-1_1.c
pid is 52444 -52444
pid is -1
output is  status 0
PASS: gcc.dg/lto/20091027-1 c_lto_20091027-1_1.o assemble, -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin
doing compile
Executing on host: arm-none-eabi-gcc.exe  c_lto_20091027-1_0.o c_lto_20091027-1_1.o  -mthumb -march=armv6s-m -mcpu=cortex-m0 -mfloat-abi=soft   -dumpbase "" -fdiagnostics-plain-output  -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin  -r -nostdlib -flinker-output=nolto-rel      -Wl,--start-group -lc -lm -Wl,--end-group --specs=nosys.specs      -o gcc-dg-lto-20091027-1-21.exe    (timeout = 800)
spawn -ignore SIGHUP arm-none-eabi-gcc.exe c_lto_20091027-1_0.o c_lto_20091027-1_1.o -mthumb -march=armv6s-m -mcpu=cortex-m0 -mfloat-abi=soft -dumpbase  -fdiagnostics-plain-output -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin -r -nostdlib -flinker-output=nolto-rel -Wl,--start-group -lc -lm -Wl,--end-group --specs=nosys.specs -o gcc-dg-lto-20091027-1-21.exe
pid is 52471 -52471
T:../lib/gcc/arm-none-eabi/14.3.1/../../../../arm-none-eabi/bin/ld.exe: failed to rename output with object-only section
collect2.exe: error: ld returned 1 exit status
pid is -1
close result is 52471 exp6 0 1
output is T:../lib/gcc/arm-none-eabi/14.3.1/../../../../arm-none-eabi/bin/ld.exe: failed to rename output with object-only section
collect2.exe: error: ld returned 1 exit status
 status 1
compiler exited with status 1
FAIL: gcc.dg/lto/20091027-1 c_lto_20091027-1_0.o-c_lto_20091027-1_1.o link, -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin


With this patch, the test is a PASS.


I've tested the patch on Linux x86_64 without any regression.
Ok for trunk and binutils-2_45-branch?

--

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.

Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
---
 ld/ldlang.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/ld/ldlang.c b/ld/ldlang.c
index d4b4ef2f29b..2df22d255f4 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -43,6 +43,7 @@
 #include "hashtab.h"
 #include "elf-bfd.h"
 #include "bfdver.h"
+#include <errno.h>
 
 #if BFD_SUPPORTS_PLUGINS
 #include "plugin.h"
@@ -10840,10 +10841,23 @@ 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 will 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 +10868,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 will crash with a
+     segmentation fault.  */
+  if (ibfd)
+    bfd_close (ibfd);
+  free (isympp);
+  free (osympp);
   if (ofilename)
     {
       unlink (ofilename);
-- 
2.25.1



More information about the Binutils mailing list