aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog20
-rw-r--r--bfd/elf.c2
-rw-r--r--bfd/elf32-arm.c17
-rw-r--r--bfd/elfxx-target.h4
-rw-r--r--bfd/libbfd-in.h2
-rw-r--r--bfd/opncls.c28
6 files changed, 68 insertions, 5 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index c5baeb6..c134282 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,23 @@
+2006-04-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/2467
+ * elf.c (_bfd_elf_close_and_cleanup): Check elf_tdata (abfd)
+ is NULL first.
+
+ * elf32-arm.c (elf32_arm_close_and_cleanup): Check if
+ abfd->sections is NULL.
+ (elf32_arm_bfd_free_cached_info): New.
+ (bfd_elf32_bfd_free_cached_info): Defined.
+
+ * elfxx-target.h (bfd_elfNN_bfd_free_cached_info): Default it
+ to _bfd_free_cached_info.
+
+ * libbfd-in.h (_bfd_free_cached_info): New.
+ * libbfd: Regenerated.
+
+ * opncls.c (_bfd_delete_bfd): Check if abfd->memory is NULL.
+ (_bfd_free_cached_info): New.
+
2006-04-21 Alan Modra <amodra@bigpond.net.au>
* elf.c (assign_file_positions_except_relocs): Move code setting
diff --git a/bfd/elf.c b/bfd/elf.c
index 30e1efe..04eff22 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -7207,7 +7207,7 @@ _bfd_elf_close_and_cleanup (bfd *abfd)
{
if (bfd_get_format (abfd) == bfd_object)
{
- if (elf_shstrtab (abfd) != NULL)
+ if (elf_tdata (abfd) != NULL && elf_shstrtab (abfd) != NULL)
_bfd_elf_strtab_free (elf_shstrtab (abfd));
_bfd_dwarf2_cleanup_debug_info (abfd);
}
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index ca33121..bd3c4e3 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -7936,11 +7936,25 @@ unrecord_section_via_map_over_sections (bfd * abfd ATTRIBUTE_UNUSED,
static bfd_boolean
elf32_arm_close_and_cleanup (bfd * abfd)
{
- bfd_map_over_sections (abfd, unrecord_section_via_map_over_sections, NULL);
+ if (abfd->sections)
+ bfd_map_over_sections (abfd,
+ unrecord_section_via_map_over_sections,
+ NULL);
return _bfd_elf_close_and_cleanup (abfd);
}
+static bfd_boolean
+elf32_arm_bfd_free_cached_info (bfd * abfd)
+{
+ if (abfd->sections)
+ bfd_map_over_sections (abfd,
+ unrecord_section_via_map_over_sections,
+ NULL);
+
+ return _bfd_free_cached_info (abfd);
+}
+
/* Display STT_ARM_TFUNC symbols as functions. */
static void
@@ -8100,6 +8114,7 @@ const struct elf_size_info elf32_arm_size_info = {
#define bfd_elf32_new_section_hook elf32_arm_new_section_hook
#define bfd_elf32_bfd_is_target_special_symbol elf32_arm_is_target_special_symbol
#define bfd_elf32_close_and_cleanup elf32_arm_close_and_cleanup
+#define bfd_elf32_bfd_free_cached_info elf32_arm_bfd_free_cached_info
#define bfd_elf32_bfd_final_link elf32_arm_bfd_final_link
#define elf_backend_get_symbol_type elf32_arm_get_symbol_type
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
index 503726d..14a693a 100644
--- a/bfd/elfxx-target.h
+++ b/bfd/elfxx-target.h
@@ -29,7 +29,9 @@
#ifndef bfd_elfNN_close_and_cleanup
#define bfd_elfNN_close_and_cleanup _bfd_elf_close_and_cleanup
#endif
-#define bfd_elfNN_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
+#ifndef bfd_elfNN_bfd_free_cached_info
+#define bfd_elfNN_bfd_free_cached_info _bfd_free_cached_info
+#endif
#ifndef bfd_elfNN_get_section_contents
#define bfd_elfNN_get_section_contents _bfd_generic_get_section_contents
#endif
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index ee2484f..2248479 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -155,6 +155,8 @@ bfd * _bfd_new_bfd
(void);
void _bfd_delete_bfd
(bfd *);
+bfd_boolean _bfd_free_cached_info
+ (bfd *);
bfd_boolean bfd_false
(bfd *ignore);
diff --git a/bfd/opncls.c b/bfd/opncls.c
index b02b137..7e62d06 100644
--- a/bfd/opncls.c
+++ b/bfd/opncls.c
@@ -115,11 +115,35 @@ _bfd_new_bfd_contained_in (bfd *obfd)
void
_bfd_delete_bfd (bfd *abfd)
{
- bfd_hash_table_free (&abfd->section_htab);
- objalloc_free ((struct objalloc *) abfd->memory);
+ if (abfd->memory)
+ {
+ bfd_hash_table_free (&abfd->section_htab);
+ objalloc_free ((struct objalloc *) abfd->memory);
+ }
free (abfd);
}
+/* Free objalloc memory. */
+
+bfd_boolean
+_bfd_free_cached_info (bfd *abfd)
+{
+ if (abfd->memory)
+ {
+ bfd_hash_table_free (&abfd->section_htab);
+ objalloc_free ((struct objalloc *) abfd->memory);
+
+ abfd->sections = NULL;
+ abfd->section_last = NULL;
+ abfd->outsymbols = NULL;
+ abfd->tdata.any = NULL;
+ abfd->usrdata = NULL;
+ abfd->memory = NULL;
+ }
+
+ return TRUE;
+}
+
/*
SECTION
Opening and closing BFDs