2002-01-15 Michael Snyder <msnyder@redhat.com>
authorMichael Snyder <msnyder@vmware.com>
Tue, 15 Jan 2002 20:00:56 +0000 (20:00 +0000)
committerMichael Snyder <msnyder@vmware.com>
Tue, 15 Jan 2002 20:00:56 +0000 (20:00 +0000)
* symfile.c (generic_load): Use bfd_map_over_sections method
instead of manipulating bfd structure members directly.
(add_section_size_callback): New function, bfd sections callback
        used by generic_load.
(load_sections_callback): New function, bfd sections callback
        used by generic_load.

gdb/ChangeLog
gdb/symfile.c

index 6d05ed1b23d33243962d012db613ff39986f7ef6..a36e31533b2bdfb82663adbaeeba5cb8a21ec6f4 100644 (file)
@@ -1,3 +1,12 @@
+2002-01-15  Michael Snyder  <msnyder@redhat.com>
+
+       * symfile.c (generic_load): Use bfd_map_over_sections method
+       instead of manipulating bfd structure members directly.
+       (add_section_size_callback): New function, bfd sections callback
+       used by generic_load.
+       (load_sections_callback): New function, bfd sections callback
+       used by generic_load.
+
 2002-01-15  Elena Zannoni  <ezannoni@redhat.com>
 
        [Based on work by Jim Blandy] 
index 461b800d1d8d2f9016073ca1734c0694c62248b4..7043b8023d41bb13cb7366f2cbf08db014c11e1a 100644 (file)
@@ -1174,19 +1174,139 @@ load_command (char *arg, int from_tty)
 static int download_write_size = 512;
 static int validate_download = 0;
 
+/* Callback service function for generic_load (bfd_map_over_sections).  */
+
+static void
+add_section_size_callback (bfd *abfd, asection *asec, void *data)
+{
+  bfd_size_type *sum = data;
+
+  *sum += bfd_get_section_size_before_reloc (asec);
+}
+
+/* Opaque data for load_section_callback.  */
+struct load_section_data {
+  unsigned long load_offset;
+  unsigned long write_count;
+  unsigned long data_count;
+  bfd_size_type total_size;
+};
+
+/* Callback service function for generic_load (bfd_map_over_sections).  */
+
+static void
+load_section_callback (bfd *abfd, asection *asec, void *data)
+{
+  struct load_section_data *args = data;
+
+  if (bfd_get_section_flags (abfd, asec) & SEC_LOAD)
+    {
+      bfd_size_type size = bfd_get_section_size_before_reloc (asec);
+      if (size > 0)
+       {
+         char *buffer;
+         struct cleanup *old_chain;
+         CORE_ADDR lma = bfd_section_lma (abfd, asec) + args->load_offset;
+         bfd_size_type block_size;
+         int err;
+         const char *sect_name = bfd_get_section_name (abfd, asec);
+         bfd_size_type sent;
+
+         if (download_write_size > 0 && size > download_write_size)
+           block_size = download_write_size;
+         else
+           block_size = size;
+
+         buffer = xmalloc (size);
+         old_chain = make_cleanup (xfree, buffer);
+
+         /* Is this really necessary?  I guess it gives the user something
+            to look at during a long download.  */
+#ifdef UI_OUT
+         ui_out_message (uiout, 0, "Loading section %s, size 0x%s lma 0x%s\n",
+                         sect_name, paddr_nz (size), paddr_nz (lma));
+#else
+         fprintf_unfiltered (gdb_stdout,
+                             "Loading section %s, size 0x%s lma 0x%s\n",
+                             sect_name, paddr_nz (size), paddr_nz (lma));
+#endif
+
+         bfd_get_section_contents (abfd, asec, buffer, 0, size);
+
+         sent = 0;
+         do
+           {
+             int len;
+             bfd_size_type this_transfer = size - sent;
+
+             if (this_transfer >= block_size)
+               this_transfer = block_size;
+             len = target_write_memory_partial (lma, buffer,
+                                                this_transfer, &err);
+             if (err)
+               break;
+             if (validate_download)
+               {
+                 /* Broken memories and broken monitors manifest
+                    themselves here when bring new computers to
+                    life.  This doubles already slow downloads.  */
+                 /* NOTE: cagney/1999-10-18: A more efficient
+                    implementation might add a verify_memory()
+                    method to the target vector and then use
+                    that.  remote.c could implement that method
+                    using the ``qCRC'' packet.  */
+                 char *check = xmalloc (len);
+                 struct cleanup *verify_cleanups = 
+                   make_cleanup (xfree, check);
+
+                 if (target_read_memory (lma, check, len) != 0)
+                   error ("Download verify read failed at 0x%s",
+                          paddr (lma));
+                 if (memcmp (buffer, check, len) != 0)
+                   error ("Download verify compare failed at 0x%s",
+                          paddr (lma));
+                 do_cleanups (verify_cleanups);
+               }
+             args->data_count += len;
+             lma += len;
+             buffer += len;
+             args->write_count += 1;
+             sent += len;
+             if (quit_flag
+                 || (ui_load_progress_hook != NULL
+                     && ui_load_progress_hook (sect_name, sent)))
+               error ("Canceled the download");
+
+             if (show_load_progress != NULL)
+               show_load_progress (sect_name, sent, size, 
+                                   args->data_count, args->total_size);
+           }
+         while (sent < size);
+
+         if (err != 0)
+           error ("Memory access error while loading section %s.", sect_name);
+
+         do_cleanups (old_chain);
+       }
+    }
+}
+
 void
 generic_load (char *args, int from_tty)
 {
   asection *s;
   bfd *loadfile_bfd;
   time_t start_time, end_time; /* Start and end times of download */
-  unsigned long data_count = 0;        /* Number of bytes transferred to memory */
-  unsigned long write_count = 0;       /* Number of writes needed. */
-  unsigned long load_offset;   /* offset to add to vma for each section */
   char *filename;
   struct cleanup *old_cleanups;
   char *offptr;
-  bfd_size_type total_size = 0;
+  struct load_section_data cbdata;
+  CORE_ADDR entry;
+
+  cbdata.load_offset = 0;      /* Offset to add to vma for each section. */
+  cbdata.write_count = 0;      /* Number of writes needed. */
+  cbdata.data_count = 0;       /* Number of bytes written to target memory. */
+  cbdata.total_size = 0;       /* Total size of all bfd sectors. */
 
   /* Parse the input argument - the user can specify a load offset as
      a second argument. */
@@ -1198,13 +1318,13 @@ generic_load (char *args, int from_tty)
     {
       char *endptr;
 
-      load_offset = strtoul (offptr, &endptr, 0);
+      cbdata.load_offset = strtoul (offptr, &endptr, 0);
       if (offptr == endptr)
        error ("Invalid download offset:%s\n", offptr);
       *offptr = '\0';
     }
   else
-    load_offset = 0;
+    cbdata.load_offset = 0;
 
   /* Open the file for loading. */
   loadfile_bfd = bfd_openr (filename, gnutarget);
@@ -1225,129 +1345,30 @@ generic_load (char *args, int from_tty)
             bfd_errmsg (bfd_get_error ()));
     }
 
-  for (s = loadfile_bfd->sections; s; s = s->next)
-    if (bfd_get_section_flags (loadfile_bfd, s) & SEC_LOAD)
-      total_size += bfd_get_section_size_before_reloc (s);
+  bfd_map_over_sections (loadfile_bfd, add_section_size_callback, 
+                        (void *) &cbdata.total_size);
 
   start_time = time (NULL);
 
-  for (s = loadfile_bfd->sections; s; s = s->next)
-    {
-      if (s->flags & SEC_LOAD)
-       {
-         bfd_size_type size = bfd_get_section_size_before_reloc (s);
-
-         if (size > 0)
-           {
-             char *buffer;
-             struct cleanup *old_chain;
-             CORE_ADDR lma = bfd_section_lma (loadfile_bfd, s) + load_offset;
-             bfd_size_type block_size;
-             int err;
-             const char *sect_name = bfd_get_section_name (loadfile_bfd, s);
-             bfd_size_type sent;
-
-             if (download_write_size > 0 && size > download_write_size)
-               block_size = download_write_size;
-             else
-               block_size = size;
-
-             buffer = xmalloc (size);
-             old_chain = make_cleanup (xfree, buffer);
-
-             /* Is this really necessary?  I guess it gives the user something
-                to look at during a long download.  */
-#ifdef UI_OUT
-             ui_out_message (uiout, 0, 
-                             "Loading section %s, size 0x%s lma 0x%s\n",
-                             sect_name, paddr_nz (size), paddr_nz (lma));
-#else
-             fprintf_unfiltered (gdb_stdout,
-                                 "Loading section %s, size 0x%s lma 0x%s\n",
-                                 sect_name, paddr_nz (size), paddr_nz (lma));
-#endif
-
-             bfd_get_section_contents (loadfile_bfd, s, buffer, 0, size);
-
-             sent = 0;
-             do
-               {
-                 int len;
-                 bfd_size_type this_transfer = size - sent;
-
-                 if (this_transfer >= block_size)
-                   this_transfer = block_size;
-                 len = target_write_memory_partial (lma, buffer,
-                                                    this_transfer, &err);
-                 if (err)
-                   break;
-                 if (validate_download)
-                   {
-                     /* Broken memories and broken monitors manifest
-                        themselves here when bring new computers to
-                        life.  This doubles already slow downloads.  */
-                     /* NOTE: cagney/1999-10-18: A more efficient
-                         implementation might add a verify_memory()
-                         method to the target vector and then use
-                         that.  remote.c could implement that method
-                         using the ``qCRC'' packet.  */
-                     char *check = xmalloc (len);
-                     struct cleanup *verify_cleanups = make_cleanup (xfree, 
-                                                                     check);
-
-                     if (target_read_memory (lma, check, len) != 0)
-                       error ("Download verify read failed at 0x%s",
-                              paddr (lma));
-                     if (memcmp (buffer, check, len) != 0)
-                       error ("Download verify compare failed at 0x%s",
-                              paddr (lma));
-                     do_cleanups (verify_cleanups);
-                   }
-                 data_count += len;
-                 lma += len;
-                 buffer += len;
-                 write_count += 1;
-                 sent += len;
-                 if (quit_flag
-                     || (ui_load_progress_hook != NULL
-                         && ui_load_progress_hook (sect_name, sent)))
-                   error ("Canceled the download");
-
-                 if (show_load_progress != NULL)
-                   show_load_progress (sect_name, sent, size, 
-                                       data_count, total_size);
-               }
-             while (sent < size);
-
-             if (err != 0)
-               error ("Memory access error while loading section %s.", 
-                      sect_name);
-
-             do_cleanups (old_chain);
-           }
-       }
-    }
+  bfd_map_over_sections (loadfile_bfd, load_section_callback, &cbdata);
 
   end_time = time (NULL);
-  {
-    CORE_ADDR entry = bfd_get_start_address (loadfile_bfd);
 
+  entry = bfd_get_start_address (loadfile_bfd);
 #ifdef UI_OUT
-    ui_out_text (uiout, "Start address ");
-    ui_out_field_fmt (uiout, "address", "0x%s", paddr_nz (entry));
-    ui_out_text (uiout, ", load size ");
-    ui_out_field_fmt (uiout, "load-size", "%lu", data_count);
-    ui_out_text (uiout, "\n");
-
+  ui_out_text (uiout, "Start address ");
+  ui_out_field_fmt (uiout, "address", "0x%s", paddr_nz (entry));
+  ui_out_text (uiout, ", load size ");
+  ui_out_field_fmt (uiout, "load-size", "%lu", cbdata.data_count);
+  ui_out_text (uiout, "\n");
 #else
-    fprintf_unfiltered (gdb_stdout,
-                       "Start address 0x%s, load size %lu\n",
-                       paddr_nz (entry), data_count);
+  fprintf_unfiltered (gdb_stdout,
+                     "Start address 0x%s, load size %lu\n",
+                     paddr_nz (entry), cbdata.data_count);
 #endif
-    /* We were doing this in remote-mips.c, I suspect it is right
-       for other targets too.  */
-    write_pc (entry);
-  }
+  /* We were doing this in remote-mips.c, I suspect it is right
+     for other targets too.  */
+  write_pc (entry);
 
   /* FIXME: are we supposed to call symbol_file_add or not?  According to
      a comment from remote-mips.c (where a call to symbol_file_add was
@@ -1355,8 +1376,8 @@ generic_load (char *args, int from_tty)
      loaded in.  remote-nindy.c had no call to symbol_file_add, but remote-vx.c
      does.  */
 
-  print_transfer_performance (gdb_stdout, data_count, write_count,
-                             end_time - start_time);
+  print_transfer_performance (gdb_stdout, cbdata.data_count, 
+                             cbdata.write_count, end_time - start_time);
 
   do_cleanups (old_cleanups);
 }