mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-06 14:49:38 +08:00
* gdbarch.sh (find_memory_regions): New callback.
* gdbarch.c, gdbarch.h: Regenerate. * gcore.c (gcore_memory_sections): Try gdbarch find_memory_regions callback before falling back to target method. * linux-nat.c (read_mapping, linux_nat_find_memory_regions): Remove. (linux_target_install_ops): No longer install it. * linux-tdep.c (linux_find_memory_regions): New function. (linux_init_abi): Install it.
This commit is contained in:
@ -1,3 +1,17 @@
|
|||||||
|
2012-01-20 Ulrich Weigand <ulrich.weigand@linaro.org>
|
||||||
|
|
||||||
|
* gdbarch.sh (find_memory_regions): New callback.
|
||||||
|
* gdbarch.c, gdbarch.h: Regenerate.
|
||||||
|
|
||||||
|
* gcore.c (gcore_memory_sections): Try gdbarch find_memory_regions
|
||||||
|
callback before falling back to target method.
|
||||||
|
|
||||||
|
* linux-nat.c (read_mapping, linux_nat_find_memory_regions): Remove.
|
||||||
|
(linux_target_install_ops): No longer install it.
|
||||||
|
|
||||||
|
* linux-tdep.c (linux_find_memory_regions): New function.
|
||||||
|
(linux_init_abi): Install it.
|
||||||
|
|
||||||
2012-01-20 Ulrich Weigand <ulrich.weigand@linaro.org>
|
2012-01-20 Ulrich Weigand <ulrich.weigand@linaro.org>
|
||||||
|
|
||||||
* gdbarch.sh (make_corefile_notes): New architecture callback.
|
* gdbarch.sh (make_corefile_notes): New architecture callback.
|
||||||
|
10
gdb/gcore.c
10
gdb/gcore.c
@ -561,8 +561,14 @@ gcore_copy_callback (bfd *obfd, asection *osec, void *ignored)
|
|||||||
static int
|
static int
|
||||||
gcore_memory_sections (bfd *obfd)
|
gcore_memory_sections (bfd *obfd)
|
||||||
{
|
{
|
||||||
if (target_find_memory_regions (gcore_create_callback, obfd) != 0)
|
/* Try gdbarch method first, then fall back to target method. */
|
||||||
return 0; /* FIXME: error return/msg? */
|
if (!gdbarch_find_memory_regions_p (target_gdbarch)
|
||||||
|
|| gdbarch_find_memory_regions (target_gdbarch,
|
||||||
|
gcore_create_callback, obfd) != 0)
|
||||||
|
{
|
||||||
|
if (target_find_memory_regions (gcore_create_callback, obfd) != 0)
|
||||||
|
return 0; /* FIXME: error return/msg? */
|
||||||
|
}
|
||||||
|
|
||||||
/* Record phdrs for section-to-segment mapping. */
|
/* Record phdrs for section-to-segment mapping. */
|
||||||
bfd_map_over_sections (obfd, make_output_phdrs, NULL);
|
bfd_map_over_sections (obfd, make_output_phdrs, NULL);
|
||||||
|
@ -240,6 +240,7 @@ struct gdbarch
|
|||||||
gdbarch_regset_from_core_section_ftype *regset_from_core_section;
|
gdbarch_regset_from_core_section_ftype *regset_from_core_section;
|
||||||
struct core_regset_section * core_regset_sections;
|
struct core_regset_section * core_regset_sections;
|
||||||
gdbarch_make_corefile_notes_ftype *make_corefile_notes;
|
gdbarch_make_corefile_notes_ftype *make_corefile_notes;
|
||||||
|
gdbarch_find_memory_regions_ftype *find_memory_regions;
|
||||||
gdbarch_core_xfer_shared_libraries_ftype *core_xfer_shared_libraries;
|
gdbarch_core_xfer_shared_libraries_ftype *core_xfer_shared_libraries;
|
||||||
gdbarch_core_pid_to_str_ftype *core_pid_to_str;
|
gdbarch_core_pid_to_str_ftype *core_pid_to_str;
|
||||||
const char * gcore_bfd_target;
|
const char * gcore_bfd_target;
|
||||||
@ -397,6 +398,7 @@ struct gdbarch startup_gdbarch =
|
|||||||
0, /* regset_from_core_section */
|
0, /* regset_from_core_section */
|
||||||
0, /* core_regset_sections */
|
0, /* core_regset_sections */
|
||||||
0, /* make_corefile_notes */
|
0, /* make_corefile_notes */
|
||||||
|
0, /* find_memory_regions */
|
||||||
0, /* core_xfer_shared_libraries */
|
0, /* core_xfer_shared_libraries */
|
||||||
0, /* core_pid_to_str */
|
0, /* core_pid_to_str */
|
||||||
0, /* gcore_bfd_target */
|
0, /* gcore_bfd_target */
|
||||||
@ -686,6 +688,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
|||||||
/* Skip verify of fetch_pointer_argument, has predicate. */
|
/* Skip verify of fetch_pointer_argument, has predicate. */
|
||||||
/* Skip verify of regset_from_core_section, has predicate. */
|
/* Skip verify of regset_from_core_section, has predicate. */
|
||||||
/* Skip verify of make_corefile_notes, has predicate. */
|
/* Skip verify of make_corefile_notes, has predicate. */
|
||||||
|
/* Skip verify of find_memory_regions, has predicate. */
|
||||||
/* Skip verify of core_xfer_shared_libraries, has predicate. */
|
/* Skip verify of core_xfer_shared_libraries, has predicate. */
|
||||||
/* Skip verify of core_pid_to_str, has predicate. */
|
/* Skip verify of core_pid_to_str, has predicate. */
|
||||||
/* Skip verify of gcore_bfd_target, has predicate. */
|
/* Skip verify of gcore_bfd_target, has predicate. */
|
||||||
@ -927,6 +930,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
|
|||||||
fprintf_unfiltered (file,
|
fprintf_unfiltered (file,
|
||||||
"gdbarch_dump: fetch_tls_load_module_address = <%s>\n",
|
"gdbarch_dump: fetch_tls_load_module_address = <%s>\n",
|
||||||
host_address_to_string (gdbarch->fetch_tls_load_module_address));
|
host_address_to_string (gdbarch->fetch_tls_load_module_address));
|
||||||
|
fprintf_unfiltered (file,
|
||||||
|
"gdbarch_dump: gdbarch_find_memory_regions_p() = %d\n",
|
||||||
|
gdbarch_find_memory_regions_p (gdbarch));
|
||||||
|
fprintf_unfiltered (file,
|
||||||
|
"gdbarch_dump: find_memory_regions = <%s>\n",
|
||||||
|
host_address_to_string (gdbarch->find_memory_regions));
|
||||||
fprintf_unfiltered (file,
|
fprintf_unfiltered (file,
|
||||||
"gdbarch_dump: float_bit = %s\n",
|
"gdbarch_dump: float_bit = %s\n",
|
||||||
plongest (gdbarch->float_bit));
|
plongest (gdbarch->float_bit));
|
||||||
@ -3277,6 +3286,30 @@ set_gdbarch_make_corefile_notes (struct gdbarch *gdbarch,
|
|||||||
gdbarch->make_corefile_notes = make_corefile_notes;
|
gdbarch->make_corefile_notes = make_corefile_notes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gdbarch_find_memory_regions_p (struct gdbarch *gdbarch)
|
||||||
|
{
|
||||||
|
gdb_assert (gdbarch != NULL);
|
||||||
|
return gdbarch->find_memory_regions != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gdbarch_find_memory_regions (struct gdbarch *gdbarch, find_memory_region_ftype func, void *data)
|
||||||
|
{
|
||||||
|
gdb_assert (gdbarch != NULL);
|
||||||
|
gdb_assert (gdbarch->find_memory_regions != NULL);
|
||||||
|
if (gdbarch_debug >= 2)
|
||||||
|
fprintf_unfiltered (gdb_stdlog, "gdbarch_find_memory_regions called\n");
|
||||||
|
return gdbarch->find_memory_regions (gdbarch, func, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
set_gdbarch_find_memory_regions (struct gdbarch *gdbarch,
|
||||||
|
gdbarch_find_memory_regions_ftype find_memory_regions)
|
||||||
|
{
|
||||||
|
gdbarch->find_memory_regions = find_memory_regions;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
gdbarch_core_xfer_shared_libraries_p (struct gdbarch *gdbarch)
|
gdbarch_core_xfer_shared_libraries_p (struct gdbarch *gdbarch)
|
||||||
{
|
{
|
||||||
|
@ -717,6 +717,14 @@ typedef char * (gdbarch_make_corefile_notes_ftype) (struct gdbarch *gdbarch, bfd
|
|||||||
extern char * gdbarch_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size);
|
extern char * gdbarch_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size);
|
||||||
extern void set_gdbarch_make_corefile_notes (struct gdbarch *gdbarch, gdbarch_make_corefile_notes_ftype *make_corefile_notes);
|
extern void set_gdbarch_make_corefile_notes (struct gdbarch *gdbarch, gdbarch_make_corefile_notes_ftype *make_corefile_notes);
|
||||||
|
|
||||||
|
/* Find core file memory regions */
|
||||||
|
|
||||||
|
extern int gdbarch_find_memory_regions_p (struct gdbarch *gdbarch);
|
||||||
|
|
||||||
|
typedef int (gdbarch_find_memory_regions_ftype) (struct gdbarch *gdbarch, find_memory_region_ftype func, void *data);
|
||||||
|
extern int gdbarch_find_memory_regions (struct gdbarch *gdbarch, find_memory_region_ftype func, void *data);
|
||||||
|
extern void set_gdbarch_find_memory_regions (struct gdbarch *gdbarch, gdbarch_find_memory_regions_ftype *find_memory_regions);
|
||||||
|
|
||||||
/* Read offset OFFSET of TARGET_OBJECT_LIBRARIES formatted shared libraries list from
|
/* Read offset OFFSET of TARGET_OBJECT_LIBRARIES formatted shared libraries list from
|
||||||
core file into buffer READBUF with length LEN. */
|
core file into buffer READBUF with length LEN. */
|
||||||
|
|
||||||
|
@ -634,6 +634,9 @@ v:struct core_regset_section *:core_regset_sections:const char *name, int len:::
|
|||||||
# Create core file notes
|
# Create core file notes
|
||||||
M:char *:make_corefile_notes:bfd *obfd, int *note_size:obfd, note_size
|
M:char *:make_corefile_notes:bfd *obfd, int *note_size:obfd, note_size
|
||||||
|
|
||||||
|
# Find core file memory regions
|
||||||
|
M:int:find_memory_regions:find_memory_region_ftype func, void *data:func, data
|
||||||
|
|
||||||
# Read offset OFFSET of TARGET_OBJECT_LIBRARIES formatted shared libraries list from
|
# Read offset OFFSET of TARGET_OBJECT_LIBRARIES formatted shared libraries list from
|
||||||
# core file into buffer READBUF with length LEN.
|
# core file into buffer READBUF with length LEN.
|
||||||
M:LONGEST:core_xfer_shared_libraries:gdb_byte *readbuf, ULONGEST offset, LONGEST len:readbuf, offset, len
|
M:LONGEST:core_xfer_shared_libraries:gdb_byte *readbuf, ULONGEST offset, LONGEST len:readbuf, offset, len
|
||||||
|
@ -4396,90 +4396,6 @@ linux_child_pid_to_exec_file (int pid)
|
|||||||
return name1;
|
return name1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Service function for corefiles and info proc. */
|
|
||||||
|
|
||||||
static int
|
|
||||||
read_mapping (FILE *mapfile,
|
|
||||||
long long *addr,
|
|
||||||
long long *endaddr,
|
|
||||||
char *permissions,
|
|
||||||
long long *offset,
|
|
||||||
char *device, long long *inode, char *filename)
|
|
||||||
{
|
|
||||||
int ret = fscanf (mapfile, "%llx-%llx %s %llx %s %llx",
|
|
||||||
addr, endaddr, permissions, offset, device, inode);
|
|
||||||
|
|
||||||
filename[0] = '\0';
|
|
||||||
if (ret > 0 && ret != EOF)
|
|
||||||
{
|
|
||||||
/* Eat everything up to EOL for the filename. This will prevent
|
|
||||||
weird filenames (such as one with embedded whitespace) from
|
|
||||||
confusing this code. It also makes this code more robust in
|
|
||||||
respect to annotations the kernel may add after the filename.
|
|
||||||
|
|
||||||
Note the filename is used for informational purposes
|
|
||||||
only. */
|
|
||||||
ret += fscanf (mapfile, "%[^\n]\n", filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (ret != 0 && ret != EOF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fills the "to_find_memory_regions" target vector. Lists the memory
|
|
||||||
regions in the inferior for a corefile. */
|
|
||||||
|
|
||||||
static int
|
|
||||||
linux_nat_find_memory_regions (find_memory_region_ftype func, void *obfd)
|
|
||||||
{
|
|
||||||
int pid = PIDGET (inferior_ptid);
|
|
||||||
char mapsfilename[MAXPATHLEN];
|
|
||||||
FILE *mapsfile;
|
|
||||||
long long addr, endaddr, size, offset, inode;
|
|
||||||
char permissions[8], device[8], filename[MAXPATHLEN];
|
|
||||||
int read, write, exec;
|
|
||||||
struct cleanup *cleanup;
|
|
||||||
|
|
||||||
/* Compose the filename for the /proc memory map, and open it. */
|
|
||||||
sprintf (mapsfilename, "/proc/%d/maps", pid);
|
|
||||||
if ((mapsfile = fopen (mapsfilename, "r")) == NULL)
|
|
||||||
error (_("Could not open %s."), mapsfilename);
|
|
||||||
cleanup = make_cleanup_fclose (mapsfile);
|
|
||||||
|
|
||||||
if (info_verbose)
|
|
||||||
fprintf_filtered (gdb_stdout,
|
|
||||||
"Reading memory regions from %s\n", mapsfilename);
|
|
||||||
|
|
||||||
/* Now iterate until end-of-file. */
|
|
||||||
while (read_mapping (mapsfile, &addr, &endaddr, &permissions[0],
|
|
||||||
&offset, &device[0], &inode, &filename[0]))
|
|
||||||
{
|
|
||||||
size = endaddr - addr;
|
|
||||||
|
|
||||||
/* Get the segment's permissions. */
|
|
||||||
read = (strchr (permissions, 'r') != 0);
|
|
||||||
write = (strchr (permissions, 'w') != 0);
|
|
||||||
exec = (strchr (permissions, 'x') != 0);
|
|
||||||
|
|
||||||
if (info_verbose)
|
|
||||||
{
|
|
||||||
fprintf_filtered (gdb_stdout,
|
|
||||||
"Save segment, %s bytes at %s (%c%c%c)",
|
|
||||||
plongest (size), paddress (target_gdbarch, addr),
|
|
||||||
read ? 'r' : ' ',
|
|
||||||
write ? 'w' : ' ', exec ? 'x' : ' ');
|
|
||||||
if (filename[0])
|
|
||||||
fprintf_filtered (gdb_stdout, " for %s", filename);
|
|
||||||
fprintf_filtered (gdb_stdout, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Invoke the callback function to create the corefile
|
|
||||||
segment. */
|
|
||||||
func (addr, size, read, write, exec, obfd);
|
|
||||||
}
|
|
||||||
do_cleanups (cleanup);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Records the thread's register state for the corefile note
|
/* Records the thread's register state for the corefile note
|
||||||
section. */
|
section. */
|
||||||
|
|
||||||
@ -4827,7 +4743,6 @@ linux_target_install_ops (struct target_ops *t)
|
|||||||
t->to_post_startup_inferior = linux_child_post_startup_inferior;
|
t->to_post_startup_inferior = linux_child_post_startup_inferior;
|
||||||
t->to_post_attach = linux_child_post_attach;
|
t->to_post_attach = linux_child_post_attach;
|
||||||
t->to_follow_fork = linux_child_follow_fork;
|
t->to_follow_fork = linux_child_follow_fork;
|
||||||
t->to_find_memory_regions = linux_nat_find_memory_regions;
|
|
||||||
t->to_make_corefile_notes = linux_nat_make_corefile_notes;
|
t->to_make_corefile_notes = linux_nat_make_corefile_notes;
|
||||||
|
|
||||||
super_xfer_partial = t->to_xfer_partial;
|
super_xfer_partial = t->to_xfer_partial;
|
||||||
|
@ -530,6 +530,53 @@ linux_info_proc (struct gdbarch *gdbarch, char *args,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* List memory regions in the inferior for a corefile. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
linux_find_memory_regions (struct gdbarch *gdbarch,
|
||||||
|
find_memory_region_ftype func, void *obfd)
|
||||||
|
{
|
||||||
|
char filename[100];
|
||||||
|
gdb_byte *data;
|
||||||
|
|
||||||
|
/* We need to know the real target PID to access /proc. */
|
||||||
|
if (current_inferior ()->fake_pid_p)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
xsnprintf (filename, sizeof filename,
|
||||||
|
"/proc/%d/maps", current_inferior ()->pid);
|
||||||
|
data = target_fileio_read_stralloc (filename);
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
struct cleanup *cleanup = make_cleanup (xfree, data);
|
||||||
|
char *line;
|
||||||
|
|
||||||
|
for (line = strtok (data, "\n"); line; line = strtok (NULL, "\n"))
|
||||||
|
{
|
||||||
|
ULONGEST addr, endaddr, offset, inode;
|
||||||
|
const char *permissions, *device, *filename;
|
||||||
|
size_t permissions_len, device_len;
|
||||||
|
int read, write, exec;
|
||||||
|
|
||||||
|
read_mapping (line, &addr, &endaddr, &permissions, &permissions_len,
|
||||||
|
&offset, &device, &device_len, &inode, &filename);
|
||||||
|
|
||||||
|
/* Decode permissions. */
|
||||||
|
read = (memchr (permissions, 'r', permissions_len) != 0);
|
||||||
|
write = (memchr (permissions, 'w', permissions_len) != 0);
|
||||||
|
exec = (memchr (permissions, 'x', permissions_len) != 0);
|
||||||
|
|
||||||
|
/* Invoke the callback function to create the corefile segment. */
|
||||||
|
func (addr, endaddr - addr, read, write, exec, obfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
do_cleanups (cleanup);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Determine which signal stopped execution. */
|
/* Determine which signal stopped execution. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -807,6 +854,7 @@ linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
|||||||
{
|
{
|
||||||
set_gdbarch_core_pid_to_str (gdbarch, linux_core_pid_to_str);
|
set_gdbarch_core_pid_to_str (gdbarch, linux_core_pid_to_str);
|
||||||
set_gdbarch_info_proc (gdbarch, linux_info_proc);
|
set_gdbarch_info_proc (gdbarch, linux_info_proc);
|
||||||
|
set_gdbarch_find_memory_regions (gdbarch, linux_find_memory_regions);
|
||||||
set_gdbarch_make_corefile_notes (gdbarch, linux_make_corefile_notes_1);
|
set_gdbarch_make_corefile_notes (gdbarch, linux_make_corefile_notes_1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user