From: Nick Clifton Date: Wed, 4 Feb 2026 11:37:25 +0000 (+0000) Subject: Free bfds on the file_chain at linker exit. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=52fdc0531ea7;p=thirdparty%2Fbinutils-gdb.git Free bfds on the file_chain at linker exit. --- diff --git a/ld/ldlang.c b/ld/ldlang.c index c0d729811ec..a8c7854b5f8 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -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 ... } diff --git a/ld/ldlang.h b/ld/ldlang.h index 36f3c03955d..c3ee40a980c 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -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 diff --git a/ld/ldmain.c b/ld/ldmain.c index a2711d230ea..c73c228e59d 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -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