bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 1/7] procfs: implement /proc/N/maps


From: Justus Winter
Subject: [PATCH 1/7] procfs: implement /proc/N/maps
Date: Mon, 22 Sep 2014 11:38:38 +0200

Fixes https://savannah.gnu.org/bugs/?32770 .

* procfs/process.c (process_file_gc_maps): New function.
(entries): Use the new function to implement /proc/N/maps.
---
 procfs/process.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 103 insertions(+), 1 deletion(-)

diff --git a/procfs/process.c b/procfs/process.c
index 4854148..a9b1a59 100644
--- a/procfs/process.c
+++ b/procfs/process.c
@@ -1,5 +1,5 @@
 /* Hurd /proc filesystem, implementation of process directories.
-   Copyright (C) 2010 Free Software Foundation, Inc.
+   Copyright (C) 2010,14 Free Software Foundation, Inc.
 
    This file is part of the GNU Hurd.
 
@@ -109,6 +109,100 @@ process_file_gc_environ (struct proc_stat *ps, char 
**contents)
 }
 
 static ssize_t
+process_file_gc_maps (struct proc_stat *ps, char **contents)
+{
+  error_t err;
+  FILE *s;
+  size_t contents_len;
+  vm_offset_t addr = 0;
+  vm_size_t size;
+  vm_prot_t prot, max_prot;
+  mach_port_t obj;
+  vm_offset_t offs;
+  vm_inherit_t inh;
+  int shared;
+
+  /* Unfortunately we cannot resolve memory objects to their backing
+     file (yet), so we use the port name as identifier.  To avoid the
+     same name from being used again and again, we defer the
+     deallocation until the end of the function.  We use a simple
+     linked list for this purpose.  */
+  struct mem_obj
+    {
+      mach_port_t port;
+      struct mem_obj *next;
+    };
+  struct mem_obj *objects = NULL;
+
+  s = open_memstream (contents, &contents_len);
+  if (s == NULL)
+    {
+      *contents = NULL;
+      return 0;
+    }
+
+  while (1)
+    {
+      err =
+       vm_region (ps->task, &addr, &size, &prot, &max_prot, &inh,
+                  &shared, &obj, &offs);
+      if (err)
+       break;
+
+      fprintf (s, "%0*x-%0*x %c%c%c%c %0*x %s %d ",
+              /* Address range.  */
+              2*sizeof s, addr,
+              2*sizeof s, addr + size,
+              /* Permissions.  */
+              prot & VM_PROT_READ? 'r': '-',
+              prot & VM_PROT_WRITE? 'w': '-',
+              prot & VM_PROT_EXECUTE? 'x': '-',
+              shared? 's': 'p',
+              /* Offset.  */
+              2*sizeof s, offs,
+              /* Device.  */
+              "00:00",
+              /* Inode.  */
+              0);
+
+      /* Pathname.  */
+      if (MACH_PORT_VALID (obj))
+       {
+         struct mem_obj *o = malloc (sizeof *o);
+         if (o)
+           {
+             o->port = obj;
+             o->next = objects;
+             objects = o;
+           }
+         else
+           mach_port_deallocate (mach_task_self (), obj);
+
+         fprintf (s, "[mem_obj=%d]\n", obj);
+       }
+      else
+       fprintf (s, "\n");
+
+      addr += size;
+    }
+
+  while (objects)
+    {
+      struct mem_obj *o = objects;
+      mach_port_deallocate (mach_task_self (), o->port);
+      objects = o->next;
+      free (o);
+    }
+
+  /* This is a bit awkward, fortunately vm_region should not fail.  */
+  if (err != KERN_NO_SPACE)
+    fprintf (s, "%s\n", strerror (err));
+
+  fclose (s);
+  return contents_len;
+}
+
+static ssize_t
 process_file_gc_stat (struct proc_stat *ps, char **contents)
 {
   struct procinfo *pi = proc_stat_proc_info (ps);
@@ -348,6 +442,14 @@ static struct procfs_dir_entry entries[] = {
     },
   },
   {
+    .name = "maps",
+    .hook = & (struct process_file_desc) {
+      .get_contents = process_file_gc_maps,
+      .needs = PSTAT_TASK,
+      .mode = 0400,
+    },
+  },
+  {
     .name = "stat",
     .hook = & (struct process_file_desc) {
       .get_contents = process_file_gc_stat,
-- 
2.1.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]