Fix bug reported and analyzed by Olivier Crete:
authorJim Blandy <jimb@codesourcery.com>
Wed, 8 Sep 2004 21:58:19 +0000 (21:58 +0000)
committerJim Blandy <jimb@codesourcery.com>
Wed, 8 Sep 2004 21:58:19 +0000 (21:58 +0000)
* 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.

gdb/ChangeLog
gdb/Makefile.in
gdb/defs.h
gdb/symfile.c
gdb/symfile.h
gdb/utils.c

index 494347b..739de21 100644 (file)
@@ -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.
index 2a464e9..dc20b17 100644 (file)
@@ -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) \
index 45bc805..1be691d 100644 (file)
@@ -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);
index d0ec083..59fc378 100644 (file)
@@ -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
index b76d3ba..0fa9c46 100644 (file)
@@ -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.  */
 
index e350c25..10c40c7 100644 (file)
@@ -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)