diff options
author | Pedro Alves <palves@redhat.com> | 2009-06-03 18:50:36 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2009-06-03 18:50:36 +0000 |
commit | 07b82ea5f9396811815e8085a4cce5ca03f50fb5 (patch) | |
tree | 528772b8131a21e8de911a9e68a4c78a780c8dd3 /gdb/exec.c | |
parent | 4fa62494657f9b422edd7049c7207bd6c6849c3f (diff) | |
download | gdb-07b82ea5f9396811815e8085a4cce5ca03f50fb5.zip gdb-07b82ea5f9396811815e8085a4cce5ca03f50fb5.tar.gz gdb-07b82ea5f9396811815e8085a4cce5ca03f50fb5.tar.bz2 |
* target.c: Include "exec.h".
(update_current_target): Don't inherit to_sections or
to_sections_end.
(target_get_section_table): New.
(target_section_by_addr): Fetch the section table from the passed
in target.
(memory_xfer_partial): Handle unmapped overlay sections before
anything else. Get the overlay mapped address here. Adjust to
use section_table_xfer_memory_partial.
(get_target_memory): Request a TARGET_OBJECT_RAW_MEMORY object
instead of TARGET_OBJECT_MEMORY.
(target_resize_to_sections): Delete.
(remove_target_sections): Adjust to remove target sections from
`current_target_sections', and use resize_section_table.
* target.h (struct target_ops) <to_sections, to_sections_end>:
Remove fields.
<to_get_section_table>: New method.
(xfer_memory, print_section_info): Delete declarations.
(struct target_section_table): New type.
(target_get_section_table): Declare.
(target_resize_to_sections): Delete declaration.
(remove_target_sections): Delete declaration.
* bfd-target.c (target_bfd_xfer_partial): Get the section table
from to_data.
(target_bfd_get_section_table): New.
(target_bfd_xclose): Adjust.
(target_bfd_reopen): Store the section table in the to_data field.
* corelow.c (core_data): New.
(core_close): Adjust to release core_data and its sections.
(core_open): Allocate core_data, and build its target sections
table.
(deprecated_core_resize_section_table): New.
(core_files_info): Pass core_data to print_section_info.
(core_xfer_partial): Adjust to use
section_table_xfer_memory_partial for TARGET_OBJECT_MEMORY xfers.
(init_core_ops): Do not install a deprecated_xfer_memory callback
anymore.
* solib.c (update_solib_list): Add the shared library sections
to the current target sections table.
* exec.c (current_target_sections_1): New global.
(current_target_sections): New global.
(exec_close_1): New function, refactored from exec_close. Remove
the exec_bfd's sections from the current target sections table.
Adjust to not use to_sections.
(exec_close): Remove all target sections. Call exec_close_1.
(exec_file_clear): Use exec_close_1 instead of unpushing the
target.
(exec_file_attach): Likewise. Adjust to not use to_sections. Add
exec_bfd's sections to the current target sections table. Don't
push the exec_ops target here.
(resize_section_table): New.
(add_target_sections): New.
(remove_target_sections): Moved here.
(section_table_xfer_memory): Adjust to implement the xfer_partial
interface, and rename to...
(section_table_xfer_memory_partial): ... this, replacing the
current function of that same name.
(exec_get_section_table): New.
(exec_xfer_partial): New.
(xfer_memory): Delete.
(print_section_info): Replace the target_ops parameter by a
target_section_table parameter.
(exec_files_info, set_section_command, exec_set_section_address):
Adjust to use the current sections table.
(init_exec_ops): Do not register a deprecated_xfer_memory
callback. Register to_xfer_partial and to_get_section_table
callbacks.
* infrun.c (handle_inferior_event): Update comments around
solib_add.
* rs6000-nat.c (xcoff_relocate_core): Adjust to use
deprecated_core_resize_section_table.
* exec.h (resize_section_table): Declare.
(section_table_xfer_memory_partial): Add const char * argument.
(remove_target_sections): Declare here.
(add_target_sections): Declare.
(print_section_info): Declare here.
* gdbcore.h (deprecated_core_resize_section_table): Declare.
Diffstat (limited to 'gdb/exec.c')
-rw-r--r-- | gdb/exec.c | 288 |
1 files changed, 182 insertions, 106 deletions
@@ -71,6 +71,16 @@ struct target_ops exec_ops; bfd *exec_bfd = NULL; long exec_bfd_mtime = 0; +/* GDB currently only supports a single symbol/address space for the + whole debug session. When that limitation is lifted, this global + goes away. */ +static struct target_section_table current_target_sections_1; + +/* The set of target sections matching the sections mapped into the + current inferior's address space. */ +static struct target_section_table *current_target_sections + = ¤t_target_sections_1; + /* Whether to open exec and core files read-only or read-write. */ int write_files = 0; @@ -92,6 +102,31 @@ exec_open (char *args, int from_tty) exec_file_attach (args, from_tty); } +/* Close and clear exec_bfd. If we end up with no target sections to + read memory from, this unpushes the exec_ops target. */ + +static void +exec_close_1 (void) +{ + if (exec_bfd) + { + bfd *abfd = exec_bfd; + char *name = bfd_get_filename (abfd); + + if (!bfd_close (abfd)) + warning (_("cannot close \"%s\": %s"), + name, bfd_errmsg (bfd_get_error ())); + xfree (name); + + /* Removing target sections may close the exec_ops target. + Clear exec_bfd before doing so to prevent recursion. */ + exec_bfd = NULL; + exec_bfd_mtime = 0; + + remove_target_sections (abfd); + } +} + static void exec_close (int quitting) { @@ -128,31 +163,20 @@ exec_close (int quitting) vmap = NULL; - if (exec_bfd) - { - char *name = bfd_get_filename (exec_bfd); + /* Delete all target sections. */ + resize_section_table + (current_target_sections, + -resize_section_table (current_target_sections, 0)); - if (!bfd_close (exec_bfd)) - warning (_("cannot close \"%s\": %s"), - name, bfd_errmsg (bfd_get_error ())); - xfree (name); - exec_bfd = NULL; - exec_bfd_mtime = 0; - } - - if (exec_ops.to_sections) - { - xfree (exec_ops.to_sections); - exec_ops.to_sections = NULL; - exec_ops.to_sections_end = NULL; - } + /* Remove exec file. */ + exec_close_1 (); } void exec_file_clear (int from_tty) { /* Remove exec file. */ - unpush_target (&exec_ops); + exec_close_1 (); if (from_tty) printf_unfiltered (_("No executable file now.\n")); @@ -179,7 +203,7 @@ void exec_file_attach (char *filename, int from_tty) { /* Remove any previous exec file. */ - unpush_target (&exec_ops); + exec_close_1 (); /* Now open and digest the file the user requested, if any. */ @@ -195,6 +219,7 @@ exec_file_attach (char *filename, int from_tty) struct cleanup *cleanups; char *scratch_pathname; int scratch_chan; + struct target_section *sections = NULL, *sections_end = NULL; scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, @@ -233,7 +258,7 @@ exec_file_attach (char *filename, int from_tty) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ - exec_close (0); + exec_close_1 (); error (_("\"%s\": not in executable format: %s"), scratch_pathname, bfd_errmsg (bfd_get_error ())); } @@ -248,18 +273,17 @@ exec_file_attach (char *filename, int from_tty) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ - exec_close (0); + exec_close_1 (); error (_("\"%s\": can't find the file sections: %s"), scratch_pathname, bfd_errmsg (bfd_get_error ())); } #endif /* DEPRECATED_IBM6000_TARGET */ - if (build_section_table (exec_bfd, &exec_ops.to_sections, - &exec_ops.to_sections_end)) + if (build_section_table (exec_bfd, §ions, §ions_end)) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ - exec_close (0); + exec_close_1 (); error (_("\"%s\": can't find the file sections: %s"), scratch_pathname, bfd_errmsg (bfd_get_error ())); } @@ -270,7 +294,10 @@ exec_file_attach (char *filename, int from_tty) set_gdbarch_from_file (exec_bfd); - push_target (&exec_ops); + /* Add the executable's sections to the current address spaces' + list of sections. */ + add_target_sections (sections, sections_end); + xfree (sections); /* Tell display code (if any) about the changed file name. */ if (deprecated_exec_file_display_hook) @@ -370,6 +397,33 @@ add_to_section_table (bfd *abfd, struct bfd_section *asect, (*table_pp)++; } +int +resize_section_table (struct target_section_table *table, int num_added) +{ + struct target_section *old_value; + int old_count; + int new_count; + + old_value = table->sections; + old_count = table->sections_end - table->sections; + + new_count = num_added + old_count; + + if (new_count) + { + table->sections = xrealloc (table->sections, + sizeof (struct target_section) * new_count); + table->sections_end = table->sections + new_count; + } + else + { + xfree (table->sections); + table->sections = table->sections_end = NULL; + } + + return old_count; +} + /* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR. Returns 0 if OK, 1 on error. */ @@ -390,6 +444,65 @@ build_section_table (struct bfd *some_bfd, struct target_section **start, /* We could realloc the table, but it probably loses for most files. */ return 0; } + +/* Add the sections array defined by [SECTIONS..SECTIONS_END[ to the + current set of target sections. */ + +void +add_target_sections (struct target_section *sections, + struct target_section *sections_end) +{ + int count; + struct target_section_table *table = current_target_sections; + + count = sections_end - sections; + + if (count > 0) + { + int space = resize_section_table (table, count); + memcpy (table->sections + space, + sections, count * sizeof (sections[0])); + + /* If these are the first file sections we can provide memory + from, push the file_stratum target. */ + if (space == 0) + push_target (&exec_ops); + } +} + +/* Remove all target sections taken from ABFD. */ + +void +remove_target_sections (bfd *abfd) +{ + struct target_section *src, *dest; + + struct target_section_table *table = current_target_sections; + + dest = table->sections; + for (src = table->sections; src < table->sections_end; src++) + if (src->bfd != abfd) + { + /* Keep this section. */ + if (dest < src) + *dest = *src; + dest++; + } + + /* If we've dropped any sections, resize the section table. */ + if (dest < src) + { + int old_count; + + old_count = resize_section_table (table, dest - src); + + /* If we don't have any more sections to read memory from, + remove the file_stratum target from the stack. */ + if (old_count + (dest - src) == 0) + unpush_target (&exec_ops); + } +} + static void bfdsec_to_vmap (struct bfd *abfd, struct bfd_section *sect, void *arg3) @@ -467,22 +580,21 @@ map_vmap (bfd *abfd, bfd *arch) < 0: We cannot handle this address, but if somebody else handles (-N) bytes, we can start from there. */ -static int -section_table_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, - int len, int write, - struct target_section *sections, - struct target_section *sections_end, - const char *section_name) +int +section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf, + ULONGEST offset, LONGEST len, + struct target_section *sections, + struct target_section *sections_end, + const char *section_name) { int res; struct target_section *p; - CORE_ADDR nextsectaddr, memend; + ULONGEST memaddr = offset; + ULONGEST memend = memaddr + len; if (len <= 0) internal_error (__FILE__, __LINE__, _("failed internal consistency check")); - memend = memaddr + len; - nextsectaddr = memend; for (p = sections; p < sections_end; p++) { @@ -493,13 +605,13 @@ section_table_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, if (memend <= p->endaddr) { /* Entire transfer is within this section. */ - if (write) + if (writebuf) res = bfd_set_section_contents (p->bfd, p->the_bfd_section, - myaddr, memaddr - p->addr, + writebuf, memaddr - p->addr, len); else res = bfd_get_section_contents (p->bfd, p->the_bfd_section, - myaddr, memaddr - p->addr, + readbuf, memaddr - p->addr, len); return (res != 0) ? len : 0; } @@ -512,90 +624,49 @@ section_table_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, { /* This section overlaps the transfer. Just do half. */ len = p->endaddr - memaddr; - if (write) + if (writebuf) res = bfd_set_section_contents (p->bfd, p->the_bfd_section, - myaddr, memaddr - p->addr, + writebuf, memaddr - p->addr, len); else res = bfd_get_section_contents (p->bfd, p->the_bfd_section, - myaddr, memaddr - p->addr, + readbuf, memaddr - p->addr, len); return (res != 0) ? len : 0; } } - else - nextsectaddr = min (nextsectaddr, p->addr); } - if (nextsectaddr >= memend) - return 0; /* We can't help */ - else - return -(nextsectaddr - memaddr); /* Next boundary where we can help */ + return 0; /* We can't help */ } -int -section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf, - ULONGEST offset, LONGEST len, - struct target_section *sections, - struct target_section *sections_end) +struct target_section_table * +exec_get_section_table (struct target_ops *ops) { - if (readbuf != NULL) - return section_table_xfer_memory (offset, readbuf, len, 0, - sections, sections_end, NULL); - else - return section_table_xfer_memory (offset, (gdb_byte *) writebuf, len, 1, - sections, sections_end, NULL); + return current_target_sections; } -/* Read or write the exec file. - - Args are address within a BFD file, address within gdb address-space, - length, and a flag indicating whether to read or write. - - Result is a length: - - 0: We cannot handle this address and length. - > 0: We have handled N bytes starting at this address. - (If N == length, we did it all.) We might be able - to handle more bytes beyond this length, but no - promises. - < 0: We cannot handle this address, but if somebody - else handles (-N) bytes, we can start from there. - - The same routine is used to handle both core and exec files; - we just tail-call it with more arguments to select between them. */ - -int -xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write, - struct mem_attrib *attrib, struct target_ops *target) +static LONGEST +exec_xfer_partial (struct target_ops *ops, enum target_object object, + const char *annex, gdb_byte *readbuf, + const gdb_byte *writebuf, + ULONGEST offset, LONGEST len) { - int res; - const char *section_name = NULL; - - if (len <= 0) - internal_error (__FILE__, __LINE__, _("failed internal consistency check")); - - if (overlay_debugging) - { - struct obj_section *section = find_pc_overlay (memaddr); - - if (section != NULL) - { - if (pc_in_unmapped_range (memaddr, section)) - memaddr = overlay_mapped_address (memaddr, section); - section_name = section->the_bfd_section->name; - } - } - - return section_table_xfer_memory (memaddr, myaddr, len, write, - target->to_sections, - target->to_sections_end, - section_name); + struct target_section_table *table = target_get_section_table (ops); + + if (object == TARGET_OBJECT_MEMORY) + return section_table_xfer_memory_partial (readbuf, writebuf, + offset, len, + table->sections, + table->sections_end, + NULL); + else + return -1; } void -print_section_info (struct target_ops *t, bfd *abfd) +print_section_info (struct target_section_table *t, bfd *abfd) { struct target_section *p; /* FIXME: 16 is not wide enough when gdbarch_addr_bit > 64. */ @@ -607,7 +678,7 @@ print_section_info (struct target_ops *t, bfd *abfd) if (abfd == exec_bfd) printf_filtered (_("\tEntry point: %s\n"), paddress (bfd_get_start_address (abfd))); - for (p = t->to_sections; p < t->to_sections_end; p++) + for (p = t->sections; p < t->sections_end; p++) { printf_filtered ("\t%s", hex_string_custom (p->addr, wid)); printf_filtered (" - %s", hex_string_custom (p->endaddr, wid)); @@ -631,7 +702,7 @@ print_section_info (struct target_ops *t, bfd *abfd) static void exec_files_info (struct target_ops *t) { - print_section_info (t, exec_bfd); + print_section_info (current_target_sections, exec_bfd); if (vmap) { @@ -667,6 +738,7 @@ set_section_command (char *args, int from_tty) unsigned long secaddr; char secprint[100]; long offset; + struct target_section_table *table; if (args == 0) error (_("Must specify section name and its virtual address")); @@ -678,7 +750,8 @@ set_section_command (char *args, int from_tty) /* Parse out new virtual address */ secaddr = parse_and_eval_address (args); - for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++) + table = current_target_sections; + for (p = table->sections; p < table->sections_end; p++) { if (!strncmp (secname, bfd_section_name (exec_bfd, p->the_bfd_section), seclen) && bfd_section_name (exec_bfd, p->the_bfd_section)[seclen] == '\0') @@ -705,8 +778,10 @@ void exec_set_section_address (const char *filename, int index, CORE_ADDR address) { struct target_section *p; + struct target_section_table *table; - for (p = exec_ops.to_sections; p < exec_ops.to_sections_end; p++) + table = current_target_sections; + for (p = table->sections; p < table->sections_end; p++) { if (strcmp (filename, p->bfd->filename) == 0 && index == p->the_bfd_section->index) @@ -754,7 +829,8 @@ Specify the filename of the executable file."; exec_ops.to_open = exec_open; exec_ops.to_close = exec_close; exec_ops.to_attach = find_default_attach; - exec_ops.deprecated_xfer_memory = xfer_memory; + exec_ops.to_xfer_partial = exec_xfer_partial; + exec_ops.to_get_section_table = exec_get_section_table; exec_ops.to_files_info = exec_files_info; exec_ops.to_insert_breakpoint = ignore; exec_ops.to_remove_breakpoint = ignore; |