aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2005-05-05 14:25:23 +0000
committerNick Clifton <nickc@redhat.com>2005-05-05 14:25:23 +0000
commit35330cce1aa1c88c8724038fdb8e2ab9b4e45186 (patch)
tree57414b15123592069ad272a6e70821df21fa04f9
parentd8244a4aba2c284db8fc896e3b4c6591c24f11d8 (diff)
downloadfsf-binutils-gdb-35330cce1aa1c88c8724038fdb8e2ab9b4e45186.zip
fsf-binutils-gdb-35330cce1aa1c88c8724038fdb8e2ab9b4e45186.tar.gz
fsf-binutils-gdb-35330cce1aa1c88c8724038fdb8e2ab9b4e45186.tar.bz2
* dwarf2.c (read_abbrevs): If bfd_realloc fails, free currently allocated memory
before returning. (decode_line_info): Likewise. (_bfd_dwarf2_cleanup_debug_info): New function: Frees memory allocated by functions in this file. * elf-bfd.h (_bfd_dwarf2_cleanup_debug_info): Prototype. * elf.c (bfd_elf_close_and_cleanup): Call _bfd_dwarf2_cleanup_debug_info.
-rw-r--r--bfd/ChangeLog11
-rw-r--r--bfd/dwarf2.c111
-rw-r--r--bfd/elf-bfd.h4
-rw-r--r--bfd/elf.c2
4 files changed, 115 insertions, 13 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 87ec00d..4faeff8 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,14 @@
+2005-05-05 John Levon <levon@movementarian.org>
+
+ * dwarf2.c (read_abbrevs): If bfd_realloc fails, free currently
+ allocated memory before returning.
+ (decode_line_info): Likewise.
+ (_bfd_dwarf2_cleanup_debug_info): New function: Frees memory
+ allocated by functions in this file.
+ * elf-bfd.h (_bfd_dwarf2_cleanup_debug_info): Prototype.
+ * elf.c (bfd_elf_close_and_cleanup): Call
+ _bfd_dwarf2_cleanup_debug_info.
+
2005-05-05 Hans-Peter Nilsson <hp@axis.com>
* Makefile.am (INCLUDES): Don't -D_GNU_SOURCE here.
diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
index 8b63084..365758a 100644
--- a/bfd/dwarf2.c
+++ b/bfd/dwarf2.c
@@ -447,11 +447,28 @@ read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash)
{
if ((cur_abbrev->num_attrs % ATTR_ALLOC_CHUNK) == 0)
{
+ struct attr_abbrev *tmp;
+
amt = cur_abbrev->num_attrs + ATTR_ALLOC_CHUNK;
amt *= sizeof (struct attr_abbrev);
- cur_abbrev->attrs = bfd_realloc (cur_abbrev->attrs, amt);
- if (! cur_abbrev->attrs)
- return 0;
+ tmp = bfd_realloc (cur_abbrev->attrs, amt);
+ if (tmp == NULL)
+ {
+ size_t i;
+
+ for (i = 0; i < ABBREV_HASH_SIZE; i++)
+ {
+ struct abbrev_info *abbrev = abbrevs[i];
+
+ while (abbrev)
+ {
+ free (abbrev->attrs);
+ abbrev = abbrev->next;
+ }
+ }
+ return NULL;
+ }
+ cur_abbrev->attrs = tmp;
}
cur_abbrev->attrs[cur_abbrev->num_attrs].name
@@ -963,11 +980,18 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
if ((table->num_dirs % DIR_ALLOC_CHUNK) == 0)
{
+ char **tmp;
+
amt = table->num_dirs + DIR_ALLOC_CHUNK;
amt *= sizeof (char *);
- table->dirs = bfd_realloc (table->dirs, amt);
- if (! table->dirs)
- return 0;
+
+ tmp = bfd_realloc (table->dirs, amt);
+ if (tmp == NULL)
+ {
+ free (table->dirs);
+ return NULL;
+ }
+ table->dirs = tmp;
}
table->dirs[table->num_dirs++] = cur_dir;
@@ -982,11 +1006,19 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
if ((table->num_files % FILE_ALLOC_CHUNK) == 0)
{
+ struct fileinfo *tmp;
+
amt = table->num_files + FILE_ALLOC_CHUNK;
amt *= sizeof (struct fileinfo);
- table->files = bfd_realloc (table->files, amt);
- if (! table->files)
- return 0;
+
+ tmp = bfd_realloc (table->files, amt);
+ if (tmp == NULL)
+ {
+ free (table->files);
+ free (table->dirs);
+ return NULL;
+ }
+ table->files = tmp;
}
table->files[table->num_files].name = cur_file;
@@ -1073,11 +1105,19 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
line_ptr += bytes_read;
if ((table->num_files % FILE_ALLOC_CHUNK) == 0)
{
+ struct fileinfo *tmp;
+
amt = table->num_files + FILE_ALLOC_CHUNK;
amt *= sizeof (struct fileinfo);
- table->files = bfd_realloc (table->files, amt);
- if (! table->files)
- return 0;
+ tmp = bfd_realloc (table->files, amt);
+ if (tmp == NULL)
+ {
+ free (table->files);
+ free (table->dirs);
+ free (filename);
+ return NULL;
+ }
+ table->files = tmp;
}
table->files[table->num_files].name = cur_file;
table->files[table->num_files].dir =
@@ -1094,7 +1134,10 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
default:
(*_bfd_error_handler) (_("Dwarf Error: mangled line number section."));
bfd_set_error (bfd_error_bad_value);
- return 0;
+ free (filename);
+ free (table->files);
+ free (table->dirs);
+ return NULL;
}
break;
case DW_LNS_copy:
@@ -2003,3 +2046,45 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
return FALSE;
}
+
+void
+_bfd_dwarf2_cleanup_debug_info (bfd *abfd)
+{
+ struct comp_unit *each;
+ struct dwarf2_debug *stash;
+
+ if (abfd == NULL || elf_tdata (abfd) == NULL)
+ return;
+
+ stash = elf_tdata (abfd)->dwarf2_find_line_info;
+
+ if (stash == NULL)
+ return;
+
+ for (each = stash->all_comp_units; each; each = each->next_unit)
+ {
+ struct abbrev_info **abbrevs = each->abbrevs;
+ size_t i;
+
+ for (i = 0; i < ABBREV_HASH_SIZE; i++)
+ {
+ struct abbrev_info *abbrev = abbrevs[i];
+
+ while (abbrev)
+ {
+ free (abbrev->attrs);
+ abbrev = abbrev->next;
+ }
+ }
+
+ if (each->line_table)
+ {
+ free (each->line_table->dirs);
+ free (each->line_table->files);
+ }
+ }
+
+ free (stash->dwarf_abbrev_buffer);
+ free (stash->dwarf_line_buffer);
+ free (stash->dwarf_ranges_buffer);
+}
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index d5814c1..6033951 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1728,6 +1728,10 @@ extern int bfd_elf_link_record_local_dynamic_symbol
extern bfd_boolean _bfd_elf_close_and_cleanup
(bfd *);
+
+extern void _bfd_dwarf2_cleanup_debug_info
+ (bfd *);
+
extern bfd_reloc_status_type _bfd_elf_rel_vtable_reloc_fn
(bfd *, arelent *, struct bfd_symbol *, void *,
asection *, bfd *, char **);
diff --git a/bfd/elf.c b/bfd/elf.c
index c2e8438..5477ba6 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -6684,6 +6684,8 @@ _bfd_elf_close_and_cleanup (bfd *abfd)
_bfd_elf_strtab_free (elf_shstrtab (abfd));
}
+ _bfd_dwarf2_cleanup_debug_info (abfd);
+
return _bfd_generic_close_and_cleanup (abfd);
}