* 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

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