PR29362, some binutils memory leaks

2022-08-16  Alan Modra  <amodra@gmail.com>
	    Cunlong Li  <shenxiaogll@163.com>

	PR 29362
	* dwarf.c (free_debug_information): New function, extracted..
	(free_debug_memory): ..from here.
	(process_debug_info): Use it when before clearing out unit
	debug_information.  Clear all fields.
	* objcopy.c (delete_symbol_htabs): New function.
	(main): Call it via xatexit.
	(copy_archive): Free "dir".
	* objdump.c (free_debug_section): Free reloc_info.
This commit is contained in:
Alan Modra 2022-08-16 00:16:49 +09:30
parent 105afa7f23
commit 450da4bd38
3 changed files with 43 additions and 28 deletions

View file

@ -3509,6 +3509,21 @@ introduce (struct dwarf_section * section, bool raw)
} }
} }
/* Free memory allocated for one unit in debug_information. */
static void
free_debug_information (debug_info *ent)
{
if (ent->max_loc_offsets)
{
free (ent->loc_offsets);
free (ent->loc_views);
free (ent->have_frame_base);
}
if (ent->max_range_lists)
free (ent->range_lists);
}
/* Process the contents of a .debug_info section. /* Process the contents of a .debug_info section.
If do_loc is TRUE then we are scanning for location lists and dwo tags If do_loc is TRUE then we are scanning for location lists and dwo tags
and we do not want to display anything to the user. and we do not want to display anything to the user.
@ -3805,25 +3820,14 @@ process_debug_info (struct dwarf_section * section,
&& alloc_num_debug_info_entries > unit && alloc_num_debug_info_entries > unit
&& ! do_types) && ! do_types)
{ {
debug_information [unit].cu_offset = cu_offset; free_debug_information (&debug_information[unit]);
debug_information [unit].pointer_size memset (&debug_information[unit], 0, sizeof (*debug_information));
= compunit.cu_pointer_size; debug_information[unit].pointer_size = compunit.cu_pointer_size;
debug_information [unit].offset_size = offset_size; debug_information[unit].offset_size = offset_size;
debug_information [unit].dwarf_version = compunit.cu_version; debug_information[unit].dwarf_version = compunit.cu_version;
debug_information [unit].base_address = 0; debug_information[unit].cu_offset = cu_offset;
debug_information [unit].addr_base = DEBUG_INFO_UNAVAILABLE; debug_information[unit].addr_base = DEBUG_INFO_UNAVAILABLE;
debug_information [unit].ranges_base = DEBUG_INFO_UNAVAILABLE; debug_information[unit].ranges_base = DEBUG_INFO_UNAVAILABLE;
debug_information [unit].rnglists_base = 0;
debug_information [unit].loc_offsets = NULL;
debug_information [unit].have_frame_base = NULL;
debug_information [unit].max_loc_offsets = 0;
debug_information [unit].num_loc_offsets = 0;
debug_information [unit].loclists_base = 0;
debug_information [unit].range_lists = NULL;
debug_information [unit].max_range_lists= 0;
debug_information [unit].num_range_lists = 0;
debug_information [unit].rnglists_base = 0;
debug_information [unit].str_offsets_base = 0;
} }
if (!do_loc && dwarf_start_die == 0) if (!do_loc && dwarf_start_die == 0)
@ -12021,15 +12025,7 @@ free_debug_memory (void)
if (debug_information != NULL) if (debug_information != NULL)
{ {
for (i = 0; i < alloc_num_debug_info_entries; i++) for (i = 0; i < alloc_num_debug_info_entries; i++)
{ free_debug_information (&debug_information[i]);
if (debug_information [i].max_loc_offsets)
{
free (debug_information [i].loc_offsets);
free (debug_information [i].have_frame_base);
}
if (debug_information [i].max_range_lists)
free (debug_information [i].range_lists);
}
free (debug_information); free (debug_information);
debug_information = NULL; debug_information = NULL;
alloc_num_debug_info_entries = num_debug_info_entries = 0; alloc_num_debug_info_entries = num_debug_info_entries = 0;

View file

@ -1048,6 +1048,20 @@ create_symbol_htabs (void)
redefine_specific_reverse_htab = create_symbol_htab (); redefine_specific_reverse_htab = create_symbol_htab ();
} }
static void
delete_symbol_htabs (void)
{
htab_delete (strip_specific_htab);
htab_delete (strip_unneeded_htab);
htab_delete (keep_specific_htab);
htab_delete (localize_specific_htab);
htab_delete (globalize_specific_htab);
htab_delete (keepglobal_specific_htab);
htab_delete (weaken_specific_htab);
htab_delete (redefine_specific_htab);
htab_delete (redefine_specific_reverse_htab);
}
/* Add a symbol to strip_specific_list. */ /* Add a symbol to strip_specific_list. */
static void static void
@ -3736,6 +3750,7 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
} }
rmdir (dir); rmdir (dir);
free (dir);
} }
static void static void
@ -6016,6 +6031,7 @@ main (int argc, char *argv[])
} }
create_symbol_htabs (); create_symbol_htabs ();
xatexit (delete_symbol_htabs);
if (argv != NULL) if (argv != NULL)
bfd_set_error_program_name (argv[0]); bfd_set_error_program_name (argv[0]);

View file

@ -4108,6 +4108,9 @@ free_debug_section (enum dwarf_section_display_enum debug)
section->start = NULL; section->start = NULL;
section->address = 0; section->address = 0;
section->size = 0; section->size = 0;
free ((char*) section->reloc_info);
section->reloc_info = NULL;
section->num_relocs= 0;
} }
void void