[rfc,v4,6/6] Implement "info proc" on Linux via target file I/O

Message ID 201201201815.q0KIFrwH002044@d06av02.portsmouth.uk.ibm.com
State Accepted
Headers show

Commit Message

Ulrich Weigand Jan. 20, 2012, 6:15 p.m.
http://sourceware.org/ml/gdb-patches/2012-01/msg00691.html


ChangeLog:

	* gdbarch.sh (info_proc): New callback.
	* gdbarch.c, gdbarch.h: Regenerate.

	* infcmd.c (info_proc_cmd_1): Try gdbarch info_proc callback
	before falling back to the target info_proc callback.

	* linux-nat.c: Do not include "cli/cli-utils.h".
	(linux_nat_info_proc): Remove.
	(linux_target_install_ops): No longer install it.

	* linux-tdep.c: Include "cli/cli-utils.h" and <ctype.h>.
	(read_mapping): New function.
	(linux_info_proc): Likewise.
	(linux_init_abi): Install it.

Patch

Index: gdb-head/gdb/gdbarch.c
===================================================================
--- gdb-head.orig/gdb/gdbarch.c	2012-01-19 10:35:56.000000000 +0100
+++ gdb-head/gdb/gdbarch.c	2012-01-19 10:41:07.000000000 +0100
@@ -272,6 +272,7 @@  struct gdbarch
   const char * solib_symbols_extension;
   int has_dos_based_file_system;
   gdbarch_gen_return_address_ftype *gen_return_address;
+  gdbarch_info_proc_ftype *info_proc;
 };
 
 
@@ -427,6 +428,7 @@  struct gdbarch startup_gdbarch =
   0,  /* solib_symbols_extension */
   0,  /* has_dos_based_file_system */
   default_gen_return_address,  /* gen_return_address */
+  0,  /* info_proc */
   /* startup_gdbarch() */
 };
 
@@ -715,6 +717,7 @@  verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of auto_wide_charset, invalid_p == 0 */
   /* Skip verify of has_dos_based_file_system, invalid_p == 0 */
   /* Skip verify of gen_return_address, invalid_p == 0 */
+  /* Skip verify of info_proc, has predicate.  */
   buf = ui_file_xstrdup (log, &length);
   make_cleanup (xfree, buf);
   if (length > 0)
@@ -1003,6 +1006,12 @@  gdbarch_dump (struct gdbarch *gdbarch, s
                       "gdbarch_dump: in_solib_return_trampoline = <%s>\n",
                       host_address_to_string (gdbarch->in_solib_return_trampoline));
   fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_info_proc_p() = %d\n",
+                      gdbarch_info_proc_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: info_proc = <%s>\n",
+                      host_address_to_string (gdbarch->info_proc));
+  fprintf_unfiltered (file,
                       "gdbarch_dump: inner_than = <%s>\n",
                       host_address_to_string (gdbarch->inner_than));
   fprintf_unfiltered (file,
@@ -3911,6 +3920,30 @@  set_gdbarch_gen_return_address (struct g
   gdbarch->gen_return_address = gen_return_address;
 }
 
+int
+gdbarch_info_proc_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->info_proc != NULL;
+}
+
+void
+gdbarch_info_proc (struct gdbarch *gdbarch, char *args, enum info_proc_what what)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->info_proc != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_info_proc called\n");
+  gdbarch->info_proc (gdbarch, args, what);
+}
+
+void
+set_gdbarch_info_proc (struct gdbarch *gdbarch,
+                       gdbarch_info_proc_ftype info_proc)
+{
+  gdbarch->info_proc = info_proc;
+}
+
 
 /* Keep a registry of per-architecture data-pointers required by GDB
    modules.  */
Index: gdb-head/gdb/gdbarch.h
===================================================================
--- gdb-head.orig/gdb/gdbarch.h	2012-01-19 10:35:56.000000000 +0100
+++ gdb-head/gdb/gdbarch.h	2012-01-19 10:41:07.000000000 +0100
@@ -1031,6 +1031,14 @@  typedef void (gdbarch_gen_return_address
 extern void gdbarch_gen_return_address (struct gdbarch *gdbarch, struct agent_expr *ax, struct axs_value *value, CORE_ADDR scope);
 extern void set_gdbarch_gen_return_address (struct gdbarch *gdbarch, gdbarch_gen_return_address_ftype *gen_return_address);
 
+/* Implement the "info proc" command. */
+
+extern int gdbarch_info_proc_p (struct gdbarch *gdbarch);
+
+typedef void (gdbarch_info_proc_ftype) (struct gdbarch *gdbarch, char *args, enum info_proc_what what);
+extern void gdbarch_info_proc (struct gdbarch *gdbarch, char *args, enum info_proc_what what);
+extern void set_gdbarch_info_proc (struct gdbarch *gdbarch, gdbarch_info_proc_ftype *info_proc);
+
 /* Definition for an unknown syscall, used basically in error-cases.  */
 #define UNKNOWN_SYSCALL (-1)
 
Index: gdb-head/gdb/gdbarch.sh
===================================================================
--- gdb-head.orig/gdb/gdbarch.sh	2012-01-19 10:35:56.000000000 +0100
+++ gdb-head/gdb/gdbarch.sh	2012-01-19 10:41:07.000000000 +0100
@@ -830,6 +830,9 @@  v:int:has_dos_based_file_system:::0:0::0
 # places that the return address may be found.
 m:void:gen_return_address:struct agent_expr *ax, struct axs_value *value, CORE_ADDR scope:ax, value, scope::default_gen_return_address::0
 
+# Implement the "info proc" command.
+M:void:info_proc:char *args, enum info_proc_what what:args, what
+
 EOF
 }
 
Index: gdb-head/gdb/infcmd.c
===================================================================
--- gdb-head.orig/gdb/infcmd.c	2012-01-19 10:40:57.000000000 +0100
+++ gdb-head/gdb/infcmd.c	2012-01-19 10:41:07.000000000 +0100
@@ -2810,7 +2810,12 @@  unset_command (char *args, int from_tty)
 static void
 info_proc_cmd_1 (char *args, enum info_proc_what what, int from_tty)
 {
-  target_info_proc (args, what);
+  struct gdbarch *gdbarch = get_current_arch ();
+
+  if (gdbarch_info_proc_p (gdbarch))
+    gdbarch_info_proc (gdbarch, args, what);
+  else
+    target_info_proc (args, what);
 }
 
 /* Implement `info proc' when given without any futher parameters.  */
Index: gdb-head/gdb/linux-tdep.c
===================================================================
--- gdb-head.orig/gdb/linux-tdep.c	2012-01-19 10:35:56.000000000 +0100
+++ gdb-head/gdb/linux-tdep.c	2012-01-19 10:41:07.000000000 +0100
@@ -24,6 +24,9 @@ 
 #include "target.h"
 #include "elf/common.h"
 #include "inferior.h"
+#include "cli/cli-utils.h"
+
+#include <ctype.h>
 
 static struct gdbarch_data *linux_gdbarch_data_handle;
 
@@ -196,6 +199,332 @@  linux_core_pid_to_str (struct gdbarch *g
   return normal_pid_to_str (ptid);
 }
 
+/* Service function for corefiles and info proc.  */
+
+static void
+read_mapping (const char *line,
+	      ULONGEST *addr, ULONGEST *endaddr,
+	      const char **permissions, size_t *permissions_len,
+	      ULONGEST *offset,
+              const char **device, size_t *device_len,
+	      ULONGEST *inode,
+	      const char **filename)
+{
+  const char *p = line;
+
+  *addr = strtoulst (p, &p, 16);
+  if (*p == '-')
+    p++;
+  *endaddr = strtoulst (p, &p, 16);
+
+  while (*p && isspace (*p))
+    p++;
+  *permissions = p;
+  while (*p && !isspace (*p))
+    p++;
+  *permissions_len = p - *permissions;
+
+  *offset = strtoulst (p, &p, 16);
+
+  while (*p && isspace (*p))
+    p++;
+  *device = p;
+  while (*p && !isspace (*p))
+    p++;
+  *device_len = p - *device;
+
+  *inode = strtoulst (p, &p, 10);
+
+  while (*p && isspace (*p))
+    p++;
+  *filename = p;
+}
+
+/* Implement the "info proc" command.  */
+
+static void
+linux_info_proc (struct gdbarch *gdbarch, char *args,
+		 enum info_proc_what what)
+{
+  /* A long is used for pid instead of an int to avoid a loss of precision
+     compiler warning from the output of strtoul.  */
+  long pid;
+  int cmdline_f = (what == IP_MINIMAL || what == IP_CMDLINE || what == IP_ALL);
+  int cwd_f = (what == IP_MINIMAL || what == IP_CWD || what == IP_ALL);
+  int exe_f = (what == IP_MINIMAL || what == IP_EXE || what == IP_ALL);
+  int mappings_f = (what == IP_MAPPINGS || what == IP_ALL);
+  int status_f = (what == IP_STATUS || what == IP_ALL);
+  int stat_f = (what == IP_STAT || what == IP_ALL);
+  char filename[100];
+  gdb_byte *data;
+  int target_errno;
+
+  if (args && isdigit (args[0]))
+    pid = strtoul (args, &args, 10);
+  else
+    {
+      if (!target_has_execution)
+	error (_("No current process: you must name one."));
+      if (current_inferior ()->fake_pid_p)
+	error (_("Can't determine the current process's PID: you must name one."));
+
+      pid = current_inferior ()->pid;
+    }
+
+  args = skip_spaces (args);
+  if (args && args[0])
+    error (_("Too many parameters: %s"), args);
+
+  printf_filtered (_("process %ld\n"), pid);
+  if (cmdline_f)
+    {
+      xsnprintf (filename, sizeof filename, "/proc/%ld/cmdline", pid);
+      data = target_fileio_read_stralloc (filename);
+      if (data)
+	{
+	  struct cleanup *cleanup = make_cleanup (xfree, data);
+          printf_filtered ("cmdline = '%s'\n", data);
+	  do_cleanups (cleanup);
+	}
+      else
+	warning (_("unable to open /proc file '%s'"), filename);
+    }
+  if (cwd_f)
+    {
+      xsnprintf (filename, sizeof filename, "/proc/%ld/cwd", pid);
+      data = target_fileio_readlink (filename, &target_errno);
+      if (data)
+	{
+	  struct cleanup *cleanup = make_cleanup (xfree, data);
+          printf_filtered ("cwd = '%s'\n", data);
+	  do_cleanups (cleanup);
+	}
+      else
+	warning (_("unable to read link '%s'"), filename);
+    }
+  if (exe_f)
+    {
+      xsnprintf (filename, sizeof filename, "/proc/%ld/exe", pid);
+      data = target_fileio_readlink (filename, &target_errno);
+      if (data)
+	{
+	  struct cleanup *cleanup = make_cleanup (xfree, data);
+          printf_filtered ("exe = '%s'\n", data);
+	  do_cleanups (cleanup);
+	}
+      else
+	warning (_("unable to read link '%s'"), filename);
+    }
+  if (mappings_f)
+    {
+      xsnprintf (filename, sizeof filename, "/proc/%ld/maps", pid);
+      data = target_fileio_read_stralloc (filename);
+      if (data)
+	{
+	  struct cleanup *cleanup = make_cleanup (xfree, data);
+	  char *line;
+
+	  printf_filtered (_("Mapped address spaces:\n\n"));
+	  if (gdbarch_addr_bit (gdbarch) == 32)
+	    {
+	      printf_filtered ("\t%10s %10s %10s %10s %s\n",
+			   "Start Addr",
+			   "  End Addr",
+			   "      Size", "    Offset", "objfile");
+            }
+	  else
+            {
+	      printf_filtered ("  %18s %18s %10s %10s %s\n",
+			   "Start Addr",
+			   "  End Addr",
+			   "      Size", "    Offset", "objfile");
+	    }
+
+	  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;
+
+	      read_mapping (line, &addr, &endaddr,
+			    &permissions, &permissions_len,
+			    &offset, &device, &device_len,
+			    &inode, &filename);
+
+	      if (gdbarch_addr_bit (gdbarch) == 32)
+	        {
+	          printf_filtered ("\t%10s %10s %10s %10s %s\n",
+				   paddress (gdbarch, addr),
+				   paddress (gdbarch, endaddr),
+				   hex_string (endaddr - addr),
+				   hex_string (offset),
+				   *filename? filename : "");
+		}
+	      else
+	        {
+	          printf_filtered ("  %18s %18s %10s %10s %s\n",
+				   paddress (gdbarch, addr),
+				   paddress (gdbarch, endaddr),
+				   hex_string (endaddr - addr),
+				   hex_string (offset),
+				   *filename? filename : "");
+	        }
+	    }
+
+	  do_cleanups (cleanup);
+	}
+      else
+	warning (_("unable to open /proc file '%s'"), filename);
+    }
+  if (status_f)
+    {
+      xsnprintf (filename, sizeof filename, "/proc/%ld/status", pid);
+      data = target_fileio_read_stralloc (filename);
+      if (data)
+	{
+	  struct cleanup *cleanup = make_cleanup (xfree, data);
+          puts_filtered (data);
+	  do_cleanups (cleanup);
+	}
+      else
+	warning (_("unable to open /proc file '%s'"), filename);
+    }
+  if (stat_f)
+    {
+      xsnprintf (filename, sizeof filename, "/proc/%ld/stat", pid);
+      data = target_fileio_read_stralloc (filename);
+      if (data)
+	{
+	  struct cleanup *cleanup = make_cleanup (xfree, data);
+	  const char *p = data;
+	  const char *ep;
+	  ULONGEST val;
+
+	  printf_filtered (_("Process: %s\n"),
+			   pulongest (strtoulst (p, &p, 10)));
+
+	  while (*p && isspace (*p))
+	    p++;
+	  if (*p == '(' && (ep = strchr (p, ')')) != NULL)
+	    {
+	      printf_filtered ("Exec file: %.*s\n", (int) (ep - p - 1), p + 1);
+	      p = ep + 1;
+	    }
+
+	  while (*p && isspace (*p))
+	    p++;
+	  if (*p)
+	    printf_filtered (_("State: %c\n"), *p++);
+
+	  if (*p)
+	    printf_filtered (_("Parent process: %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("Process group: %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("Session id: %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("TTY: %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("TTY owner process group: %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+
+	  if (*p)
+	    printf_filtered (_("Flags: %s\n"),
+			     hex_string (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("Minor faults (no memory page): %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("Minor faults, children: %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("Major faults (memory page faults): %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("Major faults, children: %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("utime: %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("stime: %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("utime, children: %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("stime, children: %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("jiffies remaining in current "
+			       "time slice: %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("'nice' value: %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("jiffies until next timeout: %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("jiffies until next SIGALRM: %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("start time (jiffies since "
+			       "system boot): %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("Virtual memory size: %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("Resident set size: %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("rlim: %s\n"),
+			     pulongest (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("Start of text: %s\n"),
+			     hex_string (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("End of text: %s\n"),
+			     hex_string (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("Start of stack: %s\n"),
+			     hex_string (strtoulst (p, &p, 10)));
+#if 0	/* Don't know how architecture-dependent the rest is...
+	   Anyway the signal bitmap info is available from "status".  */
+	  if (*p)
+	    printf_filtered (_("Kernel stack pointer: %s\n"),
+			     hex_string (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("Kernel instr pointer: %s\n"),
+			     hex_string (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("Pending signals bitmap: %s\n"),
+			     hex_string (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("Blocked signals bitmap: %s\n"),
+			     hex_string (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("Ignored signals bitmap: %s\n"),
+			     hex_string (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("Catched signals bitmap: %s\n"),
+			     hex_string (strtoulst (p, &p, 10)));
+	  if (*p)
+	    printf_filtered (_("wchan (system call): %s\n"),
+			     hex_string (strtoulst (p, &p, 10)));
+#endif
+	  do_cleanups (cleanup);
+	}
+      else
+	warning (_("unable to open /proc file '%s'"), filename);
+    }
+}
+
 /* To be called from the various GDB_OSABI_LINUX handlers for the
    various GNU/Linux architectures and machine types.  */
 
@@ -203,6 +532,7 @@  void
 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);
 }
 
 void
Index: gdb-head/gdb/linux-nat.c
===================================================================
--- gdb-head.orig/gdb/linux-nat.c	2012-01-19 10:40:57.000000000 +0100
+++ gdb-head/gdb/linux-nat.c	2012-01-19 10:41:07.000000000 +0100
@@ -58,7 +58,6 @@ 
 #include <sys/vfs.h>
 #include "solib.h"
 #include "linux-osdata.h"
-#include "cli/cli-utils.h"
 
 #ifndef SPUFS_MAGIC
 #define SPUFS_MAGIC 0x23c9b64e
@@ -4801,251 +4800,6 @@  linux_nat_make_corefile_notes (bfd *obfd
   return note_data;
 }
 
-/* Implement the "info proc" command.  */
-
-static void
-linux_nat_info_proc (struct target_ops *ops, char *args,
-		     enum info_proc_what what)
-{
-  /* A long is used for pid instead of an int to avoid a loss of precision
-     compiler warning from the output of strtoul.  */
-  long pid = PIDGET (inferior_ptid);
-  FILE *procfile;
-  char buffer[MAXPATHLEN];
-  char fname1[MAXPATHLEN], fname2[MAXPATHLEN];
-  int cmdline_f = (what == IP_MINIMAL || what == IP_CMDLINE || what == IP_ALL);
-  int cwd_f = (what == IP_MINIMAL || what == IP_CWD || what == IP_ALL);
-  int exe_f = (what == IP_MINIMAL || what == IP_EXE || what == IP_ALL);
-  int mappings_f = (what == IP_MAPPINGS || what == IP_ALL);
-  int status_f = (what == IP_STATUS || what == IP_ALL);
-  int stat_f = (what == IP_STAT || what == IP_ALL);
-  struct stat dummy;
-
-  if (args && isdigit (args[0]))
-    pid = strtoul (args, &args, 10);
-
-  args = skip_spaces (args);
-  if (args && args[0])
-    error (_("Too many parameters: %s"), args);
-
-  if (pid == 0)
-    error (_("No current process: you must name one."));
-
-  sprintf (fname1, "/proc/%ld", pid);
-  if (stat (fname1, &dummy) != 0)
-    error (_("No /proc directory: '%s'"), fname1);
-
-  printf_filtered (_("process %ld\n"), pid);
-  if (cmdline_f)
-    {
-      sprintf (fname1, "/proc/%ld/cmdline", pid);
-      if ((procfile = fopen (fname1, "r")) != NULL)
-	{
-	  struct cleanup *cleanup = make_cleanup_fclose (procfile);
-
-          if (fgets (buffer, sizeof (buffer), procfile))
-            printf_filtered ("cmdline = '%s'\n", buffer);
-          else
-            warning (_("unable to read '%s'"), fname1);
-	  do_cleanups (cleanup);
-	}
-      else
-	warning (_("unable to open /proc file '%s'"), fname1);
-    }
-  if (cwd_f)
-    {
-      sprintf (fname1, "/proc/%ld/cwd", pid);
-      memset (fname2, 0, sizeof (fname2));
-      if (readlink (fname1, fname2, sizeof (fname2)) > 0)
-	printf_filtered ("cwd = '%s'\n", fname2);
-      else
-	warning (_("unable to read link '%s'"), fname1);
-    }
-  if (exe_f)
-    {
-      sprintf (fname1, "/proc/%ld/exe", pid);
-      memset (fname2, 0, sizeof (fname2));
-      if (readlink (fname1, fname2, sizeof (fname2)) > 0)
-	printf_filtered ("exe = '%s'\n", fname2);
-      else
-	warning (_("unable to read link '%s'"), fname1);
-    }
-  if (mappings_f)
-    {
-      sprintf (fname1, "/proc/%ld/maps", pid);
-      if ((procfile = fopen (fname1, "r")) != NULL)
-	{
-	  long long addr, endaddr, size, offset, inode;
-	  char permissions[8], device[8], filename[MAXPATHLEN];
-	  struct cleanup *cleanup;
-
-	  cleanup = make_cleanup_fclose (procfile);
-	  printf_filtered (_("Mapped address spaces:\n\n"));
-	  if (gdbarch_addr_bit (target_gdbarch) == 32)
-	    {
-	      printf_filtered ("\t%10s %10s %10s %10s %7s\n",
-			   "Start Addr",
-			   "  End Addr",
-			   "      Size", "    Offset", "objfile");
-            }
-	  else
-            {
-	      printf_filtered ("  %18s %18s %10s %10s %7s\n",
-			   "Start Addr",
-			   "  End Addr",
-			   "      Size", "    Offset", "objfile");
-	    }
-
-	  while (read_mapping (procfile, &addr, &endaddr, &permissions[0],
-			       &offset, &device[0], &inode, &filename[0]))
-	    {
-	      size = endaddr - addr;
-
-	      /* FIXME: carlton/2003-08-27: Maybe the printf_filtered
-		 calls here (and possibly above) should be abstracted
-		 out into their own functions?  Andrew suggests using
-		 a generic local_address_string instead to print out
-		 the addresses; that makes sense to me, too.  */
-
-	      if (gdbarch_addr_bit (target_gdbarch) == 32)
-	        {
-	          printf_filtered ("\t%#10lx %#10lx %#10x %#10x %7s\n",
-			       (unsigned long) addr,	/* FIXME: pr_addr */
-			       (unsigned long) endaddr,
-			       (int) size,
-			       (unsigned int) offset,
-			       filename[0] ? filename : "");
-		}
-	      else
-	        {
-	          printf_filtered ("  %#18lx %#18lx %#10x %#10x %7s\n",
-			       (unsigned long) addr,	/* FIXME: pr_addr */
-			       (unsigned long) endaddr,
-			       (int) size,
-			       (unsigned int) offset,
-			       filename[0] ? filename : "");
-	        }
-	    }
-
-	  do_cleanups (cleanup);
-	}
-      else
-	warning (_("unable to open /proc file '%s'"), fname1);
-    }
-  if (status_f)
-    {
-      sprintf (fname1, "/proc/%ld/status", pid);
-      if ((procfile = fopen (fname1, "r")) != NULL)
-	{
-	  struct cleanup *cleanup = make_cleanup_fclose (procfile);
-
-	  while (fgets (buffer, sizeof (buffer), procfile) != NULL)
-	    puts_filtered (buffer);
-	  do_cleanups (cleanup);
-	}
-      else
-	warning (_("unable to open /proc file '%s'"), fname1);
-    }
-  if (stat_f)
-    {
-      sprintf (fname1, "/proc/%ld/stat", pid);
-      if ((procfile = fopen (fname1, "r")) != NULL)
-	{
-	  int itmp;
-	  char ctmp;
-	  long ltmp;
-	  struct cleanup *cleanup = make_cleanup_fclose (procfile);
-
-	  if (fscanf (procfile, "%d ", &itmp) > 0)
-	    printf_filtered (_("Process: %d\n"), itmp);
-	  if (fscanf (procfile, "(%[^)]) ", &buffer[0]) > 0)
-	    printf_filtered (_("Exec file: %s\n"), buffer);
-	  if (fscanf (procfile, "%c ", &ctmp) > 0)
-	    printf_filtered (_("State: %c\n"), ctmp);
-	  if (fscanf (procfile, "%d ", &itmp) > 0)
-	    printf_filtered (_("Parent process: %d\n"), itmp);
-	  if (fscanf (procfile, "%d ", &itmp) > 0)
-	    printf_filtered (_("Process group: %d\n"), itmp);
-	  if (fscanf (procfile, "%d ", &itmp) > 0)
-	    printf_filtered (_("Session id: %d\n"), itmp);
-	  if (fscanf (procfile, "%d ", &itmp) > 0)
-	    printf_filtered (_("TTY: %d\n"), itmp);
-	  if (fscanf (procfile, "%d ", &itmp) > 0)
-	    printf_filtered (_("TTY owner process group: %d\n"), itmp);
-	  if (fscanf (procfile, "%lu ", &ltmp) > 0)
-	    printf_filtered (_("Flags: 0x%lx\n"), ltmp);
-	  if (fscanf (procfile, "%lu ", &ltmp) > 0)
-	    printf_filtered (_("Minor faults (no memory page): %lu\n"),
-			     (unsigned long) ltmp);
-	  if (fscanf (procfile, "%lu ", &ltmp) > 0)
-	    printf_filtered (_("Minor faults, children: %lu\n"),
-			     (unsigned long) ltmp);
-	  if (fscanf (procfile, "%lu ", &ltmp) > 0)
-	    printf_filtered (_("Major faults (memory page faults): %lu\n"),
-			     (unsigned long) ltmp);
-	  if (fscanf (procfile, "%lu ", &ltmp) > 0)
-	    printf_filtered (_("Major faults, children: %lu\n"),
-			     (unsigned long) ltmp);
-	  if (fscanf (procfile, "%ld ", &ltmp) > 0)
-	    printf_filtered (_("utime: %ld\n"), ltmp);
-	  if (fscanf (procfile, "%ld ", &ltmp) > 0)
-	    printf_filtered (_("stime: %ld\n"), ltmp);
-	  if (fscanf (procfile, "%ld ", &ltmp) > 0)
-	    printf_filtered (_("utime, children: %ld\n"), ltmp);
-	  if (fscanf (procfile, "%ld ", &ltmp) > 0)
-	    printf_filtered (_("stime, children: %ld\n"), ltmp);
-	  if (fscanf (procfile, "%ld ", &ltmp) > 0)
-	    printf_filtered (_("jiffies remaining in current "
-			       "time slice: %ld\n"), ltmp);
-	  if (fscanf (procfile, "%ld ", &ltmp) > 0)
-	    printf_filtered (_("'nice' value: %ld\n"), ltmp);
-	  if (fscanf (procfile, "%lu ", &ltmp) > 0)
-	    printf_filtered (_("jiffies until next timeout: %lu\n"),
-			     (unsigned long) ltmp);
-	  if (fscanf (procfile, "%lu ", &ltmp) > 0)
-	    printf_filtered (_("jiffies until next SIGALRM: %lu\n"),
-			     (unsigned long) ltmp);
-	  if (fscanf (procfile, "%ld ", &ltmp) > 0)
-	    printf_filtered (_("start time (jiffies since "
-			       "system boot): %ld\n"), ltmp);
-	  if (fscanf (procfile, "%lu ", &ltmp) > 0)
-	    printf_filtered (_("Virtual memory size: %lu\n"),
-			     (unsigned long) ltmp);
-	  if (fscanf (procfile, "%lu ", &ltmp) > 0)
-	    printf_filtered (_("Resident set size: %lu\n"),
-			     (unsigned long) ltmp);
-	  if (fscanf (procfile, "%lu ", &ltmp) > 0)
-	    printf_filtered (_("rlim: %lu\n"), (unsigned long) ltmp);
-	  if (fscanf (procfile, "%lu ", &ltmp) > 0)
-	    printf_filtered (_("Start of text: 0x%lx\n"), ltmp);
-	  if (fscanf (procfile, "%lu ", &ltmp) > 0)
-	    printf_filtered (_("End of text: 0x%lx\n"), ltmp);
-	  if (fscanf (procfile, "%lu ", &ltmp) > 0)
-	    printf_filtered (_("Start of stack: 0x%lx\n"), ltmp);
-#if 0	/* Don't know how architecture-dependent the rest is...
-	   Anyway the signal bitmap info is available from "status".  */
-	  if (fscanf (procfile, "%lu ", &ltmp) > 0)	/* FIXME arch?  */
-	    printf_filtered (_("Kernel stack pointer: 0x%lx\n"), ltmp);
-	  if (fscanf (procfile, "%lu ", &ltmp) > 0)	/* FIXME arch?  */
-	    printf_filtered (_("Kernel instr pointer: 0x%lx\n"), ltmp);
-	  if (fscanf (procfile, "%ld ", &ltmp) > 0)
-	    printf_filtered (_("Pending signals bitmap: 0x%lx\n"), ltmp);
-	  if (fscanf (procfile, "%ld ", &ltmp) > 0)
-	    printf_filtered (_("Blocked signals bitmap: 0x%lx\n"), ltmp);
-	  if (fscanf (procfile, "%ld ", &ltmp) > 0)
-	    printf_filtered (_("Ignored signals bitmap: 0x%lx\n"), ltmp);
-	  if (fscanf (procfile, "%ld ", &ltmp) > 0)
-	    printf_filtered (_("Catched signals bitmap: 0x%lx\n"), ltmp);
-	  if (fscanf (procfile, "%lu ", &ltmp) > 0)	/* FIXME arch?  */
-	    printf_filtered (_("wchan (system call): 0x%lx\n"), ltmp);
-#endif
-	  do_cleanups (cleanup);
-	}
-      else
-	warning (_("unable to open /proc file '%s'"), fname1);
-    }
-}
-
 /* Implement the to_xfer_partial interface for memory reads using the /proc
    filesystem.  Because we can use a single read() call for /proc, this
    can be much more efficient than banging away at PTRACE_PEEKTEXT,
@@ -5340,7 +5094,6 @@  linux_target_install_ops (struct target_
   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_info_proc = linux_nat_info_proc;
 
   super_xfer_partial = t->to_xfer_partial;
   t->to_xfer_partial = linux_xfer_partial;