From: David Mosberger <davidm@napali.hpl.hp.com>




 fs/proc/task_mmu.c |   23 ++++++++++++++++++++++-
 1 files changed, 22 insertions(+), 1 deletion(-)

diff -puN fs/proc/task_mmu.c~proc-pid-maps-gate_map fs/proc/task_mmu.c
--- 25/fs/proc/task_mmu.c~proc-pid-maps-gate_map	2003-12-21 22:06:43.000000000 -0800
+++ 25-akpm/fs/proc/task_mmu.c	2003-12-21 22:06:43.000000000 -0800
@@ -1,6 +1,7 @@
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
 #include <linux/seq_file.h>
+#include <asm/elf.h>
 #include <asm/uaccess.h>
 
 char *task_mem(struct mm_struct *mm, char *buffer)
@@ -75,6 +76,22 @@ int task_statm(struct mm_struct *mm, int
 	return size;
 }
 
+#ifdef AT_SYSINFO_EHDR
+
+static struct vm_area_struct gate_vmarea = {
+	/* Do _not_ mark this area as readable, cuz not the entire range may be readable
+	   (e.g., due to execute-only pages or holes) and the tools that read
+	   /proc/PID/maps should read the interesting bits from the gate-DSO file
+	   instead.  */
+	.vm_start = FIXADDR_USER_START,
+	.vm_end = FIXADDR_USER_END
+};
+
+# define gate_map()	&gate_vmarea
+#else
+# define gate_map()	NULL
+#endif
+
 static int show_map(struct seq_file *m, void *v)
 {
 	struct vm_area_struct *map = v;
@@ -128,6 +145,8 @@ static void *m_start(struct seq_file *m,
 	if (!map) {
 		up_read(&mm->mmap_sem);
 		mmput(mm);
+		if (l == -1)
+			map = gate_map();
 	}
 	return map;
 }
@@ -135,7 +154,7 @@ static void *m_start(struct seq_file *m,
 static void m_stop(struct seq_file *m, void *v)
 {
 	struct vm_area_struct *map = v;
-	if (map) {
+	if (map && map != gate_map()) {
 		struct mm_struct *mm = map->vm_mm;
 		up_read(&mm->mmap_sem);
 		mmput(mm);
@@ -149,6 +168,8 @@ static void *m_next(struct seq_file *m, 
 	if (map->vm_next)
 		return map->vm_next;
 	m_stop(m, v);
+	if (map != gate_map())
+		return gate_map();
 	return NULL;
 }
 

_