2001-12-28 Michael Snyder <msnyder@redhat.com>
Abstract the functionality of iterating over mapped memory regions into a general purpose iterator function. * procfs.c (iterate_over_mappings): New function, general purpose iterator for memory sections. (proc_iterate_over_mappings): Reimplement using iterate_over_mappings. (solib_mappings_callback): New function, callback for above. (info_proc_mappings): Reimpliment using iterate_over_mappings. (info_mappings_callback): New function, callback for above. * procfs.c (proc_set_watchpoint): Add cast to suppress warning.
This commit is contained in:
parent
51c5503ba7
commit
831e682efe
2 changed files with 212 additions and 177 deletions
|
@ -27,13 +27,6 @@
|
|||
* ppc-tdep.h (struct gdbarch_tdep): Add altivec regnum fields.
|
||||
(altivec_register_p): Export.
|
||||
|
||||
2001-12-29 Mark Kettenis <kettenis@gnu.org>
|
||||
|
||||
* i386bsd-nat.c (reg_offset): Fix typo.
|
||||
|
||||
* i386-tdep.c (i386_push_dummy_frame): Don't write back the
|
||||
modified frame pointer until the old frame pointer has been saved.
|
||||
|
||||
2001-12-30 Andrew Cagney <ac131313@redhat.com>
|
||||
|
||||
* arch-utils.c (initialize_current_architecture): Test byte_order
|
||||
|
@ -44,6 +37,26 @@
|
|||
BFD_ENDIAN_UNKNOWN.
|
||||
* gdbarch.h, gdbarch.c: Re-generate.
|
||||
|
||||
2001-12-29 Mark Kettenis <kettenis@gnu.org>
|
||||
|
||||
* i386bsd-nat.c (reg_offset): Fix typo.
|
||||
|
||||
* i386-tdep.c (i386_push_dummy_frame): Don't write back the
|
||||
modified frame pointer until the old frame pointer has been saved.
|
||||
|
||||
2001-12-28 Michael Snyder <msnyder@redhat.com>
|
||||
|
||||
Abstract the functionality of iterating over mapped memory
|
||||
regions into a general purpose iterator function.
|
||||
* procfs.c (iterate_over_mappings): New function, general purpose
|
||||
iterator for memory sections.
|
||||
(proc_iterate_over_mappings): Reimplement using iterate_over_mappings.
|
||||
(solib_mappings_callback): New function, callback for above.
|
||||
(info_proc_mappings): Reimpliment using iterate_over_mappings.
|
||||
(info_mappings_callback): New function, callback for above.
|
||||
|
||||
* procfs.c (proc_set_watchpoint): Add cast to suppress warning.
|
||||
|
||||
2001-12-27 Michael Snyder <msnyder@redhat.com>
|
||||
|
||||
* i386-linux-nat.c: Include i386-tdep.h.
|
||||
|
|
362
gdb/procfs.c
362
gdb/procfs.c
|
@ -2848,7 +2848,11 @@ proc_set_watchpoint (procinfo *pi, CORE_ADDR addr, int len, int wflags)
|
|||
prwatch_t *pwatch;
|
||||
|
||||
pwatch = (prwatch_t *) &arg.watch;
|
||||
pwatch->pr_vaddr = address_to_host_pointer (addr);
|
||||
#ifdef PCAGENT /* Horrible hack: only defined on Solaris 2.6+ */
|
||||
pwatch->pr_vaddr = (uintptr_t) address_to_host_pointer (addr);
|
||||
#else
|
||||
pwatch->pr_vaddr = (caddr_t) address_to_host_pointer (addr);
|
||||
#endif
|
||||
pwatch->pr_size = len;
|
||||
pwatch->pr_wflags = wflags;
|
||||
#if defined(NEW_PROC_API) && defined (PCWATCH)
|
||||
|
@ -2865,115 +2869,6 @@ proc_set_watchpoint (procinfo *pi, CORE_ADDR addr, int len, int wflags)
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: proc_iterate_over_mappings
|
||||
*
|
||||
* Given a pointer to a function, call that function once for every
|
||||
* mapped address space in the process. The callback function
|
||||
* receives an open file descriptor for the file corresponding to
|
||||
* that mapped address space (if there is one), and the base address
|
||||
* of the mapped space. Quit when the callback function returns a
|
||||
* nonzero value, or at teh end of the mappings.
|
||||
*
|
||||
* Returns: the first non-zero return value of the callback function,
|
||||
* or zero.
|
||||
*/
|
||||
|
||||
int
|
||||
proc_iterate_over_mappings (int (*func) (int, CORE_ADDR))
|
||||
{
|
||||
struct prmap *map;
|
||||
procinfo *pi;
|
||||
#ifndef NEW_PROC_API /* avoid compiler warning */
|
||||
int nmaps = 0;
|
||||
int i;
|
||||
#else
|
||||
int map_fd;
|
||||
char pathname[MAX_PROC_NAME_SIZE];
|
||||
#endif
|
||||
int funcstat = 0;
|
||||
int fd;
|
||||
|
||||
pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
|
||||
|
||||
#ifdef NEW_PROC_API
|
||||
/* Open map fd. */
|
||||
sprintf (pathname, "/proc/%d/map", pi->pid);
|
||||
if ((map_fd = open_with_retry (pathname, O_RDONLY)) < 0)
|
||||
proc_error (pi, "proc_iterate_over_mappings (open)", __LINE__);
|
||||
|
||||
/* Make sure it gets closed again. */
|
||||
make_cleanup_close (map_fd);
|
||||
|
||||
/* Allocate space for mapping (lifetime only for this function). */
|
||||
map = alloca (sizeof (struct prmap));
|
||||
|
||||
/* Now read the mappings from the file,
|
||||
open a file descriptor for those that have a name,
|
||||
and call the callback function. */
|
||||
while (read (map_fd,
|
||||
(void *) map,
|
||||
sizeof (struct prmap)) == sizeof (struct prmap))
|
||||
{
|
||||
char name[MAX_PROC_NAME_SIZE + sizeof (map->pr_mapname)];
|
||||
|
||||
if (map->pr_vaddr == 0 && map->pr_size == 0)
|
||||
break; /* sanity */
|
||||
|
||||
if (map->pr_mapname[0] == 0)
|
||||
{
|
||||
fd = -1; /* no map file */
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (name, "/proc/%d/object/%s", pi->pid, map->pr_mapname);
|
||||
/* Note: caller's responsibility to close this fd! */
|
||||
fd = open_with_retry (name, O_RDONLY);
|
||||
/* Note: we don't test the above call for failure;
|
||||
we just pass the FD on as given. Sometimes there is
|
||||
no file, so the ioctl may return failure, but that's
|
||||
not a problem. */
|
||||
}
|
||||
|
||||
/* Stop looping if the callback returns non-zero. */
|
||||
if ((funcstat = (*func) (fd, (CORE_ADDR) map->pr_vaddr)) != 0)
|
||||
break;
|
||||
}
|
||||
#else
|
||||
/* Get the number of mapping entries. */
|
||||
if (ioctl (pi->ctl_fd, PIOCNMAP, &nmaps) < 0)
|
||||
proc_error (pi, "proc_iterate_over_mappings (PIOCNMAP)", __LINE__);
|
||||
|
||||
/* Allocate space for mappings (lifetime only this function). */
|
||||
map = (struct prmap *) alloca ((nmaps + 1) * sizeof (struct prmap));
|
||||
|
||||
/* Read in all the mappings. */
|
||||
if (ioctl (pi->ctl_fd, PIOCMAP, map) < 0)
|
||||
proc_error (pi, "proc_iterate_over_mappings (PIOCMAP)", __LINE__);
|
||||
|
||||
/* Now loop through the mappings, open an fd for each, and
|
||||
call the callback function. */
|
||||
for (i = 0;
|
||||
i < nmaps && map[i].pr_size != 0;
|
||||
i++)
|
||||
{
|
||||
/* Note: caller's responsibility to close this fd! */
|
||||
fd = ioctl (pi->ctl_fd, PIOCOPENM, &map[i].pr_vaddr);
|
||||
/* Note: we don't test the above call for failure;
|
||||
we just pass the FD on as given. Sometimes there is
|
||||
no file, so the ioctl may return failure, but that's
|
||||
not a problem. */
|
||||
|
||||
/* Stop looping if the callback returns non-zero. */
|
||||
funcstat = (*func) (fd, host_pointer_to_address (map[i].pr_vaddr));
|
||||
if (funcstat != 0)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return funcstat;
|
||||
}
|
||||
|
||||
#ifdef TM_I386SOL2_H /* Is it hokey to use this? */
|
||||
|
||||
#include <sys/sysi86.h>
|
||||
|
@ -5307,6 +5202,158 @@ procfs_find_LDT_entry (ptid_t ptid)
|
|||
}
|
||||
#endif /* TM_I386SOL2_H */
|
||||
|
||||
/*
|
||||
* Memory Mappings Functions:
|
||||
*/
|
||||
|
||||
/*
|
||||
* Function: iterate_over_mappings
|
||||
*
|
||||
* Call a callback function once for each mapping, passing it the mapping,
|
||||
* an optional secondary callback function, and some optional opaque data.
|
||||
* Quit and return the first non-zero value returned from the callback.
|
||||
*
|
||||
* Arguments:
|
||||
* pi -- procinfo struct for the process to be mapped.
|
||||
* func -- callback function to be called by this iterator.
|
||||
* data -- optional opaque data to be passed to the callback function.
|
||||
* child_func -- optional secondary function pointer to be passed
|
||||
* to the child function.
|
||||
*
|
||||
* Return: First non-zero return value from the callback function,
|
||||
* or zero.
|
||||
*/
|
||||
|
||||
static int
|
||||
iterate_over_mappings (procinfo *pi, int (*child_func) (), void *data,
|
||||
int (*func) (struct prmap *map,
|
||||
int (*child_func) (),
|
||||
void *data))
|
||||
{
|
||||
char pathname[MAX_PROC_NAME_SIZE];
|
||||
struct prmap *prmaps;
|
||||
struct prmap *prmap;
|
||||
int funcstat;
|
||||
int map_fd;
|
||||
int nmap;
|
||||
#ifdef NEW_PROC_API
|
||||
struct stat sbuf;
|
||||
#endif
|
||||
|
||||
/* Get the number of mappings, allocate space,
|
||||
and read the mappings into prmaps. */
|
||||
#ifdef NEW_PROC_API
|
||||
/* Open map fd. */
|
||||
sprintf (pathname, "/proc/%d/map", pi->pid);
|
||||
if ((map_fd = open (pathname, O_RDONLY)) < 0)
|
||||
proc_error (pi, "iterate_over_mappings (open)", __LINE__);
|
||||
|
||||
/* Make sure it gets closed again. */
|
||||
make_cleanup_close (map_fd);
|
||||
|
||||
/* Use stat to determine the file size, and compute
|
||||
the number of prmap_t objects it contains. */
|
||||
if (fstat (map_fd, &sbuf) != 0)
|
||||
proc_error (pi, "iterate_over_mappings (fstat)", __LINE__);
|
||||
|
||||
nmap = sbuf.st_size / sizeof (prmap_t);
|
||||
prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
|
||||
if (read (map_fd, (char *) prmaps, nmap * sizeof (*prmaps))
|
||||
!= (nmap * sizeof (*prmaps)))
|
||||
proc_error (pi, "iterate_over_mappings (read)", __LINE__);
|
||||
#else
|
||||
/* Use ioctl command PIOCNMAP to get number of mappings. */
|
||||
if (ioctl (pi->ctl_fd, PIOCNMAP, &nmap) != 0)
|
||||
proc_error (pi, "iterate_over_mappings (PIOCNMAP)", __LINE__);
|
||||
|
||||
prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
|
||||
if (ioctl (pi->ctl_fd, PIOCMAP, prmaps) != 0)
|
||||
proc_error (pi, "iterate_over_mappings (PIOCMAP)", __LINE__);
|
||||
#endif
|
||||
|
||||
for (prmap = prmaps; nmap > 0; prmap++, nmap--)
|
||||
if ((funcstat = (*func) (prmap, child_func, data)) != 0)
|
||||
return funcstat;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: solib_mappings_callback
|
||||
*
|
||||
* Calls the supplied callback function once for each mapped address
|
||||
* space in the process. The callback function receives an open
|
||||
* file descriptor for the file corresponding to that mapped
|
||||
* address space (if there is one), and the base address of the
|
||||
* mapped space. Quit when the callback function returns a
|
||||
* nonzero value, or at teh end of the mappings.
|
||||
*
|
||||
* Returns: the first non-zero return value of the callback function,
|
||||
* or zero.
|
||||
*/
|
||||
|
||||
int solib_mappings_callback (struct prmap *map,
|
||||
int (*func) (int, CORE_ADDR),
|
||||
void *data)
|
||||
{
|
||||
procinfo *pi = data;
|
||||
int fd;
|
||||
|
||||
#ifdef NEW_PROC_API
|
||||
char name[MAX_PROC_NAME_SIZE + sizeof (map->pr_mapname)];
|
||||
|
||||
if (map->pr_vaddr == 0 && map->pr_size == 0)
|
||||
return -1; /* sanity */
|
||||
|
||||
if (map->pr_mapname[0] == 0)
|
||||
{
|
||||
fd = -1; /* no map file */
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (name, "/proc/%d/object/%s", pi->pid, map->pr_mapname);
|
||||
/* Note: caller's responsibility to close this fd! */
|
||||
fd = open_with_retry (name, O_RDONLY);
|
||||
/* Note: we don't test the above call for failure;
|
||||
we just pass the FD on as given. Sometimes there is
|
||||
no file, so the open may return failure, but that's
|
||||
not a problem. */
|
||||
}
|
||||
#else
|
||||
fd = ioctl (pi->ctl_fd, PIOCOPENM, &map->pr_vaddr);
|
||||
/* Note: we don't test the above call for failure;
|
||||
we just pass the FD on as given. Sometimes there is
|
||||
no file, so the ioctl may return failure, but that's
|
||||
not a problem. */
|
||||
#endif
|
||||
return (*func) (fd, (CORE_ADDR) map->pr_vaddr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: proc_iterate_over_mappings
|
||||
*
|
||||
* Uses the unified "iterate_over_mappings" function
|
||||
* to implement the exported interface to solib-svr4.c.
|
||||
*
|
||||
* Given a pointer to a function, call that function once for every
|
||||
* mapped address space in the process. The callback function
|
||||
* receives an open file descriptor for the file corresponding to
|
||||
* that mapped address space (if there is one), and the base address
|
||||
* of the mapped space. Quit when the callback function returns a
|
||||
* nonzero value, or at teh end of the mappings.
|
||||
*
|
||||
* Returns: the first non-zero return value of the callback function,
|
||||
* or zero.
|
||||
*/
|
||||
|
||||
int
|
||||
proc_iterate_over_mappings (int (*func) (int, CORE_ADDR))
|
||||
{
|
||||
procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
|
||||
|
||||
return iterate_over_mappings (pi, func, pi, solib_mappings_callback);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: mappingflags
|
||||
*
|
||||
|
@ -5339,6 +5386,37 @@ mappingflags (flags)
|
|||
return (asciiflags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: info_mappings_callback
|
||||
*
|
||||
* Callback function, does the actual work for 'info proc mappings'.
|
||||
*/
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
info_mappings_callback (struct prmap *map, int (*ignore) (), void *unused)
|
||||
{
|
||||
char *data_fmt_string;
|
||||
|
||||
if (TARGET_ADDR_BIT == 32)
|
||||
data_fmt_string = "\t%#10lx %#10lx %#10x %#10x %7s\n";
|
||||
else
|
||||
data_fmt_string = " %#18lx %#18lx %#10x %#10x %7s\n";
|
||||
|
||||
printf_filtered (data_fmt_string,
|
||||
(unsigned long) map->pr_vaddr,
|
||||
(unsigned long) map->pr_vaddr + map->pr_size - 1,
|
||||
map->pr_size,
|
||||
#ifdef PCAGENT /* Horrible hack: only defined on Solaris 2.6+ */
|
||||
(unsigned int) map->pr_offset,
|
||||
#else
|
||||
map->pr_off,
|
||||
#endif
|
||||
mappingflags (map->pr_mflags));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: info_proc_mappings
|
||||
*
|
||||
|
@ -5348,59 +5426,16 @@ mappingflags (flags)
|
|||
static void
|
||||
info_proc_mappings (procinfo *pi, int summary)
|
||||
{
|
||||
char *header_fmt_string, *data_fmt_string;
|
||||
char pathname[MAX_PROC_NAME_SIZE];
|
||||
struct prmap *prmaps;
|
||||
struct prmap *prmap;
|
||||
int map_fd;
|
||||
int nmap;
|
||||
#ifdef NEW_PROC_API
|
||||
struct stat sbuf;
|
||||
#endif
|
||||
char *header_fmt_string;
|
||||
|
||||
if (TARGET_PTR_BIT == 32)
|
||||
{
|
||||
header_fmt_string = "\t%10s %10s %10s %10s %7s\n";
|
||||
data_fmt_string = "\t%#10lx %#10lx %#10x %#10x %7s\n";
|
||||
}
|
||||
header_fmt_string = "\t%10s %10s %10s %10s %7s\n";
|
||||
else
|
||||
{
|
||||
header_fmt_string = " %18s %18s %10s %10s %7s\n";
|
||||
data_fmt_string = " %#18lx %#18lx %#10x %#10x %7s\n";
|
||||
}
|
||||
header_fmt_string = " %18s %18s %10s %10s %7s\n";
|
||||
|
||||
if (summary)
|
||||
return; /* No output for summary mode. */
|
||||
|
||||
/* Get the number of mappings, allocate space,
|
||||
and read the mappings into prmaps. */
|
||||
#ifdef NEW_PROC_API
|
||||
/* Open map fd. */
|
||||
sprintf (pathname, "/proc/%d/map", pi->pid);
|
||||
if ((map_fd = open (pathname, O_RDONLY)) < 0)
|
||||
return; /* Can't open map file. */
|
||||
/* Make sure it gets closed again. */
|
||||
make_cleanup_close (map_fd);
|
||||
|
||||
/* Use stat to determine the file size, and compute
|
||||
the number of prmap_t objects it contains. */
|
||||
if (fstat (map_fd, &sbuf) != 0)
|
||||
return; /* Can't stat file. */
|
||||
|
||||
nmap = sbuf.st_size / sizeof (prmap_t);
|
||||
prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
|
||||
if (read (map_fd, (char *) prmaps, nmap * sizeof (*prmaps))
|
||||
!= (nmap * sizeof (*prmaps)))
|
||||
return; /* Can't read file. */
|
||||
#else
|
||||
/* Use ioctl command PIOCNMAP to get number of mappings. */
|
||||
if (ioctl (pi->ctl_fd, PIOCNMAP, &nmap) != 0)
|
||||
return; /* Can't get number of mappings. */
|
||||
prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
|
||||
if (ioctl (pi->ctl_fd, PIOCMAP, prmaps) != 0)
|
||||
return; /* Can't read mappings. */
|
||||
#endif
|
||||
|
||||
printf_filtered ("Mapped address spaces:\n\n");
|
||||
printf_filtered (header_fmt_string,
|
||||
"Start Addr",
|
||||
|
@ -5409,20 +5444,7 @@ info_proc_mappings (procinfo *pi, int summary)
|
|||
" Offset",
|
||||
"Flags");
|
||||
|
||||
for (prmap = prmaps; nmap > 0; prmap++, nmap--)
|
||||
{
|
||||
printf_filtered (data_fmt_string,
|
||||
(unsigned long) prmap->pr_vaddr,
|
||||
(unsigned long) prmap->pr_vaddr
|
||||
+ prmap->pr_size - 1,
|
||||
prmap->pr_size,
|
||||
#ifdef PCAGENT /* Gross hack: only defined on Solaris 2.6+ */
|
||||
(unsigned int) prmap->pr_offset,
|
||||
#else
|
||||
prmap->pr_off,
|
||||
#endif
|
||||
mappingflags (prmap->pr_mflags));
|
||||
}
|
||||
iterate_over_mappings (pi, NULL, NULL, info_mappings_callback);
|
||||
printf_filtered ("\n");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue