From f9a7b4adf54e44cf6859c1860283253fa7a098ac Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 29 Dec 2003 23:44:33 -0800 Subject: [PATCH] [PATCH] Put fixmaps into /proc/pid/maps via a pseudo-vma From: David Mosberger This patch makes /proc/PID/maps report the range from FIXADDR_USER_START to FIXADDR_USER_END as a final pseudo-vma. This is consistent with the notion that reading /proc/PID/maps tells you about every page containing data that the process can in fact access, and with things such as ptrace allowing access to this memory. Without this, userland tools that want to look at all of a process's accessible pages need special-case knowledge about things such as the vsyscall DSO page. With this change, existing code that iterates over the /proc/PID/maps lines will cover those pages like any other. For example, this lets gdb's "gcore" command synthesize a core file from a live process that contains the vsyscall DSO page as a real core dump would, using its existing generic iterator code and no new special cases. --- fs/proc/task_mmu.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index e3942b8879ca3..739ca9f198e90 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -1,6 +1,7 @@ #include #include #include +#include #include char *task_mem(struct mm_struct *mm, char *buffer) @@ -75,6 +76,22 @@ int task_statm(struct mm_struct *mm, int *shared, int *text, 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, loff_t *pos) 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, loff_t *pos) 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, void *v, loff_t *pos) if (map->vm_next) return map->vm_next; m_stop(m, v); + if (map != gate_map()) + return gate_map(); return NULL; } -- 2.53.0