From 07b82ea5f9396811815e8085a4cce5ca03f50fb5 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Wed, 3 Jun 2009 18:50:36 +0000 Subject: [PATCH] * 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) : Remove fields. : 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. --- gdb/ChangeLog | 80 +++++++++++++ gdb/bfd-target.c | 37 ++++-- gdb/corelow.c | 56 ++++++--- gdb/exec.c | 288 ++++++++++++++++++++++++++++++----------------- gdb/exec.h | 26 ++++- gdb/gdbcore.h | 2 + gdb/infrun.c | 18 --- gdb/rs6000-nat.c | 3 +- gdb/solib.c | 20 +--- gdb/target.c | 163 ++++++++++----------------- gdb/target.h | 32 +++--- 11 files changed, 434 insertions(+), 291 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 11bf9cac27c..13486a4bccb 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,83 @@ +2009-06-03 Pedro Alves + + * 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) : + Remove fields. + : 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. + 2009-06-03 Ulrich Weigand * value.h (struct internalvar): Remove. diff --git a/gdb/bfd-target.c b/gdb/bfd-target.c index 3eaae841616..ffaa4ffe440 100644 --- a/gdb/bfd-target.c +++ b/gdb/bfd-target.c @@ -32,35 +32,52 @@ target_bfd_xfer_partial (struct target_ops *ops, switch (object) { case TARGET_OBJECT_MEMORY: - return section_table_xfer_memory_partial (readbuf, writebuf, offset, len, - ops->to_sections, - ops->to_sections_end); + { + struct target_section_table *table = ops->to_data; + return section_table_xfer_memory_partial (readbuf, writebuf, offset, len, + table->sections, + table->sections_end, + NULL); + } default: return -1; } } +static struct target_section_table * +target_bfd_get_section_table (struct target_ops *ops) +{ + return ops->to_data; +} + static void target_bfd_xclose (struct target_ops *t, int quitting) { - bfd_close (t->to_data); - xfree (t->to_sections); + struct target_section_table *table = t->to_data; + if (table->sections) + bfd_close (table->sections->bfd); + xfree (table->sections); + xfree (table); xfree (t); } struct target_ops * target_bfd_reopen (struct bfd *bfd) { - struct target_ops *t = XZALLOC (struct target_ops); + struct target_ops *t; + struct target_section_table *table; + + table = XZALLOC (struct target_section_table); + build_section_table (bfd, &table->sections, &table->sections_end); + + t = XZALLOC (struct target_ops); t->to_shortname = "bfd"; t->to_longname = _("BFD backed target"); t->to_doc = _("You should never see this"); + t->to_get_section_table = target_bfd_get_section_table; t->to_xfer_partial = target_bfd_xfer_partial; t->to_xclose = target_bfd_xclose; - t->to_data = bfd; + t->to_data = table; - build_section_table (bfd, - &t->to_sections, - &t->to_sections_end); return t; } diff --git a/gdb/corelow.c b/gdb/corelow.c index ffaf04c93ae..947fe1fb042 100644 --- a/gdb/corelow.c +++ b/gdb/corelow.c @@ -67,6 +67,14 @@ static struct core_fns *core_vec = NULL; struct gdbarch *core_gdbarch = NULL; +/* Per-core data. Currently, only the section table. Note that these + target sections are *not* mapped in the current address spaces' set + of target sections --- those should come only from pure executable + or shared library bfds. The core bfd sections are an + implementation detail of the core target, just like ptrace is for + unix child targets. */ +static struct target_section_table *core_data; + static void core_files_info (struct target_ops *); static struct core_fns *sniff_core_bfd (bfd *); @@ -203,18 +211,16 @@ core_close (int quitting) comments in clear_solib in solib.c. */ clear_solib (); + xfree (core_data->sections); + xfree (core_data); + core_data = NULL; + name = bfd_get_filename (core_bfd); if (!bfd_close (core_bfd)) warning (_("cannot close \"%s\": %s"), name, bfd_errmsg (bfd_get_error ())); xfree (name); core_bfd = NULL; - if (core_ops.to_sections) - { - xfree (core_ops.to_sections); - core_ops.to_sections = NULL; - core_ops.to_sections_end = NULL; - } } core_vec = NULL; core_gdbarch = NULL; @@ -347,9 +353,11 @@ core_open (char *filename, int from_tty) validate_files (); + core_data = XZALLOC (struct target_section_table); + /* Find the data section */ - if (build_section_table (core_bfd, &core_ops.to_sections, - &core_ops.to_sections_end)) + if (build_section_table (core_bfd, + &core_data->sections, &core_data->sections_end)) error (_("\"%s\": Can't find sections: %s"), bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ())); @@ -434,6 +442,23 @@ core_detach (struct target_ops *ops, char *args, int from_tty) printf_filtered (_("No core file now.\n")); } +#ifdef DEPRECATED_IBM6000_TARGET + +/* Resize the core memory's section table, by NUM_ADDED. Returns a + pointer into the first new slot. This will not be necessary when + the rs6000 target is converted to use the standard solib + framework. */ + +struct target_section * +deprecated_core_resize_section_table (int num_added) +{ + int old_count; + + old_count = resize_section_table (core_data, num_added); + return core_data->sections + old_count; +} + +#endif /* Try to retrieve registers from a section in core_bfd, and supply them to core_vec->core_read_registers, as the register set numbered @@ -562,7 +587,7 @@ get_core_registers (struct target_ops *ops, static void core_files_info (struct target_ops *t) { - print_section_info (t, core_bfd); + print_section_info (core_data, core_bfd); } static LONGEST @@ -573,13 +598,11 @@ core_xfer_partial (struct target_ops *ops, enum target_object object, switch (object) { case TARGET_OBJECT_MEMORY: - if (readbuf) - return (*ops->deprecated_xfer_memory) (offset, readbuf, - len, 0/*read*/, NULL, ops); - if (writebuf) - return (*ops->deprecated_xfer_memory) (offset, (gdb_byte *) writebuf, - len, 1/*write*/, NULL, ops); - return -1; + return section_table_xfer_memory_partial (readbuf, writebuf, + offset, len, + core_data->sections, + core_data->sections_end, + NULL); case TARGET_OBJECT_AUXV: if (readbuf) @@ -738,7 +761,6 @@ init_core_ops (void) core_ops.to_detach = core_detach; core_ops.to_fetch_registers = get_core_registers; core_ops.to_xfer_partial = core_xfer_partial; - core_ops.deprecated_xfer_memory = xfer_memory; core_ops.to_files_info = core_files_info; core_ops.to_insert_breakpoint = ignore; core_ops.to_remove_breakpoint = ignore; diff --git a/gdb/exec.c b/gdb/exec.c index 985fbe57129..358992cb881 100644 --- a/gdb/exec.c +++ b/gdb/exec.c @@ -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; diff --git a/gdb/exec.h b/gdb/exec.h index c33faa7c84a..72b385c4b86 100644 --- a/gdb/exec.h +++ b/gdb/exec.h @@ -34,6 +34,11 @@ extern struct target_ops exec_ops; extern int build_section_table (struct bfd *, struct target_section **, struct target_section **); +/* Resize the section table held by TABLE, by NUM_ADDED. Returns the + old size. */ + +extern int resize_section_table (struct target_section_table *, int); + /* Request to transfer up to LEN 8-bit bytes of the target sections defined by SECTIONS and SECTIONS_END. The OFFSET specifies the starting address. @@ -50,9 +55,28 @@ extern int build_section_table (struct bfd *, struct target_section **, extern int section_table_xfer_memory_partial (gdb_byte *, const gdb_byte *, ULONGEST, LONGEST, struct target_section *, - struct target_section *); + struct target_section *, + const char *); /* Set the loaded address of a section. */ extern void exec_set_section_address (const char *, int, CORE_ADDR); +/* Remove all target sections taken from ABFD. */ + +extern void remove_target_sections (bfd *abfd); + +/* Add the sections array defined by [SECTIONS..SECTIONS_END[ to the + current set of target sections. */ + +extern void add_target_sections (struct target_section *sections, + struct target_section *sections_end); + +/* Prints info about all sections defined in the TABLE. ABFD is + special cased --- it's filename is omitted; if it is the executable + file, its entry point is printed. */ + +extern void print_section_info (struct target_section_table *table, + bfd *abfd); + + #endif diff --git a/gdb/gdbcore.h b/gdb/gdbcore.h index 8dda6425433..ec3e1a8a902 100644 --- a/gdb/gdbcore.h +++ b/gdb/gdbcore.h @@ -189,4 +189,6 @@ extern void deprecated_add_core_fns (struct core_fns *cf); extern int default_core_sniffer (struct core_fns *cf, bfd * abfd); extern int default_check_format (bfd * abfd); +struct target_section *deprecated_core_resize_section_table (int num_added); + #endif /* !defined (GDBCORE_H) */ diff --git a/gdb/infrun.c b/gdb/infrun.c index 3540acf9d77..d044772ce09 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -2448,15 +2448,6 @@ handle_inferior_event (struct execution_control_state *ecs) operations such as address => section name and hence require the table to contain all sections (including those found in shared libraries). */ - /* NOTE: cagney/2003-11-25: Pass current_target and not - exec_ops to SOLIB_ADD. This is because current GDB is - only tooled to propagate section_table changes out from - the "current_target" (see target_resize_to_sections), and - not up from the exec stratum. This, of course, isn't - right. "infrun.c" should only interact with the - exec/process stratum, instead relying on the target stack - to propagate relevant changes (stop, section table - changed, ...) up to other layers. */ #ifdef SOLIB_ADD SOLIB_ADD (NULL, 0, ¤t_target, auto_solib_add); #else @@ -3446,15 +3437,6 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (!gdbarch_get_longjmp_target)\n"); operations such as address => section name and hence require the table to contain all sections (including those found in shared libraries). */ - /* NOTE: cagney/2003-11-25: Pass current_target and not - exec_ops to SOLIB_ADD. This is because current GDB is - only tooled to propagate section_table changes out from - the "current_target" (see target_resize_to_sections), and - not up from the exec stratum. This, of course, isn't - right. "infrun.c" should only interact with the - exec/process stratum, instead relying on the target stack - to propagate relevant changes (stop, section table - changed, ...) up to other layers. */ #ifdef SOLIB_ADD SOLIB_ADD (NULL, 0, ¤t_target, auto_solib_add); #else diff --git a/gdb/rs6000-nat.c b/gdb/rs6000-nat.c index c1e3b4756e0..a7866574daa 100644 --- a/gdb/rs6000-nat.c +++ b/gdb/rs6000-nat.c @@ -1160,8 +1160,7 @@ xcoff_relocate_core (struct target_ops *target) { struct target_section *stp; - target_resize_to_sections (target, 2); - stp = target->to_sections_end - 2; + stp = deprecated_core_resize_section_table (2); stp->bfd = vp->bfd; stp->the_bfd_section = bfd_get_section_by_name (stp->bfd, ".text"); diff --git a/gdb/solib.c b/gdb/solib.c index 9eebd488524..a434ececb52 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -661,21 +661,11 @@ update_solib_list (int from_tty, struct target_ops *target) "Error while mapping shared library sections:\n", RETURN_MASK_ALL); - /* If requested, add the shared object's sections to the TARGET's - section table. Do this immediately after mapping the object so - that later nodes in the list can query this object, as is needed - in solib-osf.c. */ - if (target) - { - int count = (i->sections_end - i->sections); - if (count > 0) - { - int space = target_resize_to_sections (target, count); - memcpy (target->to_sections + space, - i->sections, - count * sizeof (i->sections[0])); - } - } + /* Add the shared object's sections to the current set of + file section tables. Do this immediately after mapping + the object so that later nodes in the list can query this + object, as is needed in solib-osf.c. */ + add_target_sections (i->sections, i->sections_end); /* Notify any observer that the shared object has been loaded now that we've added it to GDB's tables. */ diff --git a/gdb/target.c b/gdb/target.c index 6a180f336b4..8de1be8a812 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -41,6 +41,7 @@ #include "target-descriptions.h" #include "gdbthread.h" #include "solib.h" +#include "exec.h" static void target_info (char *, int); @@ -491,8 +492,6 @@ update_current_target (void) INHERIT (to_has_registers, t); INHERIT (to_has_execution, t); INHERIT (to_has_thread_control, t); - INHERIT (to_sections, t); - INHERIT (to_sections_end, t); INHERIT (to_can_async_p, t); INHERIT (to_is_async_p, t); INHERIT (to_async, t); @@ -1016,14 +1015,33 @@ done: return nbytes_read; } +struct target_section_table * +target_get_section_table (struct target_ops *target) +{ + struct target_ops *t; + + if (targetdebug) + fprintf_unfiltered (gdb_stdlog, "target_get_section_table ()\n"); + + for (t = target; t != NULL; t = t->beneath) + if (t->to_get_section_table != NULL) + return (*t->to_get_section_table) (t); + + return NULL; +} + /* Find a section containing ADDR. */ + struct target_section * target_section_by_addr (struct target_ops *target, CORE_ADDR addr) { + struct target_section_table *table = target_get_section_table (target); struct target_section *secp; - for (secp = target->to_sections; - secp < target->to_sections_end; - secp++) + + if (table == NULL) + return NULL; + + for (secp = table->sections; secp < table->sections_end; secp++) { if (addr >= secp->addr && addr < secp->endaddr) return secp; @@ -1046,24 +1064,43 @@ memory_xfer_partial (struct target_ops *ops, void *readbuf, const void *writebuf if (len == 0) return 0; - /* Try the executable file, if "trust-readonly-sections" is set. */ + /* For accesses to unmapped overlay sections, read directly from + files. Must do this first, as MEMADDR may need adjustment. */ + if (readbuf != NULL && overlay_debugging) + { + struct obj_section *section = find_pc_overlay (memaddr); + if (pc_in_unmapped_range (memaddr, section)) + { + struct target_section_table *table + = target_get_section_table (ops); + const char *section_name = section->the_bfd_section->name; + memaddr = overlay_mapped_address (memaddr, section); + return section_table_xfer_memory_partial (readbuf, writebuf, + memaddr, len, + table->sections, + table->sections_end, + section_name); + } + } + + /* Try the executable files, if "trust-readonly-sections" is set. */ if (readbuf != NULL && trust_readonly) { struct target_section *secp; + struct target_section_table *table; secp = target_section_by_addr (ops, memaddr); if (secp != NULL && (bfd_get_section_flags (secp->bfd, secp->the_bfd_section) & SEC_READONLY)) - return xfer_memory (memaddr, readbuf, len, 0, NULL, ops); - } - - /* Likewise for accesses to unmapped overlay sections. */ - if (readbuf != NULL && overlay_debugging) - { - struct obj_section *section = find_pc_overlay (memaddr); - if (pc_in_unmapped_range (memaddr, section)) - return xfer_memory (memaddr, readbuf, len, 0, NULL, ops); + { + table = target_get_section_table (ops); + return section_table_xfer_memory_partial (readbuf, writebuf, + memaddr, len, + table->sections, + table->sections_end, + NULL); + } } /* Try GDB's internal data cache. */ @@ -1688,7 +1725,11 @@ void get_target_memory (struct target_ops *ops, CORE_ADDR addr, gdb_byte *buf, LONGEST len) { - if (target_read (ops, TARGET_OBJECT_MEMORY, NULL, buf, addr, len) + /* This method is used to read from an alternate, non-current + target. This read must bypass the overlay support (as symbols + don't match this target), and GDB's internal cache (wrong cache + for this target). */ + if (target_read (ops, TARGET_OBJECT_RAW_MEMORY, NULL, buf, addr, len) != len) memory_error (EIO, addr); } @@ -2338,96 +2379,6 @@ return_minus_one (void) return -1; } -/* - * Resize the to_sections pointer. Also make sure that anyone that - * was holding on to an old value of it gets updated. - * Returns the old size. - */ - -int -target_resize_to_sections (struct target_ops *target, int num_added) -{ - struct target_ops **t; - struct target_section *old_value; - int old_count; - - old_value = target->to_sections; - - if (target->to_sections) - { - old_count = target->to_sections_end - target->to_sections; - target->to_sections = (struct target_section *) - xrealloc ((char *) target->to_sections, - (sizeof (struct target_section)) * (num_added + old_count)); - } - else - { - old_count = 0; - target->to_sections = (struct target_section *) - xmalloc ((sizeof (struct target_section)) * num_added); - } - target->to_sections_end = target->to_sections + (num_added + old_count); - - /* Check to see if anyone else was pointing to this structure. - If old_value was null, then no one was. */ - - if (old_value) - { - for (t = target_structs; t < target_structs + target_struct_size; - ++t) - { - if ((*t)->to_sections == old_value) - { - (*t)->to_sections = target->to_sections; - (*t)->to_sections_end = target->to_sections_end; - } - } - /* There is a flattened view of the target stack in current_target, - so its to_sections pointer might also need updating. */ - if (current_target.to_sections == old_value) - { - current_target.to_sections = target->to_sections; - current_target.to_sections_end = target->to_sections_end; - } - } - - return old_count; - -} - -/* Remove all target sections taken from ABFD. - - Scan the current target stack for targets whose section tables - refer to sections from BFD, and remove those sections. We use this - when we notice that the inferior has unloaded a shared object, for - example. */ -void -remove_target_sections (bfd *abfd) -{ - struct target_ops **t; - - for (t = target_structs; t < target_structs + target_struct_size; t++) - { - struct target_section *src, *dest; - - dest = (*t)->to_sections; - for (src = (*t)->to_sections; src < (*t)->to_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) - target_resize_to_sections (*t, dest - src); - } -} - - - - /* Find a single runnable target in the stack and return it. If for some reason there is more than one, return NULL. */ diff --git a/gdb/target.h b/gdb/target.h index f3bddfc304e..e4cb35d364b 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -30,6 +30,7 @@ struct mem_attrib; struct target_ops; struct bp_target_info; struct regcache; +struct target_section_table; /* This include file defines the interface between the main part of the debugger, and the part which is target-specific, or @@ -412,6 +413,7 @@ struct target_ops void (*to_rcmd) (char *command, struct ui_file *output); char *(*to_pid_to_exec_file) (int pid); void (*to_log_command) (const char *); + struct target_section_table *(*to_get_section_table) (struct target_ops *); enum strata to_stratum; int to_has_all_memory; int to_has_memory; @@ -420,10 +422,6 @@ struct target_ops int to_has_execution; int to_has_thread_control; /* control thread execution */ int to_attach_no_wait; - struct target_section - *to_sections; - struct target_section - *to_sections_end; /* ASYNC target controls */ int (*to_can_async_p) (void); int (*to_is_async_p) (void); @@ -668,9 +666,6 @@ extern int target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len); extern int target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, int len); -extern int xfer_memory (CORE_ADDR, gdb_byte *, int, int, - struct mem_attrib *, struct target_ops *); - /* Fetches the target's memory map. If one is found it is sorted and returned, after some consistency checking. Otherwise, NULL is returned. */ @@ -733,10 +728,6 @@ extern int inferior_has_vforked (ptid_t pid, ptid_t *child_pid); extern int inferior_has_execd (ptid_t pid, char **execd_pathname); -/* From exec.c */ - -extern void print_section_info (struct target_ops *, bfd *); - /* Print a line about the current target. */ #define target_files_info() \ @@ -1208,10 +1199,24 @@ struct target_section bfd *bfd; /* BFD file pointer */ }; +/* Holds an array of target sections. Defined by [SECTIONS..SECTIONS_END[. */ + +struct target_section_table +{ + struct target_section *sections; + struct target_section *sections_end; +}; + /* Return the "section" containing the specified address. */ struct target_section *target_section_by_addr (struct target_ops *target, CORE_ADDR addr); +/* Return the target section table this target (or the targets + beneath) currently manipulate. */ + +extern struct target_section_table *target_get_section_table + (struct target_ops *target); + /* From mem-break.c */ extern int memory_remove_breakpoint (struct bp_target_info *); @@ -1242,11 +1247,6 @@ extern struct target_ops *find_core_target (void); extern struct target_ops *find_target_beneath (struct target_ops *); -extern int target_resize_to_sections (struct target_ops *target, - int num_added); - -extern void remove_target_sections (bfd *abfd); - /* Read OS data object of type TYPE from the target, and return it in XML format. The result is NUL-terminated and returned as a string, allocated using xmalloc. If an error occurs or the transfer is -- 2.30.2