Subject: Re: PT_MEMMAP
To: Gregory McGarry <g.mcgarry@ieee.org>
From: Love <lha@stacken.kth.se>
List: tech-kern
Date: 07/22/2002 11:35:27
Gregory McGarry <g.mcgarry@ieee.org> writes:
> Love wrote:
>
> > I want to add PT_MEMMAP to ptrace so gdb can get the memory mapping of a
> > process. A implemation are available in [1]. Patches for current gdb are in
> > [2].
[...]
>
> Do you want the memory map of the traced process or the parent process?
Of course I want the traced process, thanks. That explains why it couldn't
dump all memory regions. :)
I added an updated patch, I changed so you can't dump your own memory
mapping, but then you can't attach to yourself so that shouldn't be a
problem.
Love
Index: sys_process.c
===================================================================
RCS file: /sources/netbsd/NetBSD-cvs/syssrc/sys/kern/sys_process.c,v
retrieving revision 1.74
diff -u -u -w -r1.74 sys_process.c
--- sys_process.c 2002/05/09 15:44:45 1.74
+++ sys_process.c 2002/07/21 23:30:26
@@ -71,6 +71,7 @@
#include <sys/syscallargs.h>
#include <uvm/uvm_extern.h>
+#include <uvm/uvm.h>
#include <machine/reg.h>
@@ -174,6 +175,7 @@
case PT_IO:
case PT_KILL:
case PT_DETACH:
+ case PT_MEMMAP:
#ifdef PT_STEP
case PT_STEP:
#endif
@@ -436,6 +438,77 @@
return (process_dofpregs(p, t, &uio));
}
#endif
+
+ case PT_MEMMAP:
+ {
+ struct vm_map *map = &t->p_vmspace->vm_map;
+ struct vm_map_entry *entry;
+
+ if (map == &curproc->p_vmspace->vm_map)
+ return EDEADLK;
+
+ vm_map_lock_read(map);
+
+ iov.iov_base = SCARG(uap, addr);
+ iov.iov_len = SCARG(uap, data);
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+ uio.uio_offset = 0;
+ uio.uio_resid = SCARG(uap, data);
+ uio.uio_segflg = UIO_USERSPACE;
+ uio.uio_rw = UIO_READ;
+ uio.uio_procp = p;
+
+ for (entry = map->header.next;
+ entry != &map->header;
+ entry = entry->next) {
+ struct ptrace_mem_map_desc desc;
+
+ if (sizeof(desc) > uio.uio_resid) {
+ error = ENOMEM;
+ break;
+ }
+
+ memset(&desc, 0, sizeof(desc));
+
+ desc.pmmd_start = (void *)entry->start;
+ desc.pmmd_end = (void *)entry->end;
+
+ if (entry->protection & VM_PROT_READ)
+ desc.pmmd_flags |= PMMD_PROT_READ;
+ if (entry->protection & VM_PROT_WRITE)
+ desc.pmmd_flags |= PMMD_PROT_WRITE;
+ if (entry->protection & VM_PROT_EXECUTE)
+ desc.pmmd_flags |= PMMD_PROT_EXEC;
+
+ if (entry->max_protection & VM_PROT_READ)
+ desc.pmmd_flags |= PMMD_PROT_MAX_READ;
+ if (entry->max_protection & VM_PROT_WRITE)
+ desc.pmmd_flags |= PMMD_PROT_MAX_WRITE;
+ if (entry->max_protection & VM_PROT_EXECUTE)
+ desc.pmmd_flags |= PMMD_PROT_MAX_EXEC;
+
+ if (entry->etype & UVM_ET_COPYONWRITE)
+ desc.pmmd_flags |= PMMD_COW;
+ if (entry->etype & UVM_ET_NEEDSCOPY)
+ desc.pmmd_flags |= PMMD_NEEDCOPY;
+
+ desc.pmmd_wiredcount = entry->wired_count;
+ desc.pmmd_inheritance = entry->inheritance;
+ desc.pmmd_advice = entry->advice;
+
+ /* is this the last entry */
+ if (entry->next == &map->header)
+ desc.pmmd_flags |= PMMD_LAST_ENTRY;
+
+ error = uiomove(&desc, sizeof(desc), &uio);
+ if (error)
+ break;
+ }
+ vm_map_unlock_read(map);
+
+ return (error);
+ }
#ifdef __HAVE_PTRACE_MACHDEP
PTRACE_MACHDEP_REQUEST_CASES