Index: sys_process.c =================================================================== RCS file: /sources/netbsd/NetBSD-cvs/syssrc/sys/kern/sys_process.c,v retrieving revision 1.75 diff -u -u -w -r1.75 sys_process.c --- sys_process.c 2002/07/25 20:04:02 1.75 +++ sys_process.c 2002/08/06 17:07:44 @@ -64,6 +64,7 @@ #include #include #include +#include #include #include @@ -71,9 +72,13 @@ #include #include +#include #include +int proc_vnode_to_path(struct vnode *, char *, int, + struct proc *, struct proc *); + /* Macros to clear/set/test flags. */ #define SET(t, f) (t) |= (f) #define CLR(t, f) (t) &= ~(f) @@ -174,6 +179,7 @@ case PT_IO: case PT_KILL: case PT_DETACH: + case PT_MEMMAP: #ifdef PT_STEP case PT_STEP: #endif @@ -436,6 +442,113 @@ return (process_dofpregs(p, t, &uio)); } #endif + + case PT_MEMMAP: + { + struct ptrace_mem_map_desc *desc; + struct vm_map *map = &t->p_vmspace->vm_map; + struct vm_map_entry *entry; + char *path; + int len; + + desc = malloc(sizeof(*desc) + MAXPATHLEN * 4, + M_TEMP, M_WAITOK); + path = ((char *)desc) + sizeof(*desc); + *path = 0; + + if (map == &curproc->p_vmspace->vm_map) { + free(path, M_TEMP); + return EDEADLK; + } + + vm_map_lock_read(map); + + iov.iov_base = SCARG(uap, addr); + iov.iov_len = SCARG(uap, data); + uio.uio_iovcnt = 1; + 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) { + + 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; + + if (UVM_ET_ISOBJ(entry) && + UVM_OBJ_IS_VNODE(entry->object.uvm_obj)) { + struct vnode *vp; + + vp = (struct vnode *) + entry->object.uvm_obj; + + desc->pmmd_flags |= PMMD_OBJECT; + error = proc_vnode_to_path(vp, path, + MAXPATHLEN * 4, curproc, t); + if (error == 0) { + len = strlen(path); + memset(path + len, 0, + MIN(MAXPATHLEN * 4 - len, + ALIGNBYTES + 1)); + len = ALIGN(len + 1); + } else { + len = ALIGN(1); + memset(path, 0, len); + } + } else + len = 0; + + if (sizeof(*desc) + len > uio.uio_resid) { + error = ENOMEM; + break; + } + + error = uiomove(desc, + sizeof(*desc) + len, &uio); + if (error) + break; + } + vm_map_unlock_read(map); + free(desc, M_TEMP); + + return (error); + } #ifdef __HAVE_PTRACE_MACHDEP PTRACE_MACHDEP_REQUEST_CASES