diff options
Diffstat (limited to 'debian')
-rw-r--r-- | debian/patches/procfs-maps.patch | 127 | ||||
-rw-r--r-- | debian/patches/series | 1 |
2 files changed, 128 insertions, 0 deletions
diff --git a/debian/patches/procfs-maps.patch b/debian/patches/procfs-maps.patch new file mode 100644 index 00000000..3d1053fb --- /dev/null +++ b/debian/patches/procfs-maps.patch @@ -0,0 +1,127 @@ +From 5c1494757f27f3ec4feb6b9d85d91d8368ee9d25 Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Thu, 18 Sep 2014 18:38:04 +0200 +Subject: [PATCH] procfs: implement /proc/N/maps + +* procfs/process.c (process_file_gc_maps): New function. +(entries): Use the new function to implement /proc/N/maps. +--- + procfs/process.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 95 insertions(+) + +diff --git a/procfs/process.c b/procfs/process.c +index 4854148..feb68ff 100644 +--- a/procfs/process.c ++++ b/procfs/process.c +@@ -109,6 +109,93 @@ 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); ++ ++ 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) ++ { ++ mach_port_deallocate (mach_task_self (), objects->port); ++ objects = objects->next; ++ } ++ ++ /* 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 +435,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 + diff --git a/debian/patches/series b/debian/patches/series index 5f063904..3097cc18 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -60,3 +60,4 @@ mach-defpager-protected-payload.patch #0002-libports-lock-less-reference-counting-for-port_info-.patch 0001-libdiskfs-remove-code-counting-cache-misses.patch trans-crash-add-verbose.patch +procfs-maps.patch |