From: Alan Modra Date: Wed, 7 Jun 2023 04:46:06 +0000 (+0930) Subject: _bfd_free_cached_info X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ba75d1c55cb42114e3bb5c8abe37e5c2bd657a02;p=binutils-gdb.git _bfd_free_cached_info doc/bfdint.texi and comments in the aout and som code about this function are just wrong, and its name is not very apt. Better would be _bfd_mostly_destroy, and we certainly should not be saying anything about the possibility of later recreating anything lost by this function. What's more, if _bfd_free_cached_info is called when creating an archive map to reduce memory usage by throwing away symbols, the target _close_and_cleanup function won't have access to tdata or section bfd_user_data to tidy memory. This means most of the target _close_and_cleanup function won't do anything, and therefore sometimes will result in memory leaks. This patch fixes the documentation problems and moves most of the target _close_and_cleanup code to target _bfd_free_cached_info. Another notable change is that bfd_generic_bfd_free_cached_info is now defined as _bfd_free_cached_info rather than _bfd_bool_bfd_true, ie. the default now frees objalloc memory. --- diff --git a/bfd/aout-target.h b/bfd/aout-target.h index 6d2f3c767a2..7765f5c80d8 100644 --- a/bfd/aout-target.h +++ b/bfd/aout-target.h @@ -598,18 +598,7 @@ MY_bfd_final_link (bfd *abfd, struct bfd_link_info *info) #endif #ifndef MY_close_and_cleanup - -/* Handle closing of a BFD including the resource-releasing parts. */ - -static bool -MY_close_and_cleanup (bfd *abfd) -{ - if (!MY_bfd_free_cached_info (abfd)) - return false; - - return _bfd_generic_close_and_cleanup (abfd); -} - +#define MY_close_and_cleanup _bfd_generic_close_and_cleanup #endif #ifndef MY_get_dynamic_symtab_upper_bound diff --git a/bfd/aoutx.h b/bfd/aoutx.h index 6d6527640fe..1a8fd85cf14 100644 --- a/bfd/aoutx.h +++ b/bfd/aoutx.h @@ -2896,35 +2896,33 @@ NAME (aout, sizeof_headers) (bfd *abfd, return adata (abfd).exec_bytes_size; } -/* Free all information we have cached for this BFD. We can always - read it again later if we need it. */ +/* Throw away most malloc'd and alloc'd information for this BFD. */ bool NAME (aout, bfd_free_cached_info) (bfd *abfd) { - asection *o; - - if (bfd_get_format (abfd) != bfd_object - || abfd->tdata.aout_data == NULL) - return true; - + if ((bfd_get_format (abfd) == bfd_object + || bfd_get_format (abfd) == bfd_core) + && abfd->tdata.aout_data != NULL) + { #define BFCI_FREE(x) do { free (x); x = NULL; } while (0) - BFCI_FREE (adata (abfd).line_buf); - BFCI_FREE (obj_aout_symbols (abfd)); + BFCI_FREE (adata (abfd).line_buf); + BFCI_FREE (obj_aout_symbols (abfd)); #ifdef USE_MMAP - obj_aout_external_syms (abfd) = 0; - bfd_free_window (&obj_aout_sym_window (abfd)); - bfd_free_window (&obj_aout_string_window (abfd)); - obj_aout_external_strings (abfd) = 0; + obj_aout_external_syms (abfd) = 0; + bfd_free_window (&obj_aout_sym_window (abfd)); + bfd_free_window (&obj_aout_string_window (abfd)); + obj_aout_external_strings (abfd) = 0; #else - BFCI_FREE (obj_aout_external_syms (abfd)); - BFCI_FREE (obj_aout_external_strings (abfd)); + BFCI_FREE (obj_aout_external_syms (abfd)); + BFCI_FREE (obj_aout_external_strings (abfd)); #endif - for (o = abfd->sections; o != NULL; o = o->next) - BFCI_FREE (o->relocation); + for (asection *o = abfd->sections; o != NULL; o = o->next) + BFCI_FREE (o->relocation); #undef BFCI_FREE + } - return true; + return _bfd_generic_bfd_free_cached_info (abfd); } /* a.out link code. */ diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index 421dc8f7ee5..271a24fff69 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -4436,8 +4436,8 @@ const struct xcoff_dwsect_name xcoff_dwsect_names[] = { }; /* For generic entry points. */ -#define _bfd_xcoff_close_and_cleanup _bfd_coff_close_and_cleanup -#define _bfd_xcoff_bfd_free_cached_info _bfd_bool_bfd_true +#define _bfd_xcoff_close_and_cleanup coff_close_and_cleanup +#define _bfd_xcoff_bfd_free_cached_info coff_bfd_free_cached_info #define _bfd_xcoff_new_section_hook coff_new_section_hook #define _bfd_xcoff_get_section_contents _bfd_generic_get_section_contents #define _bfd_xcoff_get_section_contents_in_window \ diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c index 71d21583ee5..d76c99a3eca 100644 --- a/bfd/coff64-rs6000.c +++ b/bfd/coff64-rs6000.c @@ -2618,8 +2618,8 @@ const bfd_target rs6000_xcoff64_vec = }, /* Generic */ - _bfd_coff_close_and_cleanup, - _bfd_bool_bfd_true, + coff_close_and_cleanup, + coff_bfd_free_cached_info, coff_new_section_hook, _bfd_generic_get_section_contents, _bfd_generic_get_section_contents_in_window, @@ -2891,8 +2891,8 @@ const bfd_target rs6000_xcoff64_aix_vec = }, /* Generic */ - _bfd_coff_close_and_cleanup, - _bfd_bool_bfd_true, + coff_close_and_cleanup, + coff_bfd_free_cached_info, coff_new_section_hook, _bfd_generic_get_section_contents, _bfd_generic_get_section_contents_in_window, diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 47562713938..62720255b7f 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -5866,11 +5866,11 @@ static const bfd_coff_backend_data bigobj_swap_table = #endif /* COFF_WITH_PE_BIGOBJ */ #ifndef coff_close_and_cleanup -#define coff_close_and_cleanup _bfd_coff_close_and_cleanup +#define coff_close_and_cleanup _bfd_generic_close_and_cleanup #endif #ifndef coff_bfd_free_cached_info -#define coff_bfd_free_cached_info _bfd_generic_bfd_free_cached_info +#define coff_bfd_free_cached_info _bfd_coff_free_cached_info #endif #ifndef coff_get_section_contents diff --git a/bfd/coffgen.c b/bfd/coffgen.c index afc663c056f..9d45253178e 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -3275,43 +3275,37 @@ bfd_coff_group_name (bfd *abfd, const asection *sec) } bool -_bfd_coff_close_and_cleanup (bfd *abfd) +_bfd_coff_free_cached_info (bfd *abfd) { - struct coff_tdata *tdata = coff_data (abfd); + struct coff_tdata *tdata; - if (tdata != NULL) + if (bfd_family_coff (abfd) + && (bfd_get_format (abfd) == bfd_object + || bfd_get_format (abfd) == bfd_core) + && (tdata = coff_data (abfd)) != NULL) { - if (bfd_family_coff (abfd) && bfd_get_format (abfd) == bfd_object) + if (tdata->section_by_index) { - if (tdata->section_by_index) - { - htab_delete (tdata->section_by_index); - tdata->section_by_index = NULL; - } + htab_delete (tdata->section_by_index); + tdata->section_by_index = NULL; + } - if (tdata->section_by_target_index) - { - htab_delete (tdata->section_by_target_index); - tdata->section_by_target_index = NULL; - } + if (tdata->section_by_target_index) + { + htab_delete (tdata->section_by_target_index); + tdata->section_by_target_index = NULL; } + _bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info); + _bfd_stab_cleanup (abfd, &tdata->line_info); + /* PR 25447: Do not clear the keep_syms and keep_strings flags. These may have been set by pe_ILF_build_a_bfd() indicating that the syms and strings pointers are not to be freed. */ - if (bfd_get_format (abfd) == bfd_object - && bfd_family_coff (abfd) - && !_bfd_coff_free_symbols (abfd)) + if (!_bfd_coff_free_symbols (abfd)) return false; - - if (bfd_get_format (abfd) == bfd_object - || bfd_get_format (abfd) == bfd_core) - { - _bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info); - _bfd_stab_cleanup (abfd, &tdata->line_info); - } } - return _bfd_generic_close_and_cleanup (abfd); + return _bfd_generic_bfd_free_cached_info (abfd); } diff --git a/bfd/doc/bfdint.texi b/bfd/doc/bfdint.texi index cb251b1a0d6..8cf08576c1b 100644 --- a/bfd/doc/bfdint.texi +++ b/bfd/doc/bfdint.texi @@ -493,22 +493,25 @@ functions which don't easily fit into other categories. @table @samp @item _close_and_cleanup -Free any target specific information associated with the BFD. This is -called when any BFD is closed (the @samp{bfd_write_contents} function -mentioned earlier is only called for a BFD opened for writing). Most -targets use @samp{bfd_alloc} to allocate all target specific -information, and therefore don't have to do anything in this function. -This function pointer is typically set to -@samp{_bfd_generic_close_and_cleanup}, which simply returns true. +Free any target specific information associated with the BFD that +isn't freed by @samp{_bfd_free_cached_info}. This is called when any +BFD is closed (the @samp{bfd_write_contents} function mentioned +earlier is only called for a BFD opened for writing). This function +pointer is typically set to @samp{_bfd_generic_close_and_cleanup}, +which simply returns true. @item _bfd_free_cached_info -Free any cached information associated with the BFD which can be -recreated later if necessary. This is used to reduce the memory -consumption required by programs using BFD. This is normally called via -the @samp{bfd_free_cached_info} macro. It is used by the default -archive routines when computing the archive map. Most targets do not -do anything special for this entry point, and just set it to -@samp{_bfd_generic_free_cached_info}, which simply returns true. +This function is designed for use by the generic archive routines, and +is also called by bfd_close. After creating the archive map archive +element bfds don't need symbols and other structures. Many targets +use @samp{bfd_alloc} to allocate target specific information and thus +do not need to do anything special for this entry point, and just set +it to @samp{_bfd_generic_free_cached_info} which throws away objalloc +memory for the bfd. Note that this means the bfd tdata and sections +are no longer available. Targets that malloc memory, attaching it to +the bfd tdata or to section used_by_bfd should implement a target +version of this function to free that memory before calling +@samp{_bfd_generic_free_cached_info}. @item _new_section_hook This is called from @samp{bfd_make_section_anyway} whenever a new diff --git a/bfd/ecoff.c b/bfd/ecoff.c index 573f52d0299..f2626c541e2 100644 --- a/bfd/ecoff.c +++ b/bfd/ecoff.c @@ -110,18 +110,20 @@ _bfd_ecoff_mkobject_hook (bfd *abfd, void * filehdr, void * aouthdr) } bool -_bfd_ecoff_close_and_cleanup (bfd *abfd) +_bfd_ecoff_bfd_free_cached_info (bfd *abfd) { - struct ecoff_tdata *tdata = ecoff_data (abfd); + struct ecoff_tdata *tdata; - if (tdata != NULL && bfd_get_format (abfd) == bfd_object) + if ((bfd_get_format (abfd) == bfd_object + || bfd_get_format (abfd) == bfd_core) + && (tdata = ecoff_data (abfd)) != NULL) while (tdata->mips_refhi_list != NULL) { struct mips_hi *ref = tdata->mips_refhi_list; tdata->mips_refhi_list = ref->next; free (ref); } - return _bfd_generic_close_and_cleanup (abfd); + return _bfd_generic_bfd_free_cached_info (abfd); } /* Initialize a new section. */ diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 2a64a1e6a03..e08c5a110e5 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -2721,7 +2721,7 @@ extern bool bfd_elf_link_record_dynamic_symbol extern int bfd_elf_link_record_local_dynamic_symbol (struct bfd_link_info *, bfd *, long); -extern bool _bfd_elf_close_and_cleanup +extern bool _bfd_elf_free_cached_info (bfd *); extern bool _bfd_elf_common_definition diff --git a/bfd/elf.c b/bfd/elf.c index af2fb04dcbe..c4e2f89a16e 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -9589,21 +9589,22 @@ _bfd_elf_validate_reloc (bfd *abfd, arelent *areloc) } bool -_bfd_elf_close_and_cleanup (bfd *abfd) +_bfd_elf_free_cached_info (bfd *abfd) { - struct elf_obj_tdata *tdata = elf_tdata (abfd); - if (tdata != NULL - && (bfd_get_format (abfd) == bfd_object - || bfd_get_format (abfd) == bfd_core)) + struct elf_obj_tdata *tdata; + + if ((bfd_get_format (abfd) == bfd_object + || bfd_get_format (abfd) == bfd_core) + && (tdata = elf_tdata (abfd)) != NULL) { - if (elf_tdata (abfd)->o != NULL && elf_shstrtab (abfd) != NULL) + if (tdata->o != NULL && elf_shstrtab (abfd) != NULL) _bfd_elf_strtab_free (elf_shstrtab (abfd)); _bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info); _bfd_dwarf1_cleanup_debug_info (abfd, &tdata->dwarf1_find_line_info); _bfd_stab_cleanup (abfd, &tdata->line_info); } - return _bfd_generic_close_and_cleanup (abfd); + return _bfd_generic_bfd_free_cached_info (abfd); } /* For Rel targets, we encode meaningful data for BFD_RELOC_VTABLE_ENTRY diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c index 65e8131d5b1..27bd98607fe 100644 --- a/bfd/elf32-mips.c +++ b/bfd/elf32-mips.c @@ -2599,7 +2599,7 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = { _bfd_mips_elf_print_private_bfd_data #define bfd_elf32_bfd_relax_section _bfd_mips_elf_relax_section #define bfd_elf32_mkobject _bfd_mips_elf_mkobject -#define bfd_elf32_close_and_cleanup _bfd_mips_elf_close_and_cleanup +#define bfd_elf32_free_cached_info _bfd_mips_elf_free_cached_info /* Support for SGI-ish mips targets. */ #define TARGET_LITTLE_SYM mips_elf32_le_vec diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index 81d58c8cbc1..5cf9a665ae5 100644 --- a/bfd/elf64-alpha.c +++ b/bfd/elf64-alpha.c @@ -1519,13 +1519,6 @@ elf64_alpha_find_nearest_line (bfd *abfd, asymbol **symbols, (*swap->swap_fdr_in) (abfd, fraw_src, fdr_ptr); alpha_elf_tdata (abfd)->find_line_info = fi; - - /* Note that we don't bother to ever free this information. - find_nearest_line is either called all the time, as in - objdump -l, so the information should be saved, or it is - rarely called, as in ld error messages, so the memory - wasted is unimportant. Still, it would probably be a - good idea for free_cached_info to throw it away. */ } if (_bfd_ecoff_locate_line (abfd, section, offset, &fi->d, swap, diff --git a/bfd/elf64-ia64-vms.c b/bfd/elf64-ia64-vms.c index 1866a5798fa..a260c7ee6d8 100644 --- a/bfd/elf64-ia64-vms.c +++ b/bfd/elf64-ia64-vms.c @@ -4728,7 +4728,7 @@ elf64_vms_close_and_cleanup (bfd *abfd) } } - return _bfd_elf_close_and_cleanup (abfd); + return _bfd_generic_close_and_cleanup (abfd); } /* Add symbols from an ELF object file to the linker hash table. */ diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c index 696083e33a2..1179f622193 100644 --- a/bfd/elf64-mips.c +++ b/bfd/elf64-mips.c @@ -4815,7 +4815,7 @@ const struct elf_size_info mips_elf64_size_info = #define bfd_elf64_get_dynamic_reloc_upper_bound mips_elf64_get_dynamic_reloc_upper_bound #define bfd_elf64_mkobject _bfd_mips_elf_mkobject -#define bfd_elf64_close_and_cleanup _bfd_mips_elf_close_and_cleanup +#define bfd_elf64_free_cached_info _bfd_mips_elf_free_cached_info /* The SGI style (n)64 NewABI. */ #define TARGET_LITTLE_SYM mips_elf64_le_vec diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index a977bec2f50..9c0762a15ef 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -18406,7 +18406,7 @@ ppc64_elf_free_cached_info (bfd *abfd) if (opd->reloc_count == 0) free (ppc64_elf_section_data (opd)->u.opd.u.contents); - return _bfd_free_cached_info (abfd); + return _bfd_generic_bfd_free_cached_info (abfd); } #include "elf64-target.h" diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c index 9e943f2d25a..e6aa1673586 100644 --- a/bfd/elfn32-mips.c +++ b/bfd/elfn32-mips.c @@ -4197,7 +4197,7 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = { #define bfd_elf32_bfd_print_private_bfd_data \ _bfd_mips_elf_print_private_bfd_data #define bfd_elf32_mkobject mips_elf_n32_mkobject -#define bfd_elf32_close_and_cleanup _bfd_mips_elf_close_and_cleanup +#define bfd_elf32_free_cached_info _bfd_mips_elf_free_cached_info /* Support for SGI-ish mips targets using n32 ABI. */ diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 3ad5cb95b40..a75cd365a02 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -8742,7 +8742,7 @@ elfNN_aarch64_bfd_free_cached_info (bfd *abfd) bfd_map_over_sections (abfd, unrecord_section_via_map_over_sections, NULL); - return _bfd_free_cached_info (abfd); + return _bfd_generic_bfd_free_cached_info (abfd); } /* Create dynamic sections. This is different from the ARM backend in that diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 49355a42f7d..7d29ec2d105 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -1419,25 +1419,25 @@ free_ecoff_debug (struct ecoff_debug_info *debug) } bool -_bfd_mips_elf_close_and_cleanup (bfd *abfd) +_bfd_mips_elf_free_cached_info (bfd *abfd) { - if (bfd_get_format (abfd) == bfd_object) + struct mips_elf_obj_tdata *tdata; + + if ((bfd_get_format (abfd) == bfd_object + || bfd_get_format (abfd) == bfd_core) + && (tdata = mips_elf_tdata (abfd)) != NULL) { - struct mips_elf_obj_tdata *tdata = mips_elf_tdata (abfd); - if (tdata != NULL) + BFD_ASSERT (tdata->root.object_id == MIPS_ELF_DATA); + while (tdata->mips_hi16_list != NULL) { - BFD_ASSERT (tdata->root.object_id == MIPS_ELF_DATA); - while (tdata->mips_hi16_list != NULL) - { - struct mips_hi16 *hi = tdata->mips_hi16_list; - tdata->mips_hi16_list = hi->next; - free (hi); - } - if (tdata->find_line_info != NULL) - free_ecoff_debug (&tdata->find_line_info->d); + struct mips_hi16 *hi = tdata->mips_hi16_list; + tdata->mips_hi16_list = hi->next; + free (hi); } + if (tdata->find_line_info != NULL) + free_ecoff_debug (&tdata->find_line_info->d); } - return _bfd_elf_close_and_cleanup (abfd); + return _bfd_elf_free_cached_info (abfd); } bool diff --git a/bfd/elfxx-mips.h b/bfd/elfxx-mips.h index 2c790ed5ed6..d78b6798754 100644 --- a/bfd/elfxx-mips.h +++ b/bfd/elfxx-mips.h @@ -37,7 +37,7 @@ struct ecoff_debug_info; extern bool _bfd_mips_elf_mkobject (bfd *); -extern bool _bfd_mips_elf_close_and_cleanup +extern bool _bfd_mips_elf_free_cached_info (bfd *); extern bool _bfd_mips_elf_new_section_hook (bfd *, asection *); diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index 9bcbdfb27dd..8eabad4bd3f 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -28,10 +28,10 @@ one for little-endian machines. */ #ifndef bfd_elfNN_close_and_cleanup -#define bfd_elfNN_close_and_cleanup _bfd_elf_close_and_cleanup +#define bfd_elfNN_close_and_cleanup _bfd_generic_close_and_cleanup #endif #ifndef bfd_elfNN_bfd_free_cached_info -#define bfd_elfNN_bfd_free_cached_info _bfd_free_cached_info +#define bfd_elfNN_bfd_free_cached_info _bfd_elf_free_cached_info #endif #ifndef bfd_elfNN_get_section_contents #define bfd_elfNN_get_section_contents _bfd_generic_get_section_contents diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h index 07ef59a24e1..ae1b61aa4e3 100644 --- a/bfd/libbfd-in.h +++ b/bfd/libbfd-in.h @@ -261,7 +261,7 @@ extern int bfd_generic_stat_arch_elt extern bool _bfd_archive_close_and_cleanup (bfd *) ATTRIBUTE_HIDDEN; extern void _bfd_unlink_from_archive_parent (bfd *) ATTRIBUTE_HIDDEN; -#define _bfd_generic_bfd_free_cached_info _bfd_bool_bfd_true +#define _bfd_generic_bfd_free_cached_info _bfd_free_cached_info extern bool _bfd_generic_new_section_hook (bfd *, asection *) ATTRIBUTE_HIDDEN; extern bool _bfd_generic_get_section_contents diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 4f082ac75d6..92fbf0195ee 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -267,7 +267,7 @@ extern int bfd_generic_stat_arch_elt extern bool _bfd_archive_close_and_cleanup (bfd *) ATTRIBUTE_HIDDEN; extern void _bfd_unlink_from_archive_parent (bfd *) ATTRIBUTE_HIDDEN; -#define _bfd_generic_bfd_free_cached_info _bfd_bool_bfd_true +#define _bfd_generic_bfd_free_cached_info _bfd_free_cached_info extern bool _bfd_generic_new_section_hook (bfd *, asection *) ATTRIBUTE_HIDDEN; extern bool _bfd_generic_get_section_contents diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h index 96f44512ac5..4e2203656de 100644 --- a/bfd/libcoff-in.h +++ b/bfd/libcoff-in.h @@ -405,7 +405,7 @@ extern bfd_vma bfd_coff_reloc16_get_value (arelent *, struct bfd_link_info *, asection *); extern void bfd_perform_slip (bfd *, unsigned int, asection *, bfd_vma); -extern bool _bfd_coff_close_and_cleanup +extern bool _bfd_coff_free_cached_info (bfd *); /* Functions and types in cofflink.c. */ diff --git a/bfd/libcoff.h b/bfd/libcoff.h index 61561c5a471..b53c3117f50 100644 --- a/bfd/libcoff.h +++ b/bfd/libcoff.h @@ -409,7 +409,7 @@ extern bfd_vma bfd_coff_reloc16_get_value (arelent *, struct bfd_link_info *, asection *); extern void bfd_perform_slip (bfd *, unsigned int, asection *, bfd_vma); -extern bool _bfd_coff_close_and_cleanup +extern bool _bfd_coff_free_cached_info (bfd *); /* Functions and types in cofflink.c. */ diff --git a/bfd/libecoff.h b/bfd/libecoff.h index 12664b890c4..0c4bb43c39a 100644 --- a/bfd/libecoff.h +++ b/bfd/libecoff.h @@ -243,8 +243,8 @@ extern bool _bfd_ecoff_slurp_symbolic_info extern bool _bfd_ecoff_write_object_contents (bfd *); -extern bool _bfd_ecoff_close_and_cleanup (bfd *); -#define _bfd_ecoff_bfd_free_cached_info _bfd_generic_bfd_free_cached_info +#define _bfd_ecoff_close_and_cleanup _bfd_generic_close_and_cleanup +extern bool _bfd_ecoff_bfd_free_cached_info (bfd *); extern bool _bfd_ecoff_new_section_hook (bfd *, asection *); extern bool _bfd_ecoff_get_section_contents diff --git a/bfd/mach-o-target.c b/bfd/mach-o-target.c index f8e8dc73dc8..5211486696b 100644 --- a/bfd/mach-o-target.c +++ b/bfd/mach-o-target.c @@ -24,7 +24,6 @@ #ifndef MACH_O_TARGET_COMMON_DEFINED #define MACH_O_TARGET_COMMON_DEFINED -#define bfd_mach_o_bfd_free_cached_info _bfd_generic_bfd_free_cached_info #define bfd_mach_o_get_section_contents_in_window _bfd_generic_get_section_contents_in_window #define bfd_mach_o_bfd_print_private_bfd_data bfd_mach_o_bfd_print_private_bfd_data #define bfd_mach_o_bfd_is_target_special_symbol _bfd_bool_bfd_asymbol_false diff --git a/bfd/mach-o.c b/bfd/mach-o.c index 9b9aba5ae89..55407fa347d 100644 --- a/bfd/mach-o.c +++ b/bfd/mach-o.c @@ -6199,8 +6199,6 @@ bfd_mach_o_close_and_cleanup (bfd *abfd) bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); if (bfd_get_format (abfd) == bfd_object && mdata != NULL) { - _bfd_dwarf2_cleanup_debug_info (abfd, &mdata->dwarf2_find_line_info); - bfd_mach_o_free_cached_info (abfd); if (mdata->dsym_bfd != NULL) { bfd *fat_bfd = mdata->dsym_bfd->my_archive; @@ -6231,18 +6229,27 @@ bfd_mach_o_close_and_cleanup (bfd *abfd) } bool -bfd_mach_o_free_cached_info (bfd *abfd) +bfd_mach_o_bfd_free_cached_info (bfd *abfd) { - bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd); - asection *asect; - free (mdata->dyn_reloc_cache); - mdata->dyn_reloc_cache = NULL; - for (asect = abfd->sections; asect != NULL; asect = asect->next) + bfd_mach_o_data_struct *mdata; + + if ((bfd_get_format (abfd) == bfd_object + || bfd_get_format (abfd) == bfd_core) + && (mdata = bfd_mach_o_get_data (abfd)) != NULL) { - free (asect->relocation); - asect->relocation = NULL; + _bfd_dwarf2_cleanup_debug_info (abfd, &mdata->dwarf2_find_line_info); + free (mdata->dyn_reloc_cache); + mdata->dyn_reloc_cache = NULL; + + for (asection *asect = abfd->sections; asect; asect = asect->next) + { + free (asect->relocation); + asect->relocation = NULL; + } } + /* Do not call _bfd_generic_bfd_free_cached_info here. + bfd_mach_o_close_and_cleanup uses tdata. */ return true; } diff --git a/bfd/mach-o.h b/bfd/mach-o.h index 8d99c93ea5f..1c71163bb3a 100644 --- a/bfd/mach-o.h +++ b/bfd/mach-o.h @@ -733,7 +733,7 @@ bool bfd_mach_o_find_nearest_line (bfd *, asymbol **, _bfd_nosymbols_find_nearest_line_with_alt #define bfd_mach_o_find_line _bfd_nosymbols_find_line bool bfd_mach_o_close_and_cleanup (bfd *); -bool bfd_mach_o_free_cached_info (bfd *); +bool bfd_mach_o_bfd_free_cached_info (bfd *); unsigned int bfd_mach_o_section_get_nbr_indirect (bfd *, bfd_mach_o_section *); unsigned int bfd_mach_o_section_get_entry_size (bfd *, bfd_mach_o_section *); diff --git a/bfd/pdp11.c b/bfd/pdp11.c index 9edbba92c82..68809e5340c 100644 --- a/bfd/pdp11.c +++ b/bfd/pdp11.c @@ -2531,35 +2531,33 @@ NAME (aout, sizeof_headers) (bfd *abfd, return adata (abfd).exec_bytes_size; } -/* Free all information we have cached for this BFD. We can always - read it again later if we need it. */ +/* Throw away most malloc'd and alloc'd information for this BFD. */ bool NAME (aout, bfd_free_cached_info) (bfd *abfd) { - asection *o; - - if (bfd_get_format (abfd) != bfd_object - || abfd->tdata.aout_data == NULL) - return true; - + if ((bfd_get_format (abfd) == bfd_object + || bfd_get_format (abfd) == bfd_core) + && abfd->tdata.aout_data != NULL) + { #define BFCI_FREE(x) do { free (x); x = NULL; } while (0) - BFCI_FREE (adata (abfd).line_buf); - BFCI_FREE (obj_aout_symbols (abfd)); + BFCI_FREE (adata (abfd).line_buf); + BFCI_FREE (obj_aout_symbols (abfd)); #ifdef USE_MMAP - obj_aout_external_syms (abfd) = 0; - bfd_free_window (&obj_aout_sym_window (abfd)); - bfd_free_window (&obj_aout_string_window (abfd)); - obj_aout_external_strings (abfd) = 0; + obj_aout_external_syms (abfd) = 0; + bfd_free_window (&obj_aout_sym_window (abfd)); + bfd_free_window (&obj_aout_string_window (abfd)); + obj_aout_external_strings (abfd) = 0; #else - BFCI_FREE (obj_aout_external_syms (abfd)); - BFCI_FREE (obj_aout_external_strings (abfd)); + BFCI_FREE (obj_aout_external_syms (abfd)); + BFCI_FREE (obj_aout_external_strings (abfd)); #endif - for (o = abfd->sections; o != NULL; o = o->next) - BFCI_FREE (o->relocation); + for (asection *o = abfd->sections; o != NULL; o = o->next) + BFCI_FREE (o->relocation); #undef BFCI_FREE + } - return true; + return _bfd_generic_bfd_free_cached_info (abfd); } /* Routine to create an entry in an a.out link hash table. */ diff --git a/bfd/som.c b/bfd/som.c index ef1f6dc3eb6..61f755e0444 100644 --- a/bfd/som.c +++ b/bfd/som.c @@ -6789,13 +6789,13 @@ som_write_armap (bfd *abfd, return true; } -/* Free all information we have cached for this BFD. We can always - read it again later if we need it. */ +/* Throw away some malloc'd information for this BFD. */ static bool som_bfd_free_cached_info (bfd *abfd) { - if (bfd_get_format (abfd) == bfd_object) + if (bfd_get_format (abfd) == bfd_object + || bfd_get_format (abfd) == bfd_core) { asection *o; @@ -6813,8 +6813,8 @@ som_bfd_free_cached_info (bfd *abfd) #undef FREE } - /* Do not call _bfd_free_cached_info here. som_write_armap needs - to access the bfd obj_alloc memory. */ + /* Do not call _bfd_generic_bfd_free_cached_info here. + som_write_armap needs to access the bfd objalloc memory. */ return true; } diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c index b0ad4016da3..704dc631b7d 100644 --- a/bfd/vms-alpha.c +++ b/bfd/vms-alpha.c @@ -10103,25 +10103,12 @@ bfd_vms_get_data (bfd *abfd) return (struct vms_private_data_struct *)abfd->tdata.any; } -#define vms_bfd_is_target_special_symbol _bfd_bool_bfd_asymbol_false -#define vms_bfd_link_just_syms _bfd_generic_link_just_syms -#define vms_bfd_copy_link_hash_symbol_type \ - _bfd_generic_copy_link_hash_symbol_type -#define vms_bfd_is_group_section bfd_generic_is_group_section -#define vms_bfd_group_name bfd_generic_group_name -#define vms_bfd_discard_group bfd_generic_discard_group -#define vms_section_already_linked _bfd_generic_section_already_linked -#define vms_bfd_define_common_symbol bfd_generic_define_common_symbol -#define vms_bfd_link_hide_symbol _bfd_generic_link_hide_symbol -#define vms_bfd_define_start_stop bfd_generic_define_start_stop -#define vms_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data - #define vms_bfd_copy_private_bfd_data _bfd_generic_bfd_copy_private_bfd_data -#define vms_bfd_free_cached_info _bfd_generic_bfd_free_cached_info +#define vms_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data #define vms_bfd_copy_private_section_data _bfd_generic_bfd_copy_private_section_data #define vms_bfd_copy_private_symbol_data _bfd_generic_bfd_copy_private_symbol_data +#define vms_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data #define vms_bfd_set_private_flags _bfd_generic_bfd_set_private_flags -#define vms_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data /* Symbols table. */ #define alpha_vms_make_empty_symbol _bfd_generic_make_empty_symbol @@ -10144,7 +10131,7 @@ bfd_vms_get_data (bfd *abfd) /* Generic table. */ #define alpha_vms_close_and_cleanup vms_close_and_cleanup -#define alpha_vms_bfd_free_cached_info vms_bfd_free_cached_info +#define alpha_vms_bfd_free_cached_info _bfd_bool_bfd_true #define alpha_vms_new_section_hook vms_new_section_hook #define alpha_vms_set_section_contents _bfd_vms_set_section_contents #define alpha_vms_get_section_contents_in_window _bfd_generic_get_section_contents_in_window