* 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:
parent
6432734d1d
commit
35c2fab7c6
|
@ -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>
|
||||
|
||||
* gdbarch.sh (make_corefile_notes): New architecture callback.
|
||||
|
|
|
@ -561,8 +561,14 @@ gcore_copy_callback (bfd *obfd, asection *osec, void *ignored)
|
|||
static int
|
||||
gcore_memory_sections (bfd *obfd)
|
||||
{
|
||||
/* Try gdbarch method first, then fall back to target method. */
|
||||
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. */
|
||||
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;
|
||||
struct core_regset_section * core_regset_sections;
|
||||
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_pid_to_str_ftype *core_pid_to_str;
|
||||
const char * gcore_bfd_target;
|
||||
|
@ -397,6 +398,7 @@ struct gdbarch startup_gdbarch =
|
|||
0, /* regset_from_core_section */
|
||||
0, /* core_regset_sections */
|
||||
0, /* make_corefile_notes */
|
||||
0, /* find_memory_regions */
|
||||
0, /* core_xfer_shared_libraries */
|
||||
0, /* core_pid_to_str */
|
||||
0, /* gcore_bfd_target */
|
||||
|
@ -686,6 +688,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
|
|||
/* Skip verify of fetch_pointer_argument, has predicate. */
|
||||
/* Skip verify of regset_from_core_section, 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_pid_to_str, 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,
|
||||
"gdbarch_dump: fetch_tls_load_module_address = <%s>\n",
|
||||
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,
|
||||
"gdbarch_dump: float_bit = %s\n",
|
||||
plongest (gdbarch->float_bit));
|
||||
|
@ -3277,6 +3286,30 @@ set_gdbarch_make_corefile_notes (struct gdbarch *gdbarch,
|
|||
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
|
||||
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 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
|
||||
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
|
||||
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
|
||||
# core file into buffer READBUF with length 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;
|
||||
}
|
||||
|
||||
/* 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
|
||||
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_attach = linux_child_post_attach;
|
||||
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;
|
||||
|
||||
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. */
|
||||
|
||||
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_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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue