* dwarf2.c (read_abbrevs): Free the abbreviation table if we run
   out of memory.
   (decode_line_info): Free the line_info_table before returning a
   failure result.
   (_bfd_dwarf2_cleanup_debug_info): Free the abbreviation table.
   Free the line table.  Free the function table.  Free the variable
   table.
This commit is contained in:
Nick Clifton
2008-02-20 15:56:33 +00:00
parent 07ea644b36
commit b42bf1e0f9
2 changed files with 93 additions and 15 deletions

View File

@ -1,3 +1,15 @@
2008-02-20 Diogo de Carvalho Kraemer <diogo@kraemer.eng.br>
Nick Clifton <nickc@redhat.com>
PR 868
* dwarf2.c (read_abbrevs): Free the abbreviation table if we run
out of memory.
(decode_line_info): Free the line_info_table before returning a
failure result.
(_bfd_dwarf2_cleanup_debug_info): Free the abbreviation table.
Free the line table. Free the function table. Free the variable
table.
2008-02-17 Mark Kettenis <kettenis@gnu.org> 2008-02-17 Mark Kettenis <kettenis@gnu.org>
* elf.c (swap_out_syms): Avoid preprocessing directive within * elf.c (swap_out_syms): Avoid preprocessing directive within

View File

@ -656,10 +656,16 @@ read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash)
while (abbrev) while (abbrev)
{ {
free (abbrev->attrs); struct abbrev_info * a = abbrev;
abbrev = abbrev->next;
abbrev = a->next;
if (a->attrs)
free (abbrev->attrs);
free (a);
} }
} }
free (abbrevs);
return NULL; return NULL;
} }
cur_abbrev->attrs = tmp; cur_abbrev->attrs = tmp;
@ -1123,9 +1129,11 @@ arange_add (bfd *abfd, struct arange *first_arange, bfd_vma low_pc, bfd_vma high
first_arange->next = arange; first_arange->next = arange;
} }
/* Decode the line number information for UNIT. */ /* Decode the line number information for UNIT.
Note: this function allocates memory. It is the caller's
responsibility to free it. */
static struct line_info_table* static struct line_info_table *
decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash) decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
{ {
bfd *abfd = unit->abfd; bfd *abfd = unit->abfd;
@ -1274,6 +1282,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
{ {
free (table->files); free (table->files);
free (table->dirs); free (table->dirs);
free (table);
return NULL; return NULL;
} }
table->files = tmp; table->files = tmp;
@ -1370,6 +1379,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
{ {
free (table->files); free (table->files);
free (table->dirs); free (table->dirs);
free (table);
free (filename); free (filename);
return NULL; return NULL;
} }
@ -1393,6 +1403,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
free (filename); free (filename);
free (table->files); free (table->files);
free (table->dirs); free (table->dirs);
free (table);
return NULL; return NULL;
} }
break; break;
@ -1814,7 +1825,10 @@ read_rangelist (struct comp_unit *unit, struct arange *arange, bfd_uint64_t offs
/* DWARF2 Compilation unit functions. */ /* DWARF2 Compilation unit functions. */
/* Scan over each die in a comp. unit looking for functions to add /* Scan over each die in a comp. unit looking for functions to add
to the function table and variables to the variable table. */ to the function table and variables to the variable table.
Returns TRUE upon success, FALSE otherwise. Allocates memory
blocks to the unit->function_table and unit->variable_table fields.
It is the caller's responsibility to free this memory. */
static bfd_boolean static bfd_boolean
scan_unit_for_symbols (struct comp_unit *unit) scan_unit_for_symbols (struct comp_unit *unit)
@ -1831,7 +1845,7 @@ scan_unit_for_symbols (struct comp_unit *unit)
nested_funcs = bfd_malloc (nested_funcs_size * sizeof (struct funcinfo *)); nested_funcs = bfd_malloc (nested_funcs_size * sizeof (struct funcinfo *));
if (nested_funcs == NULL) if (nested_funcs == NULL)
return FALSE; return FALSE;
nested_funcs[nesting_level] = 0; nested_funcs[nesting_level] = NULL;
while (nesting_level) while (nesting_level)
{ {
@ -1868,6 +1882,7 @@ scan_unit_for_symbols (struct comp_unit *unit)
|| abbrev->tag == DW_TAG_inlined_subroutine) || abbrev->tag == DW_TAG_inlined_subroutine)
{ {
bfd_size_type amt = sizeof (struct funcinfo); bfd_size_type amt = sizeof (struct funcinfo);
func = bfd_zalloc (abfd, amt); func = bfd_zalloc (abfd, amt);
func->tag = abbrev->tag; func->tag = abbrev->tag;
func->prev_func = unit->function_table; func->prev_func = unit->function_table;
@ -1889,6 +1904,7 @@ scan_unit_for_symbols (struct comp_unit *unit)
if (abbrev->tag == DW_TAG_variable) if (abbrev->tag == DW_TAG_variable)
{ {
bfd_size_type amt = sizeof (struct varinfo); bfd_size_type amt = sizeof (struct varinfo);
var = bfd_zalloc (abfd, amt); var = bfd_zalloc (abfd, amt);
var->tag = abbrev->tag; var->tag = abbrev->tag;
var->stack = 1; var->stack = 1;
@ -3201,25 +3217,75 @@ _bfd_dwarf2_cleanup_debug_info (bfd *abfd)
for (each = stash->all_comp_units; each; each = each->next_unit) for (each = stash->all_comp_units; each; each = each->next_unit)
{ {
struct abbrev_info **abbrevs = each->abbrevs; struct funcinfo * function_table = each->function_table;
size_t i; struct varinfo * variable_table = each->variable_table;
for (i = 0; i < ABBREV_HASH_SIZE; i++) if (each->abbrevs != NULL)
{ {
struct abbrev_info *abbrev = abbrevs[i]; size_t i;
while (abbrev) for (i = 0; i < ABBREV_HASH_SIZE; i++)
{ {
free (abbrev->attrs); struct abbrev_info *abbrev = each->abbrevs[i];
abbrev = abbrev->next;
while (abbrev)
{
struct abbrev_info * a = abbrev;
abbrev = a->next;
if (a->attrs)
free (a->attrs);
free (a);
}
} }
free (each->abbrevs);
each->abbrevs = NULL;
} }
if (each->line_table) if (each->line_table)
{ {
free (each->line_table->dirs); /* FIXME: We should free the line_info structures as well. */
free (each->line_table->files); if (each->line_table->dirs)
free (each->line_table->dirs);
if (each->line_table->files)
free (each->line_table->files);
free (each->line_table);
each->line_table = NULL;
} }
while (function_table)
{
struct funcinfo * f = function_table;
function_table = f->prev_func;
if (f->file)
free (f->file);
if (f->caller_file)
free (f->caller_file);
free (f);
}
each->function_table = NULL;
while (variable_table)
{
struct varinfo * v = variable_table;
variable_table = variable_table->prev_var;
if (v->file)
free (v->file);
free (v);
}
each->variable_table = NULL;
} }
free (stash->dwarf_abbrev_buffer); free (stash->dwarf_abbrev_buffer);