svn commit: r204813 - in stable/8/sys: kern sys
Marcel Moolenaar
marcel at FreeBSD.org
Sun Mar 7 00:05:45 UTC 2010
Author: marcel
Date: Sun Mar 7 00:05:44 2010
New Revision: 204813
URL: http://svn.freebsd.org/changeset/base/204813
Log:
MFC revs 203696, 203708, 203783 and 203788:
Add PT_VM_TIMESTAMP and PT_VM_ENTRY so that the tracing process can
obtain the memory map of the traced process.
Requested by: kib@
Modified:
stable/8/sys/kern/sys_process.c
stable/8/sys/sys/ptrace.h
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
stable/8/sys/netinet/ (props changed)
Modified: stable/8/sys/kern/sys_process.c
==============================================================================
--- stable/8/sys/kern/sys_process.c Sat Mar 6 23:01:10 2010 (r204812)
+++ stable/8/sys/kern/sys_process.c Sun Mar 7 00:05:44 2010 (r204813)
@@ -72,6 +72,20 @@ struct ptrace_io_desc32 {
u_int32_t piod_addr;
u_int32_t piod_len;
};
+
+struct ptrace_vm_entry32 {
+ int pve_entry;
+ int pve_timestamp;
+ uint32_t pve_start;
+ uint32_t pve_end;
+ uint32_t pve_offset;
+ u_int pve_prot;
+ u_int pve_pathlen;
+ int32_t pve_fileid;
+ u_int pve_fsid;
+ uint32_t pve_path;
+};
+
#endif
/*
@@ -339,6 +353,148 @@ proc_rwmem(struct proc *p, struct uio *u
return (error);
}
+static int
+ptrace_vm_entry(struct thread *td, struct proc *p, struct ptrace_vm_entry *pve)
+{
+ struct vattr vattr;
+ vm_map_t map;
+ vm_map_entry_t entry;
+ vm_object_t obj, tobj, lobj;
+ struct vmspace *vm;
+ struct vnode *vp;
+ char *freepath, *fullpath;
+ u_int pathlen;
+ int error, index, vfslocked;
+
+ error = 0;
+ obj = NULL;
+
+ vm = vmspace_acquire_ref(p);
+ map = &vm->vm_map;
+ vm_map_lock_read(map);
+
+ do {
+ entry = map->header.next;
+ index = 0;
+ while (index < pve->pve_entry && entry != &map->header) {
+ entry = entry->next;
+ index++;
+ }
+ if (index != pve->pve_entry) {
+ error = EINVAL;
+ break;
+ }
+ while (entry != &map->header &&
+ (entry->eflags & MAP_ENTRY_IS_SUB_MAP) != 0) {
+ entry = entry->next;
+ index++;
+ }
+ if (entry == &map->header) {
+ error = ENOENT;
+ break;
+ }
+
+ /* We got an entry. */
+ pve->pve_entry = index + 1;
+ pve->pve_timestamp = map->timestamp;
+ pve->pve_start = entry->start;
+ pve->pve_end = entry->end - 1;
+ pve->pve_offset = entry->offset;
+ pve->pve_prot = entry->protection;
+
+ /* Backing object's path needed? */
+ if (pve->pve_pathlen == 0)
+ break;
+
+ pathlen = pve->pve_pathlen;
+ pve->pve_pathlen = 0;
+
+ obj = entry->object.vm_object;
+ if (obj != NULL)
+ VM_OBJECT_LOCK(obj);
+ } while (0);
+
+ vm_map_unlock_read(map);
+ vmspace_free(vm);
+
+ pve->pve_fsid = VNOVAL;
+ pve->pve_fileid = VNOVAL;
+
+ if (error == 0 && obj != NULL) {
+ lobj = obj;
+ for (tobj = obj; tobj != NULL; tobj = tobj->backing_object) {
+ if (tobj != obj)
+ VM_OBJECT_LOCK(tobj);
+ if (lobj != obj)
+ VM_OBJECT_UNLOCK(lobj);
+ lobj = tobj;
+ pve->pve_offset += tobj->backing_object_offset;
+ }
+ vp = (lobj->type == OBJT_VNODE) ? lobj->handle : NULL;
+ if (vp != NULL)
+ vref(vp);
+ if (lobj != obj)
+ VM_OBJECT_UNLOCK(lobj);
+ VM_OBJECT_UNLOCK(obj);
+
+ if (vp != NULL) {
+ freepath = NULL;
+ fullpath = NULL;
+ vn_fullpath(td, vp, &fullpath, &freepath);
+ vfslocked = VFS_LOCK_GIANT(vp->v_mount);
+ vn_lock(vp, LK_SHARED | LK_RETRY);
+ if (VOP_GETATTR(vp, &vattr, td->td_ucred) == 0) {
+ pve->pve_fileid = vattr.va_fileid;
+ pve->pve_fsid = vattr.va_fsid;
+ }
+ vput(vp);
+ VFS_UNLOCK_GIANT(vfslocked);
+
+ if (fullpath != NULL) {
+ pve->pve_pathlen = strlen(fullpath) + 1;
+ if (pve->pve_pathlen <= pathlen) {
+ error = copyout(fullpath, pve->pve_path,
+ pve->pve_pathlen);
+ } else
+ error = ENAMETOOLONG;
+ }
+ if (freepath != NULL)
+ free(freepath, M_TEMP);
+ }
+ }
+
+ return (error);
+}
+
+#ifdef COMPAT_IA32
+static int
+ptrace_vm_entry32(struct thread *td, struct proc *p,
+ struct ptrace_vm_entry32 *pve32)
+{
+ struct ptrace_vm_entry pve;
+ int error;
+
+ pve.pve_entry = pve32->pve_entry;
+ pve.pve_pathlen = pve32->pve_pathlen;
+ pve.pve_path = (void *)(uintptr_t)pve32->pve_path;
+
+ error = ptrace_vm_entry(td, p, &pve);
+ if (error == 0) {
+ pve32->pve_entry = pve.pve_entry;
+ pve32->pve_timestamp = pve.pve_timestamp;
+ pve32->pve_start = pve.pve_start;
+ pve32->pve_end = pve.pve_end;
+ pve32->pve_offset = pve.pve_offset;
+ pve32->pve_prot = pve.pve_prot;
+ pve32->pve_fileid = pve.pve_fileid;
+ pve32->pve_fsid = pve.pve_fsid;
+ }
+
+ pve32->pve_pathlen = pve.pve_pathlen;
+ return (error);
+}
+#endif /* COMPAT_IA32 */
+
/*
* Process debugging system call.
*/
@@ -382,6 +538,7 @@ ptrace(struct thread *td, struct ptrace_
union {
struct ptrace_io_desc piod;
struct ptrace_lwpinfo pl;
+ struct ptrace_vm_entry pve;
struct dbreg dbreg;
struct fpreg fpreg;
struct reg reg;
@@ -390,6 +547,7 @@ ptrace(struct thread *td, struct ptrace_
struct fpreg32 fpreg32;
struct reg32 reg32;
struct ptrace_io_desc32 piod32;
+ struct ptrace_vm_entry32 pve32;
#endif
} r;
void *addr;
@@ -422,6 +580,9 @@ ptrace(struct thread *td, struct ptrace_
case PT_IO:
error = COPYIN(uap->addr, &r.piod, sizeof r.piod);
break;
+ case PT_VM_ENTRY:
+ error = COPYIN(uap->addr, &r.pve, sizeof r.pve);
+ break;
default:
addr = uap->addr;
break;
@@ -434,6 +595,9 @@ ptrace(struct thread *td, struct ptrace_
return (error);
switch (uap->req) {
+ case PT_VM_ENTRY:
+ error = COPYOUT(&r.pve, uap->addr, sizeof r.pve);
+ break;
case PT_IO:
error = COPYOUT(&r.piod, uap->addr, sizeof r.piod);
break;
@@ -970,6 +1134,21 @@ kern_ptrace(struct thread *td, int req,
PROC_LOCK(p);
break;
+ case PT_VM_TIMESTAMP:
+ td->td_retval[0] = p->p_vmspace->vm_map.timestamp;
+ break;
+
+ case PT_VM_ENTRY:
+ PROC_UNLOCK(p);
+#ifdef COMPAT_IA32
+ if (wrap32)
+ error = ptrace_vm_entry32(td, p, addr);
+ else
+#endif
+ error = ptrace_vm_entry(td, p, addr);
+ PROC_LOCK(p);
+ break;
+
default:
#ifdef __HAVE_PTRACE_MACHDEP
if (req >= PT_FIRSTMACH) {
Modified: stable/8/sys/sys/ptrace.h
==============================================================================
--- stable/8/sys/sys/ptrace.h Sat Mar 6 23:01:10 2010 (r204812)
+++ stable/8/sys/sys/ptrace.h Sun Mar 7 00:05:44 2010 (r204813)
@@ -67,6 +67,10 @@
#define PT_SETFPREGS 36 /* set floating-point registers */
#define PT_GETDBREGS 37 /* get debugging registers */
#define PT_SETDBREGS 38 /* set debugging registers */
+
+#define PT_VM_TIMESTAMP 40 /* Get VM version (timestamp) */
+#define PT_VM_ENTRY 41 /* Get VM map (entry) */
+
#define PT_FIRSTMACH 64 /* for machine-specific requests */
#include <machine/ptrace.h> /* machine-specific requests, if any */
@@ -98,6 +102,20 @@ struct ptrace_lwpinfo {
sigset_t pl_siglist; /* LWP pending signal */
};
+/* Argument structure for PT_VM_ENTRY. */
+struct ptrace_vm_entry {
+ int pve_entry; /* Entry number used for iteration. */
+ int pve_timestamp; /* Generation number of VM map. */
+ u_long pve_start; /* Start VA of range. */
+ u_long pve_end; /* End VA of range (incl). */
+ u_long pve_offset; /* Offset in backing object. */
+ u_int pve_prot; /* Protection of memory range. */
+ u_int pve_pathlen; /* Size of path. */
+ long pve_fileid; /* File ID. */
+ uint32_t pve_fsid; /* File system ID. */
+ char *pve_path; /* Path name of object. */
+};
+
#ifdef _KERNEL
#define PTRACESTOP_SC(p, td, flag) \
More information about the svn-src-all
mailing list