diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 17 | ||||
-rw-r--r-- | gdb/bfd-target.c | 80 | ||||
-rw-r--r-- | gdb/bfd-target.h | 6 | ||||
-rw-r--r-- | gdb/exec.c | 100 | ||||
-rw-r--r-- | gdb/exec.h | 18 |
5 files changed, 121 insertions, 100 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6aff604..8b55328 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,22 @@ 2009-05-22 Pedro Alves <pedro@codesourcery.com> + * bfd-target.c: Don't include gdb_assert.h or gdb_string.h. + Include exec.h. + (struct section_closure): Delete. + (add_to_section_table): Delete. + (build_target_sections_from_bfd): Delete. + (target_bfd_xfer_partial): Use section_table_xfer_memory_partial. + (target_bfd_reopen): Use build_section_table. + * exec.c (xfer_memory): Move most code except for overlay + debugging support from here... + (section_table_xfer_memory): ... to this new function. + (section_table_xfer_memory_partial): New. + * exec.h (section_table_xfer_memory_partial): Declare. + * bfd-target.h (build_target_sections_from_bfd): Delete + declaration. + +2009-05-22 Pedro Alves <pedro@codesourcery.com> + * remote.c (compare_sections_command): Don't declare exec_bfd. * tracepoint.c: Include "gdbcore.h". (remote_set_transparent_ranges): Don't declare exec_bfd. diff --git a/gdb/bfd-target.c b/gdb/bfd-target.c index 5ce9e19..3eaae84 100644 --- a/gdb/bfd-target.c +++ b/gdb/bfd-target.c @@ -20,51 +20,7 @@ #include "defs.h" #include "target.h" #include "bfd-target.h" -#include "gdb_assert.h" -#include "gdb_string.h" - -/* Locate all mappable sections of a BFD file, filling in a target - section for each. */ - -struct section_closure -{ - struct section_table *end; -}; - -static void -add_to_section_table (struct bfd *abfd, struct bfd_section *asect, - void *closure) -{ - struct section_closure *pp = closure; - flagword aflag; - - /* NOTE: cagney/2003-10-22: Is this pruning useful? */ - aflag = bfd_get_section_flags (abfd, asect); - if (!(aflag & SEC_ALLOC)) - return; - if (bfd_section_size (abfd, asect) == 0) - return; - pp->end->bfd = abfd; - pp->end->the_bfd_section = asect; - pp->end->addr = bfd_section_vma (abfd, asect); - pp->end->endaddr = pp->end->addr + bfd_section_size (abfd, asect); - pp->end++; -} - -void -build_target_sections_from_bfd (struct target_ops *targ, struct bfd *abfd) -{ - unsigned count; - struct section_table *start; - struct section_closure cl; - - count = bfd_count_sections (abfd); - target_resize_to_sections (targ, count); - start = targ->to_sections; - cl.end = targ->to_sections; - bfd_map_over_sections (abfd, add_to_section_table, &cl); - gdb_assert (cl.end - start <= count); -} +#include "exec.h" static LONGEST target_bfd_xfer_partial (struct target_ops *ops, @@ -76,32 +32,9 @@ target_bfd_xfer_partial (struct target_ops *ops, switch (object) { case TARGET_OBJECT_MEMORY: - { - struct section_table *s = target_section_by_addr (ops, offset); - if (s == NULL) - return -1; - /* If the length extends beyond the section, truncate it. Be - careful to not suffer from overflow (wish S contained a - length). */ - if ((offset - s->addr + len) > (s->endaddr - s->addr)) - len = (s->endaddr - s->addr) - (offset - s->addr); - if (readbuf != NULL - && !bfd_get_section_contents (s->bfd, s->the_bfd_section, - readbuf, offset - s->addr, len)) - return -1; -#if 1 - if (writebuf != NULL) - return -1; -#else - /* FIXME: cagney/2003-10-31: The BFD interface doesn't yet - take a const buffer. */ - if (writebuf != NULL - && !bfd_set_section_contents (s->bfd, s->the_bfd_section, - writebuf, offset - s->addr, len)) - return -1; -#endif - return len; - } + return section_table_xfer_memory_partial (readbuf, writebuf, offset, len, + ops->to_sections, + ops->to_sections_end); default: return -1; } @@ -125,6 +58,9 @@ target_bfd_reopen (struct bfd *bfd) t->to_xfer_partial = target_bfd_xfer_partial; t->to_xclose = target_bfd_xclose; t->to_data = bfd; - build_target_sections_from_bfd (t, bfd); + + build_section_table (bfd, + &t->to_sections, + &t->to_sections_end); return t; } diff --git a/gdb/bfd-target.h b/gdb/bfd-target.h index 3bacdfd..03931d7 100644 --- a/gdb/bfd-target.h +++ b/gdb/bfd-target.h @@ -28,10 +28,4 @@ struct target_ops; freopen and fdopen). */ struct target_ops *target_bfd_reopen (struct bfd *bfd); -/* Map over ABFD's sections, creating corresponding entries in the - target's section table. */ - -void build_target_sections_from_bfd (struct target_ops *targ, - struct bfd *abfd); - #endif @@ -446,10 +446,16 @@ map_vmap (bfd *abfd, bfd *arch) return vp; } -/* Read or write the exec file. +/* Read or write from BFD executable files. - Args are address within a BFD file, address within gdb address-space, - length, and a flag indicating whether to read or write. + MEMADDR is an address within the target address space, MYADDR is an + address within GDB address-space where data is written to, LEN is + length of buffer, and WRITE indicates whether to read or write. + SECTIONS and SECTIONS_END defines a section table holding sections + from possibly multiple BFDs. + + If SECTION_NAME is not NULL, only access sections with that same + name. Result is a length: @@ -459,38 +465,28 @@ map_vmap (bfd *abfd, bfd *arch) 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. */ + else handles (-N) bytes, we can start from there. */ -int -xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write, - struct mem_attrib *attrib, struct target_ops *target) +static int +section_table_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, + int len, int write, + struct section_table *sections, + struct section_table *sections_end, + const char *section_name) { int res; struct section_table *p; CORE_ADDR nextsectaddr, memend; - struct obj_section *section = NULL; if (len <= 0) internal_error (__FILE__, __LINE__, _("failed internal consistency check")); - if (overlay_debugging) - { - section = find_pc_overlay (memaddr); - if (pc_in_unmapped_range (memaddr, section)) - memaddr = overlay_mapped_address (memaddr, section); - } - memend = memaddr + len; nextsectaddr = memend; - for (p = target->to_sections; p < target->to_sections_end; p++) + for (p = sections; p < sections_end; p++) { - if (overlay_debugging && section - && strcmp (section->the_bfd_section->name, - p->the_bfd_section->name) != 0) + if (section_name && strcmp (section_name, p->the_bfd_section->name) != 0) continue; /* not the section we need */ if (memaddr >= p->addr) { @@ -536,6 +532,66 @@ xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write, else return -(nextsectaddr - memaddr); /* Next boundary where we can help */ } + +int +section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf, + ULONGEST offset, LONGEST len, + struct section_table *sections, + struct section_table *sections_end) +{ + 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); +} + +/* 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) +{ + 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); +} void @@ -34,6 +34,24 @@ extern struct target_ops exec_ops; extern int build_section_table (struct bfd *, struct section_table **, struct section_table **); +/* 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. + + Return the number of bytes actually transfered, or non-positive + when no data is available for the requested range. + + This function is intended to be used from target_xfer_partial + implementations. See target_read and target_write for more + information. + + One, and only one, of readbuf or writebuf must be non-NULL. */ + +extern int section_table_xfer_memory_partial (gdb_byte *, const gdb_byte *, + ULONGEST, LONGEST, + struct section_table *, + struct section_table *); + /* Set the loaded address of a section. */ extern void exec_set_section_address (const char *, int, CORE_ADDR); |