* 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.
This commit is contained in:
parent
415756309f
commit
348f8c02f4
5 changed files with 121 additions and 100 deletions
|
@ -1,3 +1,20 @@
|
|||
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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
100
gdb/exec.c
100
gdb/exec.c
|
@ -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.
|
||||
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 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
|
||||
|
|
18
gdb/exec.h
18
gdb/exec.h
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue