aboutsummaryrefslogtreecommitdiff
path: root/gdb/symfile.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2006-08-15 18:46:25 +0000
committerDaniel Jacobowitz <drow@false.org>2006-08-15 18:46:25 +0000
commitcf7a04e8fbf324f6be2009931021fda40479f2dd (patch)
tree39372f9e07462f178418ec6c91dd008f4d691bd1 /gdb/symfile.c
parent8992f0d7c2d63ad6b5c102572be103791c6a958e (diff)
downloadgdb-cf7a04e8fbf324f6be2009931021fda40479f2dd.zip
gdb-cf7a04e8fbf324f6be2009931021fda40479f2dd.tar.gz
gdb-cf7a04e8fbf324f6be2009931021fda40479f2dd.tar.bz2
PR remote/1966
* dcache.c (dcache_write_line): Use target_write. (dcache_read_line): Use target_read. * mi/mi-main.c (mi_cmd_data_read_memory): Use target_read. * symfile.c (struct load_section_data): Add new per-section members. (load_progress): New function. (load_section_callback): Pass load_progress to the new target_write_with_progress. * target.c (current_xfer_partial, memory_xfer_partial): New. (target_xfer_partial): New prototype. (target_xfer_memory, target_xfer_partial_p, xfer_using_stratum) (do_xfer_memory, target_xfer_memory_partial) (target_read_memory_partial, target_write_memory_partial): Delete. (trust_readonly): Move higher in the file. (update_current_target): Use current_xer_partial. (target_xfer_partial): Use memory_xfer_partial. Handle TARGET_OBJECT_RAW_MEMORY specially. (target_read_memory): Use target_read. (target_write_memory): Use target_write. (default_xfer_partial): Call to_xfer_partial directly. (target_write_with_progress): New function, based on target_write. (target_write): Call it. * target.h (enum target_object): Add TARGET_OBJECT_RAW_MEMORY. (target_write_with_progress): New prototype. (do_xfer_memory, target_read_memory_partial) (target_write_memory_partial): Delete prototypes.
Diffstat (limited to 'gdb/symfile.c')
-rw-r--r--gdb/symfile.c163
1 files changed, 87 insertions, 76 deletions
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 9d89f83..8a6c65b 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1540,93 +1540,104 @@ struct load_section_data {
unsigned long write_count;
unsigned long data_count;
bfd_size_type total_size;
+
+ /* Per-section data for load_progress. */
+ const char *section_name;
+ ULONGEST section_sent;
+ ULONGEST section_size;
+ CORE_ADDR lma;
+ gdb_byte *buffer;
};
+/* Target write callback routine for load_section_callback. */
+
+static void
+load_progress (ULONGEST bytes, void *untyped_arg)
+{
+ struct load_section_data *args = untyped_arg;
+
+ 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. */
+ gdb_byte *check = xmalloc (bytes);
+ struct cleanup *verify_cleanups = make_cleanup (xfree, check);
+
+ if (target_read_memory (args->lma, check, bytes) != 0)
+ error (_("Download verify read failed at 0x%s"),
+ paddr (args->lma));
+ if (memcmp (args->buffer, check, bytes) != 0)
+ error (_("Download verify compare failed at 0x%s"),
+ paddr (args->lma));
+ do_cleanups (verify_cleanups);
+ }
+ args->data_count += bytes;
+ args->lma += bytes;
+ args->buffer += bytes;
+ args->write_count += 1;
+ args->section_sent += bytes;
+ if (quit_flag
+ || (deprecated_ui_load_progress_hook != NULL
+ && deprecated_ui_load_progress_hook (args->section_name,
+ args->section_sent)))
+ error (_("Canceled the download"));
+
+ if (deprecated_show_load_progress != NULL)
+ deprecated_show_load_progress (args->section_name,
+ args->section_sent,
+ args->section_size,
+ args->data_count,
+ args->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;
+ bfd_size_type size = bfd_get_section_size (asec);
+ gdb_byte *buffer;
+ struct cleanup *old_chain;
+ const char *sect_name = bfd_get_section_name (abfd, asec);
+ LONGEST transferred;
- if (bfd_get_section_flags (abfd, asec) & SEC_LOAD)
- {
- bfd_size_type size = bfd_get_section_size (asec);
- if (size > 0)
- {
- gdb_byte *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;
-
- 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. */
- ui_out_message (uiout, 0, "Loading section %s, size 0x%s lma 0x%s\n",
- sect_name, paddr_nz (size), paddr_nz (lma));
-
- bfd_get_section_contents (abfd, asec, buffer, 0, size);
-
- sent = 0;
- do
- {
- int len;
- bfd_size_type this_transfer = size - sent;
-
- 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. */
- gdb_byte *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
- || (deprecated_ui_load_progress_hook != NULL
- && deprecated_ui_load_progress_hook (sect_name, sent)))
- error (_("Canceled the download"));
-
- if (deprecated_show_load_progress != NULL)
- deprecated_show_load_progress (sect_name, sent, size,
- args->data_count,
- args->total_size);
- }
- while (sent < size);
+ if ((bfd_get_section_flags (abfd, asec) & SEC_LOAD) == 0)
+ return;
- if (err != 0)
- error (_("Memory access error while loading section %s."), sect_name);
+ if (size == 0)
+ return;
- do_cleanups (old_chain);
- }
- }
+ buffer = xmalloc (size);
+ old_chain = make_cleanup (xfree, buffer);
+
+ args->section_name = sect_name;
+ args->section_sent = 0;
+ args->section_size = size;
+ args->lma = bfd_section_lma (abfd, asec) + args->load_offset;
+ args->buffer = buffer;
+
+ /* Is this really necessary? I guess it gives the user something
+ to look at during a long download. */
+ ui_out_message (uiout, 0, "Loading section %s, size 0x%s lma 0x%s\n",
+ sect_name, paddr_nz (size), paddr_nz (args->lma));
+
+ bfd_get_section_contents (abfd, asec, buffer, 0, size);
+
+ transferred = target_write_with_progress (&current_target,
+ TARGET_OBJECT_MEMORY,
+ NULL, buffer, args->lma,
+ size, load_progress, args);
+ if (transferred < size)
+ error (_("Memory access error while loading section %s."),
+ sect_name);
+
+ do_cleanups (old_chain);
}
void