From: Alan Modra Date: Wed, 21 Dec 2022 11:10:12 +0000 (+1030) Subject: PR29925, Memory leak in find_abstract_instance X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d28fbc7197ba0e021a43f873eff90b05dcdcff6a;p=binutils-gdb.git PR29925, Memory leak in find_abstract_instance The testcase in the PR had a variable with both DW_AT_decl_file and DW_AT_specification, where the DW_AT_specification also specified DW_AT_decl_file. This leads to a memory leak as the file name is malloced and duplicates are not expected. I've also changed find_abstract_instance to not use a temp for "name", because that can result in a change in behaviour from the usual last of duplicate attributes wins. PR 29925 * dwarf2.c (find_abstract_instance): Delete "name" variable. Free *filename_ptr before assigning new file name. (scan_unit_for_symbols): Similarly free func->file and var->file before assigning. --- diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c index 0cd8152ee6e..b608afbc0cf 100644 --- a/bfd/dwarf2.c +++ b/bfd/dwarf2.c @@ -3441,7 +3441,6 @@ find_abstract_instance (struct comp_unit *unit, struct abbrev_info *abbrev; uint64_t die_ref = attr_ptr->u.val; struct attribute attr; - const char *name = NULL; if (recur_count == 100) { @@ -3602,9 +3601,9 @@ find_abstract_instance (struct comp_unit *unit, case DW_AT_name: /* Prefer DW_AT_MIPS_linkage_name or DW_AT_linkage_name over DW_AT_name. */ - if (name == NULL && is_str_form (&attr)) + if (*pname == NULL && is_str_form (&attr)) { - name = attr.u.str; + *pname = attr.u.str; if (mangle_style (unit->lang) == 0) *is_linkage = true; } @@ -3612,7 +3611,7 @@ find_abstract_instance (struct comp_unit *unit, case DW_AT_specification: if (is_int_form (&attr) && !find_abstract_instance (unit, &attr, recur_count + 1, - &name, is_linkage, + pname, is_linkage, filename_ptr, linenumber_ptr)) return false; break; @@ -3622,7 +3621,7 @@ find_abstract_instance (struct comp_unit *unit, non-string forms into these attributes. */ if (is_str_form (&attr)) { - name = attr.u.str; + *pname = attr.u.str; *is_linkage = true; } break; @@ -3630,8 +3629,11 @@ find_abstract_instance (struct comp_unit *unit, if (!comp_unit_maybe_decode_line_info (unit)) return false; if (is_int_form (&attr)) - *filename_ptr = concat_filename (unit->line_table, - attr.u.val); + { + free (*filename_ptr); + *filename_ptr = concat_filename (unit->line_table, + attr.u.val); + } break; case DW_AT_decl_line: if (is_int_form (&attr)) @@ -3643,7 +3645,6 @@ find_abstract_instance (struct comp_unit *unit, } } } - *pname = name; return true; } @@ -4139,8 +4140,11 @@ scan_unit_for_symbols (struct comp_unit *unit) case DW_AT_decl_file: if (is_int_form (&attr)) - func->file = concat_filename (unit->line_table, - attr.u.val); + { + free (func->file); + func->file = concat_filename (unit->line_table, + attr.u.val); + } break; case DW_AT_decl_line: @@ -4182,8 +4186,11 @@ scan_unit_for_symbols (struct comp_unit *unit) case DW_AT_decl_file: if (is_int_form (&attr)) - var->file = concat_filename (unit->line_table, - attr.u.val); + { + free (var->file); + var->file = concat_filename (unit->line_table, + attr.u.val); + } break; case DW_AT_decl_line: