aboutsummaryrefslogtreecommitdiff
path: root/bfd/dwarf2.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2008-02-20 15:56:33 +0000
committerNick Clifton <nickc@redhat.com>2008-02-20 15:56:33 +0000
commitb42bf1e0f9756b758ad5b081a2d007c4a71eed39 (patch)
treef73b39612d83cda987737dc95ecbc0d8c45fb217 /bfd/dwarf2.c
parent07ea644b36ccd4072072cb90174d08969862040f (diff)
downloadgdb-b42bf1e0f9756b758ad5b081a2d007c4a71eed39.zip
gdb-b42bf1e0f9756b758ad5b081a2d007c4a71eed39.tar.gz
gdb-b42bf1e0f9756b758ad5b081a2d007c4a71eed39.tar.bz2
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.
Diffstat (limited to 'bfd/dwarf2.c')
-rw-r--r--bfd/dwarf2.c96
1 files changed, 81 insertions, 15 deletions
diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
index d0b50ff..7ad218e 100644
--- a/bfd/dwarf2.c
+++ b/bfd/dwarf2.c
@@ -656,10 +656,16 @@ read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash)
while (abbrev)
{
- free (abbrev->attrs);
- abbrev = abbrev->next;
+ struct abbrev_info * a = abbrev;
+
+ abbrev = a->next;
+ if (a->attrs)
+ free (abbrev->attrs);
+ free (a);
}
}
+
+ free (abbrevs);
return NULL;
}
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;
}
-/* 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)
{
bfd *abfd = unit->abfd;
@@ -1274,6 +1282,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
{
free (table->files);
free (table->dirs);
+ free (table);
return NULL;
}
table->files = tmp;
@@ -1370,6 +1379,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
{
free (table->files);
free (table->dirs);
+ free (table);
free (filename);
return NULL;
}
@@ -1393,6 +1403,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
free (filename);
free (table->files);
free (table->dirs);
+ free (table);
return NULL;
}
break;
@@ -1814,7 +1825,10 @@ read_rangelist (struct comp_unit *unit, struct arange *arange, bfd_uint64_t offs
/* DWARF2 Compilation unit functions. */
/* 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
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 *));
if (nested_funcs == NULL)
return FALSE;
- nested_funcs[nesting_level] = 0;
+ nested_funcs[nesting_level] = NULL;
while (nesting_level)
{
@@ -1868,6 +1882,7 @@ scan_unit_for_symbols (struct comp_unit *unit)
|| abbrev->tag == DW_TAG_inlined_subroutine)
{
bfd_size_type amt = sizeof (struct funcinfo);
+
func = bfd_zalloc (abfd, amt);
func->tag = abbrev->tag;
func->prev_func = unit->function_table;
@@ -1889,6 +1904,7 @@ scan_unit_for_symbols (struct comp_unit *unit)
if (abbrev->tag == DW_TAG_variable)
{
bfd_size_type amt = sizeof (struct varinfo);
+
var = bfd_zalloc (abfd, amt);
var->tag = abbrev->tag;
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)
{
- struct abbrev_info **abbrevs = each->abbrevs;
- size_t i;
+ struct funcinfo * function_table = each->function_table;
+ 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);
- abbrev = abbrev->next;
+ struct abbrev_info *abbrev = each->abbrevs[i];
+
+ 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)
{
- free (each->line_table->dirs);
- free (each->line_table->files);
+ /* FIXME: We should free the line_info structures as well. */
+ 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);