aboutsummaryrefslogtreecommitdiff
path: root/gdb/procfs.c
diff options
context:
space:
mode:
authorMichael Snyder <msnyder@vmware.com>2002-01-03 20:50:25 +0000
committerMichael Snyder <msnyder@vmware.com>2002-01-03 20:50:25 +0000
commit831e682efed7d11695f65c9148f40b81da1d121b (patch)
tree8b82d59c75a296ccd9750fa64899939dfdb00025 /gdb/procfs.c
parent51c5503ba726b734a9b6011dcfdeb5e95c06f1a6 (diff)
downloadgdb-831e682efed7d11695f65c9148f40b81da1d121b.zip
gdb-831e682efed7d11695f65c9148f40b81da1d121b.tar.gz
gdb-831e682efed7d11695f65c9148f40b81da1d121b.tar.bz2
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.
Diffstat (limited to 'gdb/procfs.c')
-rw-r--r--gdb/procfs.c362
1 files changed, 192 insertions, 170 deletions
diff --git a/gdb/procfs.c b/gdb/procfs.c
index 7983678..32b4e60 100644
--- a/gdb/procfs.c
+++ b/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>
@@ -5308,6 +5203,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
*
* Returns an ascii representation of a memory mapping's flags.
@@ -5340,6 +5387,37 @@ mappingflags (flags)
}
/*
+ * 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
*
* Implement the "info proc mappings" subcommand.
@@ -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");
}