* 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.
This commit is contained in:
Pedro Alves 2009-06-03 18:50:36 +00:00
parent 4fa6249465
commit 07b82ea5f9
11 changed files with 433 additions and 290 deletions

View file

@ -1,3 +1,83 @@
2009-06-03 Pedro Alves <pedro@codesourcery.com>
* 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.
2009-06-03 Ulrich Weigand <uweigand@de.ibm.com>
* value.h (struct internalvar): Remove.

View file

@ -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;
}

View file

@ -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;

View file

@ -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
= &current_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, &sections, &sections_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;
struct target_section_table *table = target_get_section_table (ops);
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);
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;

View file

@ -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

View file

@ -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) */

View file

@ -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, &current_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, &current_target, auto_solib_add);
#else

View file

@ -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");

View file

@ -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. */

View file

@ -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. */

View file

@ -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