]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Free bfds on the file_chain at linker exit.
authorNick Clifton <nickc@redhat.com>
Wed, 4 Feb 2026 11:37:25 +0000 (11:37 +0000)
committerNick Clifton <nickc@redhat.com>
Wed, 4 Feb 2026 11:37:25 +0000 (11:37 +0000)
ld/ldlang.c
ld/ldlang.h
ld/ldmain.c

index c0d729811ecf921c71227fdc421a6d7a047567b3..a8c7854b5f8be75014bdb4715c938c43a42d2b1c 100644 (file)
@@ -1427,6 +1427,37 @@ lang_finish (void)
   ldfile_free ();
 }
 
+/* Called by ld_cleanup() at linker exit.  Frees any remaining memory used by
+   ldlang.c in order to pacify memory leak checkers.  */
+
+void
+lang_cleanup (void)
+{
+  lang_input_statement_type *search;
+
+  /* FIXME: Walking the file_chain list closes most of the open bfds but not
+     all of them.  We should find and close the others as well.
+
+     Note: the bfds closed here can also be found on the input_file_chain and
+     link_info.input_bfd lists.  A bfd can only be closed once however, so we
+     must not walk those other lists.  */
+
+  for (search = (void *) file_chain.head;
+       search != NULL;
+       search = search->next_real_file)
+    {
+      if (search->the_bfd == NULL)
+       continue;
+      
+      bfd_close_all_done (search->the_bfd);
+      search->the_bfd = NULL;
+    }
+
+  stat_free (NULL);
+
+  obstack_free (&pt_obstack, NULL);
+}
+
 /*----------------------------------------------------------------------
   A region is an area of memory declared with the
   MEMORY {  name:org=exp, len=exp ... }
index 36f3c03955dadfa6ccb90ca165a988f8cebe5dfc..c3ee40a980ce3cec545760fe5cdc669e99d0846a 100644 (file)
@@ -546,6 +546,8 @@ extern void lang_init
   (bool);
 extern void lang_finish
   (void);
+extern void lang_cleanup
+  (void);
 extern lang_memory_region_type * lang_memory_region_lookup
   (const char * const, bool);
 extern void lang_memory_region_alias
index a2711d230ea06d5576e697f15d26ecccc5c2e82b..c73c228e59d75e118b5ef5f4ec9dde16632e9b24 100644 (file)
@@ -222,14 +222,11 @@ write_dependency_file (void)
 static void
 ld_cleanup (void)
 {
-  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);
-    }
+
+  lang_cleanup ();
+
   /* Note - we do not call ld_plugin_start (PHASE_PLUGINS) here as this
      function is only called when the linker is exiting - ie after any
      stats may have been reported, and potentially in the middle of a