This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA] symfile.c -- one more bfd access method change


Elena Zannoni wrote:
> 
> Michael Snyder writes:
>  >
>  > Last one, I promise.  Use bfd_map_over_sections function instead of
>  > grokking the bfd structure directly.
>  >
>  > 2002-01-11  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.
>  >      (load_sections_callback): New function, bfd sections callback.
> 
> OK, but can you change the ChangeLog to say that
> load_section_callback's code is a piece of generic_load?
> 
> Thanks
> Elena

OK, committed.

> 
>  >
>  > Index: symfile.c
>  > ===================================================================
>  > RCS file: /cvs/src/src/gdb/symfile.c,v
>  > retrieving revision 1.48
>  > diff -c -3 -p -r1.48 symfile.c
>  > *** symfile.c        2002/01/13 05:59:30     1.48
>  > --- symfile.c        2002/01/13 06:02:39
>  > *************** load_command (char *arg, int from_tty)
>  > *** 1174,1192 ****
>  >   static int download_write_size = 512;
>  >   static int validate_download = 0;
>  >
>  >   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;
>  >
>  >     /* Parse the input argument - the user can specify a load offset as
>  >        a second argument. */
>  > --- 1174,1312 ----
>  >   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 */
>  >     char *filename;
>  >     struct cleanup *old_cleanups;
>  >     char *offptr;
>  > !   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. */
>  > *************** generic_load (char *args, int from_tty)
>  > *** 1198,1210 ****
>  >       {
>  >         char *endptr;
>  >
>  > !       load_offset = strtoul (offptr, &endptr, 0);
>  >         if (offptr == endptr)
>  >      error ("Invalid download offset:%s\n", offptr);
>  >         *offptr = '\0';
>  >       }
>  >     else
>  > !     load_offset = 0;
>  >
>  >     /* Open the file for loading. */
>  >     loadfile_bfd = bfd_openr (filename, gnutarget);
>  > --- 1318,1330 ----
>  >       {
>  >         char *endptr;
>  >
>  > !       cbdata.load_offset = strtoul (offptr, &endptr, 0);
>  >         if (offptr == endptr)
>  >      error ("Invalid download offset:%s\n", offptr);
>  >         *offptr = '\0';
>  >       }
>  >     else
>  > !     cbdata.load_offset = 0;
>  >
>  >     /* Open the file for loading. */
>  >     loadfile_bfd = bfd_openr (filename, gnutarget);
>  > *************** generic_load (char *args, int from_tty)
>  > *** 1225,1353 ****
>  >           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);
>  >
>  >     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);
>  > -        }
>  > -    }
>  > -     }
>  > -
>  >     end_time = time (NULL);
>  > -   {
>  > -     CORE_ADDR 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");
>  > !
>  >   #else
>  > !     fprintf_unfiltered (gdb_stdout,
>  > !                    "Start address 0x%s, load size %lu\n",
>  > !                    paddr_nz (entry), data_count);
>  >   #endif
>  > !     /* 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
>  > --- 1345,1374 ----
>  >           bfd_errmsg (bfd_get_error ()));
>  >       }
>  >
>  > !   bfd_map_over_sections (loadfile_bfd, add_section_size_callback,
>  > !                     (void *) &cbdata.total_size);
>  >
>  >     start_time = time (NULL);
>  >
>  > !   bfd_map_over_sections (loadfile_bfd, load_section_callback, &cbdata);
>  >
>  >     end_time = time (NULL);
>  >
>  > +   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", cbdata.data_count);
>  > !   ui_out_text (uiout, "\n");
>  >   #else
>  > !   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);
>  >
>  >     /* 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
>  > *************** generic_load (char *args, int from_tty)
>  > *** 1355,1362 ****
>  >        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);
>  >
>  >     do_cleanups (old_cleanups);
>  >   }
>  > --- 1376,1383 ----
>  >        loaded in.  remote-nindy.c had no call to symbol_file_add, but remote-vx.c
>  >        does.  */
>  >
>  > !   print_transfer_performance (gdb_stdout, cbdata.data_count,
>  > !                          cbdata.write_count, end_time - start_time);
>  >
>  >     do_cleanups (old_cleanups);
>  >   }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]