Close elements of output archive

Message ID Z3U3_W97XwPNaxZ_@squeak.grove.modra.org
State New
Headers
Series Close elements of output archive |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 fail Patch failed to apply

Commit Message

Alan Modra Jan. 1, 2025, 12:41 p.m. UTC
  When cleaning up an archive, close all its elements.  This fixes a
number of ar memory leaks.

bfd/
	* archive.c (_bfd_archive_close_and_cleanup): Close elements
	of an archive open for writing.
binutils/
	* objcopy.c (copy_archive): Don't close output archive
	elements here.
	* dlltool.c (gen_lib_file): Likewise.
ld/
	* pe-dll.c (pe_dll_generate_implib): Don't close output
	archive elements here.
  

Patch

diff --git a/bfd/archive.c b/bfd/archive.c
index b3019e21059..ef0109599e1 100644
--- a/bfd/archive.c
+++ b/bfd/archive.c
@@ -2882,6 +2882,15 @@  _bfd_unlink_from_archive_parent (bfd *abfd)
 bool
 _bfd_archive_close_and_cleanup (bfd *abfd)
 {
+  if (bfd_write_p (abfd) && abfd->format == bfd_archive)
+    {
+      bfd *current;
+      while ((current = abfd->archive_head) != NULL)
+	{
+	  abfd->archive_head = current->archive_next;
+	  bfd_close_all_done (current);
+	}
+    }
   if (bfd_read_p (abfd) && abfd->format == bfd_archive)
     {
       bfd *nbfd;
diff --git a/binutils/dlltool.c b/binutils/dlltool.c
index 4426aae713e..d32bf2062b4 100644
--- a/binutils/dlltool.c
+++ b/binutils/dlltool.c
@@ -3009,13 +3009,6 @@  gen_lib_file (int delay)
   if (! bfd_close (outarch))
     bfd_fatal (imp_name);
 
-  while (head != NULL)
-    {
-      bfd *n = head->archive_next;
-      bfd_close (head);
-      head = n;
-    }
-
   /* Delete all the temp files.  */
   unlink_temp_files ();
 
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 10539ed054b..f64417697cb 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -3845,10 +3845,7 @@  copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
 	  if (l->obfd == NULL)
 	    rmdir (l->name);
 	  else
-	    {
-	      bfd_close (l->obfd);
-	      unlink (l->name);
-	    }
+	    unlink (l->name);
 	  free (l->name);
 	}
       next = l->next;
diff --git a/ld/pe-dll.c b/ld/pe-dll.c
index 2b2ef68b31c..d888a0b6373 100644
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -3058,13 +3058,6 @@  pe_dll_generate_implib (def_file *def, const char *impfilename, struct bfd_link_
 
   if (! bfd_close (outarch))
     einfo ("%X%P: bfd_close %s: %E\n", impfilename);
-
-  while (head != NULL)
-    {
-      bfd *n = head->archive_next;
-      bfd_close (head);
-      head = n;
-    }
 }
 
 static int undef_count = 0;