diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 15 | ||||
-rw-r--r-- | gdb/Makefile.in | 2 | ||||
-rw-r--r-- | gdb/defs.h | 4 | ||||
-rw-r--r-- | gdb/symfile.c | 36 | ||||
-rw-r--r-- | gdb/symfile.h | 5 | ||||
-rw-r--r-- | gdb/utils.c | 14 |
6 files changed, 68 insertions, 8 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 494347b..739de21 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,18 @@ +2004-09-08 Jim Blandy <jimb@redhat.com> + + Fix bug reported and analyzed by Olivier Crete: + * symfile.c (copy_section_addr_info): New function. + (symbol_file_add_with_addrs_or_offsets): Use it to save the + original set of address arguments, instead of handwritten code + that uses one length to allocate and a different length to + initialize. Use make_cleanup_free_section_addr_info. + * symfile.h (copy_section_addr_info): New declaration. + * utils.c: #include "symfile.h". + (do_free_section_addr_info, make_cleanup_free_section_addr_info): + New functions. + * defs.h (make_cleanup_free_section_addr_info): New declaration. + * Makefile.in (utils.o): Update dependencies. + 2004-09-08 Andrew Cagney <cagney@gnu.org> * thread-db.c (keep_thread_db): Delete. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 2a464e9..dc20b17 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -2611,7 +2611,7 @@ user-regs.o: user-regs.c $(defs_h) $(user_regs_h) $(gdbtypes_h) \ utils.o: utils.c $(defs_h) $(gdb_assert_h) $(gdb_string_h) $(event_top_h) \ $(tui_h) $(gdbcmd_h) $(serial_h) $(bfd_h) $(target_h) $(demangle_h) \ $(expression_h) $(language_h) $(charset_h) $(annotate_h) \ - $(filenames_h) $(inferior_h) $(readline_h) + $(filenames_h) $(inferior_h) $(readline_h) $(symfile_h) uw-thread.o: uw-thread.c $(defs_h) $(gdbthread_h) $(target_h) $(inferior_h) \ $(regcache_h) $(gregset_h) v850ice.o: v850ice.c $(defs_h) $(gdb_string_h) $(frame_h) $(symtab_h) \ @@ -360,6 +360,10 @@ extern struct cleanup *make_cleanup_freeargv (char **); struct ui_file; extern struct cleanup *make_cleanup_ui_file_delete (struct ui_file *); +struct section_addr_info; +extern struct cleanup *(make_cleanup_free_section_addr_info + (struct section_addr_info *)); + extern struct cleanup *make_cleanup_close (int fd); extern struct cleanup *make_cleanup_bfd_close (bfd *abfd); diff --git a/gdb/symfile.c b/gdb/symfile.c index d0ec083..59fc378 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -324,6 +324,32 @@ alloc_section_addr_info (size_t num_sections) return sap; } + +/* Return a freshly allocated copy of ADDRS. The section names, if + any, are also freshly allocated copies of those in ADDRS. */ +struct section_addr_info * +copy_section_addr_info (struct section_addr_info *addrs) +{ + struct section_addr_info *copy + = alloc_section_addr_info (addrs->num_sections); + int i; + + copy->num_sections = addrs->num_sections; + for (i = 0; i < addrs->num_sections; i++) + { + copy->other[i].addr = addrs->other[i].addr; + if (addrs->other[i].name) + copy->other[i].name = xstrdup (addrs->other[i].name); + else + copy->other[i].name = NULL; + copy->other[i].sectindex = addrs->other[i].sectindex; + } + + return copy; +} + + + /* Build (allocate and populate) a section_addr_info struct from an existing section table. */ @@ -772,7 +798,7 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty, struct objfile *objfile; struct partial_symtab *psymtab; char *debugfile; - struct section_addr_info *orig_addrs; + struct section_addr_info *orig_addrs = NULL; struct cleanup *my_cleanups; const char *name = bfd_get_filename (abfd); @@ -790,14 +816,10 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty, objfile = allocate_objfile (abfd, flags); discard_cleanups (my_cleanups); - orig_addrs = alloc_section_addr_info (bfd_count_sections (abfd)); - my_cleanups = make_cleanup (xfree, orig_addrs); if (addrs) { - int i; - orig_addrs->num_sections = addrs->num_sections; - for (i = 0; i < addrs->num_sections; i++) - orig_addrs->other[i] = addrs->other[i]; + orig_addrs = copy_section_addr_info (addrs); + make_cleanup_free_section_addr_info (orig_addrs); } /* We either created a new mapped symbol table, mapped an existing diff --git a/gdb/symfile.h b/gdb/symfile.h index b76d3ba..0fa9c46 100644 --- a/gdb/symfile.h +++ b/gdb/symfile.h @@ -198,6 +198,11 @@ extern struct objfile *symbol_file_add_from_bfd (bfd *, int, extern struct section_addr_info *alloc_section_addr_info (size_t num_sections); +/* Return a freshly allocated copy of ADDRS. The section names, if + any, are also freshly allocated copies of those in ADDRS. */ +extern struct section_addr_info *(copy_section_addr_info + (struct section_addr_info *addrs)); + /* Build (allocate and populate) a section_addr_info struct from an existing section table. */ diff --git a/gdb/utils.c b/gdb/utils.c index e350c25..10c40c7 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -51,6 +51,7 @@ #include "charset.h" #include "annotate.h" #include "filenames.h" +#include "symfile.h" #include "inferior.h" /* for signed_pointer_to_address */ @@ -260,6 +261,19 @@ make_cleanup_ui_file_delete (struct ui_file *arg) return make_my_cleanup (&cleanup_chain, do_ui_file_delete, arg); } +static void +do_free_section_addr_info (void *arg) +{ + free_section_addr_info (arg); +} + +struct cleanup * +make_cleanup_free_section_addr_info (struct section_addr_info *addrs) +{ + return make_my_cleanup (&cleanup_chain, do_free_section_addr_info, addrs); +} + + struct cleanup * make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function, void *arg) |