/* Generic symbol file reading for the GNU debugger, GDB.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001 Free Software Foundation, Inc.
+
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
Contributed by Cygnus Support, using pieces from other GDB modules.
This file is part of GDB.
/* External variables and functions referenced. */
-extern int info_verbose;
-
extern void report_transfer_performance (unsigned long, time_t, time_t);
/* Functions this file defines */
for (stp = start, oidx = 0; stp != end; stp++)
{
- if (stp->the_bfd_section->flags & (SEC_ALLOC | SEC_LOAD)
+ if (bfd_get_section_flags (stp->bfd,
+ stp->the_bfd_section) & (SEC_ALLOC | SEC_LOAD)
&& oidx < MAX_SECTIONS)
{
sap->other[oidx].addr = stp->addr;
- sap->other[oidx].name = xstrdup (stp->the_bfd_section->name);
+ sap->other[oidx].name
+ = xstrdup (bfd_section_name (stp->bfd, stp->the_bfd_section));
sap->other[oidx].sectindex = stp->the_bfd_section->index;
oidx++;
}
for (i = 0;
!s_addr && i < MAX_SECTIONS && addrs->other[i].name;
i++)
- if (strcmp (s->the_bfd_section->name, addrs->other[i].name) == 0)
+ if (strcmp (bfd_section_name (s->objfile->obfd,
+ s->the_bfd_section),
+ addrs->other[i].name) == 0)
s_addr = addrs->other[i].addr; /* end added for gdb/13815 */
s->addr -= s->offset;
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. */
+ 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;
+
+ 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;
- CORE_ADDR total_size = 0;
- CORE_ADDR total_sent = 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. */
if (offptr != NULL)
{
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);
bfd_errmsg (bfd_get_error ()));
}
- for (s = loadfile_bfd->sections; s; s = s->next)
- if (s->flags & 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)
- {
- CORE_ADDR size = bfd_get_section_size_before_reloc (s);
- if (size > 0)
- {
- char *buffer;
- struct cleanup *old_chain;
- CORE_ADDR lma = s->lma + load_offset;
- CORE_ADDR block_size;
- int err;
- const char *sect_name = bfd_get_section_name (loadfile_bfd, s);
- CORE_ADDR 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
- {
- CORE_ADDR len;
- CORE_ADDR 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;
- total_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, total_sent, 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;
- 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", "%ld" , data_count);
- ui_out_text (uiout, "\n");
-#else
- fprintf_unfiltered (gdb_stdout,
- "Start address 0x%s , load size %ld\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);
- }
+ entry = bfd_get_start_address (loadfile_bfd);
+ 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");
+ /* 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
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);
}
report_transfer_performance (unsigned long data_count, time_t start_time,
time_t end_time)
{
- print_transfer_performance (gdb_stdout, data_count, end_time - start_time, 0);
+ print_transfer_performance (gdb_stdout, data_count,
+ end_time - start_time, 0);
}
void
unsigned long write_count,
unsigned long time_count)
{
-#ifdef UI_OUT
ui_out_text (uiout, "Transfer rate: ");
if (time_count > 0)
{
- ui_out_field_fmt (uiout, "transfer-rate", "%ld",
+ ui_out_field_fmt (uiout, "transfer-rate", "%lu",
(data_count * 8) / time_count);
ui_out_text (uiout, " bits/sec");
}
else
{
- ui_out_field_fmt (uiout, "transferred-bits", "%ld", (data_count * 8));
+ ui_out_field_fmt (uiout, "transferred-bits", "%lu", (data_count * 8));
ui_out_text (uiout, " bits in <1 sec");
}
if (write_count > 0)
{
ui_out_text (uiout, ", ");
- ui_out_field_fmt (uiout, "write-rate", "%ld", data_count / write_count);
+ ui_out_field_fmt (uiout, "write-rate", "%lu", data_count / write_count);
ui_out_text (uiout, " bytes/write");
}
ui_out_text (uiout, ".\n");
-#else
- fprintf_unfiltered (stream, "Transfer rate: ");
- if (time_count > 0)
- fprintf_unfiltered (stream, "%ld bits/sec", (data_count * 8) / time_count);
- else
- fprintf_unfiltered (stream, "%ld bits in <1 sec", (data_count * 8));
- if (write_count > 0)
- fprintf_unfiltered (stream, ", %ld bytes/write", data_count / write_count);
- fprintf_unfiltered (stream, ".\n");
-#endif
}
/* This function allows the addition of incrementally linked object files.
/* FIXME: Do we have to free a whole linked list, or is this
enough? */
if (objfile->global_psymbols.list)
- mfree (objfile->md, objfile->global_psymbols.list);
+ xmfree (objfile->md, objfile->global_psymbols.list);
memset (&objfile->global_psymbols, 0,
sizeof (objfile->global_psymbols));
if (objfile->static_psymbols.list)
- mfree (objfile->md, objfile->static_psymbols.list);
+ xmfree (objfile->md, objfile->static_psymbols.list);
memset (&objfile->static_psymbols, 0,
sizeof (objfile->static_psymbols));
if (objfile->global_psymbols.list)
{
- mfree (objfile->md, (PTR) objfile->global_psymbols.list);
+ xmfree (objfile->md, (PTR) objfile->global_psymbols.list);
}
if (objfile->static_psymbols.list)
{
- mfree (objfile->md, (PTR) objfile->static_psymbols.list);
+ xmfree (objfile->md, (PTR) objfile->static_psymbols.list);
}
/* Current best guess is that approximately a twentieth
/* Overlay debugging state: */
-int overlay_debugging = 0; /* 0 == off, 1 == manual, -1 == auto */
+enum overlay_debugging_state overlay_debugging = ovly_off;
int overlay_cache_invalid = 0; /* True if need to refresh mapped state */
/* Target vector for refreshing overlay mapped state */
int
section_is_overlay (asection *section)
{
+ /* FIXME: need bfd *, so we can use bfd_section_lma methods. */
+
if (overlay_debugging)
if (section && section->lma != 0 &&
section->vma != section->lma)
switch (overlay_debugging)
{
default:
- case 0:
+ case ovly_off:
return 0; /* overlay debugging off */
- case -1: /* overlay debugging automatic */
+ case ovly_auto: /* overlay debugging automatic */
/* Unles there is a target_overlay_update function,
there's really nothing useful to do here (can't really go auto) */
if (target_overlay_update)
(*target_overlay_update) (osect);
}
/* fall thru to manual case */
- case 1: /* overlay debugging manual */
+ case ovly_on: /* overlay debugging manual */
return osect->ovly_mapped == 1;
}
}
CORE_ADDR
pc_in_unmapped_range (CORE_ADDR pc, asection *section)
{
+ /* FIXME: need bfd *, so we can use bfd_section_lma methods. */
+
int size;
if (overlay_debugging)
CORE_ADDR
pc_in_mapped_range (CORE_ADDR pc, asection *section)
{
+ /* FIXME: need bfd *, so we can use bfd_section_vma methods. */
+
int size;
if (overlay_debugging)
int
sections_overlap (asection *a, asection *b)
{
+ /* FIXME: need bfd *, so we can use bfd_section_vma methods. */
+
CORE_ADDR a_start = a->vma;
CORE_ADDR a_end = a->vma + bfd_get_section_size_before_reloc (a);
CORE_ADDR b_start = b->vma;
CORE_ADDR
overlay_unmapped_address (CORE_ADDR pc, asection *section)
{
+ /* FIXME: need bfd *, so we can use bfd_section_lma methods. */
+
if (overlay_debugging)
if (section && section_is_overlay (section) &&
pc_in_mapped_range (pc, section))
CORE_ADDR
overlay_mapped_address (CORE_ADDR pc, asection *section)
{
+ /* FIXME: need bfd *, so we can use bfd_section_vma methods. */
+
if (overlay_debugging)
if (section && section_is_overlay (section) &&
pc_in_unmapped_range (pc, section))
static void
overlay_auto_command (char *args, int from_tty)
{
- overlay_debugging = -1;
+ overlay_debugging = ovly_auto;
if (info_verbose)
printf_filtered ("Automatic overlay debugging enabled.");
}
static void
overlay_manual_command (char *args, int from_tty)
{
- overlay_debugging = 1;
+ overlay_debugging = ovly_on;
if (info_verbose)
printf_filtered ("Overlay debugging enabled.");
}
static void
overlay_off_command (char *args, int from_tty)
{
- overlay_debugging = 0;
+ overlay_debugging = ovly_off;
if (info_verbose)
printf_filtered ("Overlay debugging disabled.");
}
static void
read_target_long_array (CORE_ADDR memaddr, unsigned int *myaddr, int len)
{
+ /* FIXME (alloca): Not safe if array is very large. */
char *buf = alloca (len * TARGET_LONG_BYTES);
int i;
static int
simple_read_overlay_table (void)
{
- struct minimal_symbol *msym;
+ struct minimal_symbol *novlys_msym, *ovly_table_msym;
simple_free_overlay_table ();
- msym = lookup_minimal_symbol ("_novlys", 0, 0);
- if (msym != NULL)
- cache_novlys = read_memory_integer (SYMBOL_VALUE_ADDRESS (msym), 4);
- else
- return 0; /* failure */
- cache_ovly_table = (void *) xmalloc (cache_novlys * sizeof (*cache_ovly_table));
- if (cache_ovly_table != NULL)
+ novlys_msym = lookup_minimal_symbol ("_novlys", NULL, NULL);
+ if (! novlys_msym)
{
- msym = lookup_minimal_symbol ("_ovly_table", 0, 0);
- if (msym != NULL)
- {
- cache_ovly_table_base = SYMBOL_VALUE_ADDRESS (msym);
- read_target_long_array (cache_ovly_table_base,
- (int *) cache_ovly_table,
- cache_novlys * 4);
- }
- else
- return 0; /* failure */
+ error ("Error reading inferior's overlay table: "
+ "couldn't find `_novlys' variable\n"
+ "in inferior. Use `overlay manual' mode.");
+ return 0;
}
- else
- return 0; /* failure */
+
+ ovly_table_msym = lookup_minimal_symbol ("_ovly_table", NULL, NULL);
+ if (! ovly_table_msym)
+ {
+ error ("Error reading inferior's overlay table: couldn't find "
+ "`_ovly_table' array\n"
+ "in inferior. Use `overlay manual' mode.");
+ return 0;
+ }
+
+ cache_novlys = read_memory_integer (SYMBOL_VALUE_ADDRESS (novlys_msym), 4);
+ cache_ovly_table
+ = (void *) xmalloc (cache_novlys * sizeof (*cache_ovly_table));
+ cache_ovly_table_base = SYMBOL_VALUE_ADDRESS (ovly_table_msym);
+ read_target_long_array (cache_ovly_table_base,
+ (int *) cache_ovly_table,
+ cache_novlys * 4);
+
return 1; /* SUCCESS */
}
struct minimal_symbol *msym;
simple_free_overlay_region_table ();
- msym = lookup_minimal_symbol ("_novly_regions", 0, 0);
+ msym = lookup_minimal_symbol ("_novly_regions", NULL, NULL);
if (msym != NULL)
cache_novly_regions = read_memory_integer (SYMBOL_VALUE_ADDRESS (msym), 4);
else
cache_ovly_region_table = (void *) xmalloc (cache_novly_regions * 12);
if (cache_ovly_region_table != NULL)
{
- msym = lookup_minimal_symbol ("_ovly_region_table", 0, 0);
+ msym = lookup_minimal_symbol ("_ovly_region_table", NULL, NULL);
if (msym != NULL)
{
cache_ovly_region_table_base = SYMBOL_VALUE_ADDRESS (msym);
simple_overlay_update_1 (struct obj_section *osect)
{
int i, size;
+ bfd *obfd = osect->objfile->obfd;
+ asection *bsect = osect->the_bfd_section;
size = bfd_get_section_size_before_reloc (osect->the_bfd_section);
for (i = 0; i < cache_novlys; i++)
- if (cache_ovly_table[i][VMA] == osect->the_bfd_section->vma &&
- cache_ovly_table[i][LMA] == osect->the_bfd_section->lma /* &&
- cache_ovly_table[i][SIZE] == size */ )
+ if (cache_ovly_table[i][VMA] == bfd_section_vma (obfd, bsect)
+ && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, bsect)
+ /* && cache_ovly_table[i][SIZE] == size */ )
{
read_target_long_array (cache_ovly_table_base + i * TARGET_LONG_BYTES,
(int *) cache_ovly_table[i], 4);
- if (cache_ovly_table[i][VMA] == osect->the_bfd_section->vma &&
- cache_ovly_table[i][LMA] == osect->the_bfd_section->lma /* &&
- cache_ovly_table[i][SIZE] == size */ )
+ if (cache_ovly_table[i][VMA] == bfd_section_vma (obfd, bsect)
+ && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, bsect)
+ /* && cache_ovly_table[i][SIZE] == size */ )
{
osect->ovly_mapped = cache_ovly_table[i][MAPPED];
return 1;
}
- else /* Warning! Warning! Target's ovly table has changed! */
+ else /* Warning! Warning! Target's ovly table has changed! */
return 0;
}
return 0;
if (cache_ovly_table != NULL)
/* Does its cached location match what's currently in the symtab? */
if (cache_ovly_table_base ==
- SYMBOL_VALUE_ADDRESS (lookup_minimal_symbol ("_ovly_table", 0, 0)))
+ SYMBOL_VALUE_ADDRESS (lookup_minimal_symbol ("_ovly_table", NULL, NULL)))
/* Then go ahead and try to look up this single section in the cache */
if (simple_overlay_update_1 (osect))
/* Found it! We're done. */
Or else we want all the sections, in which case it's actually
more efficient to read the whole table in one block anyway. */
- if (simple_read_overlay_table () == 0) /* read failed? No table? */
- {
- warning ("Failed to read the target overlay mapping table.");
- return;
- }
+ if (! simple_read_overlay_table ())
+ return;
+
/* Now may as well update all sections, even if only one was requested. */
ALL_OBJSECTIONS (objfile, osect)
if (section_is_overlay (osect->the_bfd_section))
{
int i, size;
+ bfd *obfd = osect->objfile->obfd;
+ asection *bsect = osect->the_bfd_section;
size = bfd_get_section_size_before_reloc (osect->the_bfd_section);
for (i = 0; i < cache_novlys; i++)
- if (cache_ovly_table[i][VMA] == osect->the_bfd_section->vma &&
- cache_ovly_table[i][LMA] == osect->the_bfd_section->lma /* &&
- cache_ovly_table[i][SIZE] == size */ )
- { /* obj_section matches i'th entry in ovly_table */
+ if (cache_ovly_table[i][VMA] == bfd_section_vma (obfd, bsect)
+ && cache_ovly_table[i][LMA] == bfd_section_lma (obfd, bsect)
+ /* && cache_ovly_table[i][SIZE] == size */ )
+ { /* obj_section matches i'th entry in ovly_table */
osect->ovly_mapped = cache_ovly_table[i][MAPPED];
break; /* finished with inner for loop: break out */
}
"Set mapping between filename extension and source language.\n\
Usage: set extension-language .foo bar",
&setlist);
- c->function.cfunc = set_ext_lang_command;
+ set_cmd_cfunc (c, set_ext_lang_command);
add_info ("extensions", info_ext_lang_command,
"All filename extensions associated with a source language.");