Call bfd_close_all_done in ld_cleanup

Alan Modra amodra@gmail.com
Fri Jan 27 07:02:34 GMT 2023


This is similar to "Call bfd_close_all_done in output_file_close",
but with some code tidying in the pe/pep write_build_id functions.
write_build_id is passed the output bfd as its parameter, so there is
no need to go looking for the output bfd via link_info (and doing so
will no longer work since I clear link_info.output_bfd before calling
bfd_close).

	* emultempl/pe.em (write_build_id): Rename t to td.  Formatting.
	Don't access pe_data(link_info.output_bfd), use td instead.
	(setup_build_id): Rename t to td.  Formatting.
	* emultempl/pep.em: As for pe.em.
	* ldmain.c (ld_cleanup): Call bfd_close_all_done on linker bfds.
	(main): Clear link_info.output_bfd when closing.

diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index 7e1866a23c7..55412d6ef9e 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -1300,7 +1300,7 @@ pecoff_checksum_contents (bfd *abfd,
 static bool
 write_build_id (bfd *abfd)
 {
-  struct pe_tdata *t = pe_data (abfd);
+  struct pe_tdata *td = pe_data (abfd);
   asection *asec;
   struct bfd_link_order *link_order = NULL;
   unsigned char *contents;
@@ -1316,7 +1316,7 @@ write_build_id (bfd *abfd)
 	{
 	  if (l->type == bfd_indirect_link_order)
 	    {
-	      if (l->u.indirect.section == t->build_id.sec)
+	      if (l->u.indirect.section == td->build_id.sec)
 		{
 		  link_order = l;
 		  break;
@@ -1335,15 +1335,16 @@ write_build_id (bfd *abfd)
       return true;
     }
 
-  if (t->build_id.sec->contents == NULL)
-    t->build_id.sec->contents = (unsigned char *) xmalloc (t->build_id.sec->size);
-  contents = t->build_id.sec->contents;
+  if (td->build_id.sec->contents == NULL)
+    td->build_id.sec->contents = xmalloc (td->build_id.sec->size);
+  contents = td->build_id.sec->contents;
 
-  build_id_size = compute_build_id_size (t->build_id.style);
+  build_id_size = compute_build_id_size (td->build_id.style);
   build_id = xmalloc (build_id_size);
-  generate_build_id (abfd, t->build_id.style, pecoff_checksum_contents, build_id, build_id_size);
+  generate_build_id (abfd, td->build_id.style, pecoff_checksum_contents,
+		     build_id, build_id_size);
 
-  bfd_vma ib = pe_data (link_info.output_bfd)->pe_opthdr.ImageBase;
+  bfd_vma ib = td->pe_opthdr.ImageBase;
 
 #ifdef PDB_H
   if (pdb_name)
@@ -1390,10 +1391,12 @@ write_build_id (bfd *abfd)
   cvinfo.CVSignature = CVINFO_PDB70_CVSIGNATURE;
   cvinfo.Age = 1;
 
-  /* Zero pad or truncate the generated build_id to fit in the CodeView record.  */
+  /* Zero pad or truncate the generated build_id to fit in the
+     CodeView record.  */
   memset (&(cvinfo.Signature), 0, CV_INFO_SIGNATURE_LENGTH);
-  memcpy (&(cvinfo.Signature), build_id, (build_id_size > CV_INFO_SIGNATURE_LENGTH)
-	  ? CV_INFO_SIGNATURE_LENGTH :  build_id_size);
+  memcpy (&(cvinfo.Signature), build_id,
+	  (build_id_size > CV_INFO_SIGNATURE_LENGTH
+	   ? CV_INFO_SIGNATURE_LENGTH : build_id_size));
 
   free (build_id);
 
@@ -1403,9 +1406,9 @@ write_build_id (bfd *abfd)
     return 0;
 
   /* Record the location of the debug directory in the data directory.  */
-  pe_data (link_info.output_bfd)->pe_opthdr.DataDirectory[PE_DEBUG_DATA].VirtualAddress
-    = asec->vma  - ib + link_order->offset;
-  pe_data (link_info.output_bfd)->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size
+  td->pe_opthdr.DataDirectory[PE_DEBUG_DATA].VirtualAddress
+    = asec->vma - ib + link_order->offset;
+  td->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size
     = sizeof (struct external_IMAGE_DEBUG_DIRECTORY);
 
   return true;
@@ -1429,17 +1432,17 @@ setup_build_id (bfd *ibfd)
   s = bfd_make_section_anyway_with_flags (ibfd, ".buildid", flags);
   if (s != NULL)
     {
-      struct pe_tdata *t = pe_data (link_info.output_bfd);
-      t->build_id.after_write_object_contents = &write_build_id;
-      t->build_id.style = emit_build_id;
-      t->build_id.sec = s;
+      struct pe_tdata *td = pe_data (link_info.output_bfd);
+      td->build_id.after_write_object_contents = &write_build_id;
+      td->build_id.style = emit_build_id;
+      td->build_id.sec = s;
 
       /* Section is a fixed size:
 	 One IMAGE_DEBUG_DIRECTORY entry, of type IMAGE_DEBUG_TYPE_CODEVIEW,
 	 pointing at a CV_INFO_PDB70 record containing the build-id, followed by
 	 PdbFileName if relevant.  */
-      s->size = sizeof (struct external_IMAGE_DEBUG_DIRECTORY)
-	+ sizeof (CV_INFO_PDB70) + 1;
+      s->size = (sizeof (struct external_IMAGE_DEBUG_DIRECTORY)
+		 + sizeof (CV_INFO_PDB70) + 1);
 
 #ifdef PDB_H
       if (pdb_name)
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index 613a2c70531..2a3fd0e6ea8 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -1302,7 +1302,7 @@ pecoff_checksum_contents (bfd *abfd,
 static bool
 write_build_id (bfd *abfd)
 {
-  struct pe_tdata *t = pe_data (abfd);
+  struct pe_tdata *td = pe_data (abfd);
   asection *asec;
   struct bfd_link_order *link_order = NULL;
   unsigned char *contents;
@@ -1318,7 +1318,7 @@ write_build_id (bfd *abfd)
 	{
 	  if (l->type == bfd_indirect_link_order)
 	    {
-	      if (l->u.indirect.section == t->build_id.sec)
+	      if (l->u.indirect.section == td->build_id.sec)
 		{
 		  link_order = l;
 		  break;
@@ -1337,15 +1337,16 @@ write_build_id (bfd *abfd)
       return true;
     }
 
-  if (t->build_id.sec->contents == NULL)
-    t->build_id.sec->contents = (unsigned char *) xmalloc (t->build_id.sec->size);
-  contents = t->build_id.sec->contents;
+  if (td->build_id.sec->contents == NULL)
+    td->build_id.sec->contents = xmalloc (td->build_id.sec->size);
+  contents = td->build_id.sec->contents;
 
-  build_id_size = compute_build_id_size (t->build_id.style);
+  build_id_size = compute_build_id_size (td->build_id.style);
   build_id = xmalloc (build_id_size);
-  generate_build_id (abfd, t->build_id.style, pecoff_checksum_contents, build_id, build_id_size);
+  generate_build_id (abfd, td->build_id.style, pecoff_checksum_contents,
+		     build_id, build_id_size);
 
-  bfd_vma ib = pe_data (link_info.output_bfd)->pe_opthdr.ImageBase;
+  bfd_vma ib = td->pe_opthdr.ImageBase;
 
 #ifdef PDB_H
   if (pdb_name)
@@ -1372,7 +1373,7 @@ write_build_id (bfd *abfd)
   struct external_IMAGE_DEBUG_DIRECTORY *ext = (struct external_IMAGE_DEBUG_DIRECTORY *)contents;
   _bfd_XXi_swap_debugdir_out (abfd, &idd, ext);
 
-  /* Write the debug directory enttry */
+  /* Write the debug directory entry.  */
   if (bfd_seek (abfd, asec->filepos + link_order->offset, SEEK_SET) != 0)
     return 0;
 
@@ -1392,10 +1393,12 @@ write_build_id (bfd *abfd)
   cvinfo.CVSignature = CVINFO_PDB70_CVSIGNATURE;
   cvinfo.Age = 1;
 
-  /* Zero pad or truncate the generated build_id to fit in the CodeView record.  */
+  /* Zero pad or truncate the generated build_id to fit in the
+     CodeView record.  */
   memset (&(cvinfo.Signature), 0, CV_INFO_SIGNATURE_LENGTH);
-  memcpy (&(cvinfo.Signature), build_id, (build_id_size > CV_INFO_SIGNATURE_LENGTH)
-	  ? CV_INFO_SIGNATURE_LENGTH :  build_id_size);
+  memcpy (&(cvinfo.Signature), build_id,
+	  (build_id_size > CV_INFO_SIGNATURE_LENGTH
+	   ? CV_INFO_SIGNATURE_LENGTH : build_id_size));
 
   free (build_id);
 
@@ -1405,9 +1408,9 @@ write_build_id (bfd *abfd)
     return 0;
 
   /* Record the location of the debug directory in the data directory.  */
-  pe_data (link_info.output_bfd)->pe_opthdr.DataDirectory[PE_DEBUG_DATA].VirtualAddress
-    = asec->vma  - ib + link_order->offset;
-  pe_data (link_info.output_bfd)->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size
+  td->pe_opthdr.DataDirectory[PE_DEBUG_DATA].VirtualAddress
+    = asec->vma - ib + link_order->offset;
+  td->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size
     = sizeof (struct external_IMAGE_DEBUG_DIRECTORY);
 
   return true;
@@ -1431,10 +1434,10 @@ setup_build_id (bfd *ibfd)
   s = bfd_make_section_anyway_with_flags (ibfd, ".buildid", flags);
   if (s != NULL)
     {
-      struct pe_tdata *t = pe_data (link_info.output_bfd);
-      t->build_id.after_write_object_contents = &write_build_id;
-      t->build_id.style = emit_build_id;
-      t->build_id.sec = s;
+      struct pe_tdata *td = pe_data (link_info.output_bfd);
+      td->build_id.after_write_object_contents = &write_build_id;
+      td->build_id.style = emit_build_id;
+      td->build_id.sec = s;
 
       /* Section is a fixed size:
 	 One IMAGE_DEBUG_DIRECTORY entry, of type IMAGE_DEBUG_TYPE_CODEVIEW,
diff --git a/ld/ldmain.c b/ld/ldmain.c
index 9290a189b0d..8c2fc9b8d8c 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -212,7 +212,14 @@ write_dependency_file (void)
 static void
 ld_cleanup (void)
 {
-  bfd_cache_close_all ();
+  bfd *ibfd, *inext;
+  if (link_info.output_bfd)
+    bfd_close_all_done (link_info.output_bfd);
+  for (ibfd = link_info.input_bfds; ibfd; ibfd = inext)
+    {
+      inext = ibfd->link.next;
+      bfd_close_all_done (ibfd);
+    }
 #if BFD_SUPPORTS_PLUGINS
   plugin_call_cleanup ();
 #endif
@@ -559,7 +566,9 @@ main (int argc, char **argv)
     }
   else
     {
-      if (!bfd_close (link_info.output_bfd))
+      bfd *obfd = link_info.output_bfd;
+      link_info.output_bfd = NULL;
+      if (!bfd_close (obfd))
 	einfo (_("%F%P: %s: final close failed: %E\n"), output_filename);
 
       /* If the --force-exe-suffix is enabled, and we're making an
@@ -621,7 +630,7 @@ main (int argc, char **argv)
       fflush (stderr);
     }
 
-  /* Prevent ld_cleanup from doing anything, after a successful link.  */
+  /* Prevent ld_cleanup from deleting the output file.  */
   output_filename = NULL;
 
   xexit (0);

-- 
Alan Modra
Australia Development Lab, IBM


More information about the Binutils mailing list