aboutsummaryrefslogtreecommitdiff
path: root/gdb/procfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/procfs.c')
-rw-r--r--gdb/procfs.c153
1 files changed, 142 insertions, 11 deletions
diff --git a/gdb/procfs.c b/gdb/procfs.c
index 76333ef..7983678 100644
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -2879,9 +2879,6 @@ proc_set_watchpoint (procinfo *pi, CORE_ADDR addr, int len, int wflags)
* or zero.
*/
-/* FIXME: it's probably a waste to cache this FD.
- It doesn't get called that often... and if I open it
- every time, I don't need to lseek it. */
int
proc_iterate_over_mappings (int (*func) (int, CORE_ADDR))
{
@@ -5310,18 +5307,142 @@ procfs_find_LDT_entry (ptid_t ptid)
}
#endif /* TM_I386SOL2_H */
+/*
+ * Function: mappingflags
+ *
+ * Returns an ascii representation of a memory mapping's flags.
+ */
+static char *
+mappingflags (flags)
+ long flags;
+{
+ static char asciiflags[8];
+
+ strcpy (asciiflags, "-------");
+#if defined (MA_PHYS)
+ if (flags & MA_PHYS)
+ asciiflags[0] = 'd';
+#endif
+ if (flags & MA_STACK)
+ asciiflags[1] = 's';
+ if (flags & MA_BREAK)
+ asciiflags[2] = 'b';
+ if (flags & MA_SHARED)
+ asciiflags[3] = 's';
+ if (flags & MA_READ)
+ asciiflags[4] = 'r';
+ if (flags & MA_WRITE)
+ asciiflags[5] = 'w';
+ if (flags & MA_EXEC)
+ asciiflags[6] = 'x';
+ return (asciiflags);
+}
+
+/*
+ * Function: info_proc_mappings
+ *
+ * Implement the "info proc mappings" subcommand.
+ */
+
+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
+
+ 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";
+ }
+ else
+ {
+ header_fmt_string = " %18s %18s %10s %10s %7s\n";
+ data_fmt_string = " %#18lx %#18lx %#10x %#10x %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",
+ " End Addr",
+ " Size",
+ " 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));
+ }
+ printf_filtered ("\n");
+}
+
+/*
+ * Function: info_proc_cmd
+ *
+ * Implement the "info proc" command.
+ */
static void
info_proc_cmd (char *args, int from_tty)
{
struct cleanup *old_chain;
- procinfo *process = NULL;
- procinfo *thread = NULL;
- char **argv = NULL;
- char *tmp = NULL;
- int pid = 0;
- int tid = 0;
+ procinfo *process = NULL;
+ procinfo *thread = NULL;
+ char **argv = NULL;
+ char *tmp = NULL;
+ int pid = 0;
+ int tid = 0;
+ int mappings = 0;
old_chain = make_cleanup (null_cleanup, 0);
if (args)
@@ -5343,6 +5464,10 @@ info_proc_cmd (char *args, int from_tty)
{
tid = strtoul (argv[0] + 1, NULL, 10);
}
+ else if (strncmp (argv[0], "mappings", strlen (argv[0])) == 0)
+ {
+ mappings = 1;
+ }
else
{
/* [...] */
@@ -5389,6 +5514,11 @@ info_proc_cmd (char *args, int from_tty)
proc_prettyprint_why (proc_why (thread), proc_what (thread), 1);
}
+ if (mappings)
+ {
+ info_proc_mappings (process, 0);
+ }
+
do_cleanups (old_chain);
}
@@ -5466,8 +5596,9 @@ _initialize_procfs (void)
init_procfs_ops ();
add_target (&procfs_ops);
add_info ("proc", info_proc_cmd,
- "Show /proc process information about any running process.\
-Default is the process being debugged.");
+ "Show /proc process information about any running process.\n\
+Specify process id, or use the program being debugged by default.\n\
+Specify keyword 'mappings' for detailed info on memory mappings.");
add_com ("proc-trace-entry", no_class, proc_trace_sysentry_cmd,
"Give a trace of entries into the syscall.");
add_com ("proc-trace-exit", no_class, proc_trace_sysexit_cmd,