summaryrefslogtreecommitdiffstats
path: root/sys/compat/linprocfs
diff options
context:
space:
mode:
authorcognet <cognet@FreeBSD.org>2003-10-19 14:13:51 +0000
committercognet <cognet@FreeBSD.org>2003-10-19 14:13:51 +0000
commit82c805f9172c25949e91a6e246eb34df1f2ab858 (patch)
tree4e6d3742155444b7b300c9cb1a7a41a9f4307237 /sys/compat/linprocfs
parentd5e5722561c045dd33c5b3f203dfb7c2d3446859 (diff)
downloadFreeBSD-src-82c805f9172c25949e91a6e246eb34df1f2ab858.zip
FreeBSD-src-82c805f9172c25949e91a6e246eb34df1f2ab858.tar.gz
Implement partially /proc/<pid>/maps.
It looks enough to make SImics run. Reviewed by: des
Diffstat (limited to 'sys/compat/linprocfs')
-rw-r--r--sys/compat/linprocfs/linprocfs.c101
1 files changed, 96 insertions, 5 deletions
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
index cc1eea0..a472f24 100644
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -822,11 +822,102 @@ linprocfs_doprocenviron(PFS_FILL_ARGS)
static int
linprocfs_doprocmaps(PFS_FILL_ARGS)
{
- sbuf_printf(sb, "doprocmaps\n%c", '\0');
-
- return (0);
-}
-
+ int len;
+ int error;
+ int ino;
+ vm_map_t map = &p->p_vmspace->vm_map;
+ vm_map_entry_t entry;
+ char mebuffer[512];
+
+
+ PROC_LOCK(p);
+ error = p_candebug(td, p);
+ PROC_UNLOCK(p);
+ if (error)
+ return (error);
+
+ if (uio->uio_rw != UIO_READ)
+ return (EOPNOTSUPP);
+
+ if (uio->uio_offset != 0)
+ return (0);
+
+ error = 0;
+ if (map != &curthread->td_proc->p_vmspace->vm_map)
+ vm_map_lock_read(map);
+ for (entry = map->header.next;
+ ((uio->uio_resid > 0) && (entry != &map->header));
+ entry = entry->next) {
+ vm_object_t obj, tobj, lobj;
+ int ref_count, shadow_count, flags;
+ int shared;
+ vm_ooffset_t off = 0;
+ char *name = "", *freename = NULL;
+
+ if (entry->eflags & MAP_ENTRY_IS_SUB_MAP)
+ continue;
+
+ obj = entry->object.vm_object;
+ for (lobj = tobj = obj; tobj; tobj = tobj->backing_object)
+ lobj = tobj;
+
+ ino = 0;
+ if (lobj) {
+ VM_OBJECT_LOCK(lobj);
+ off = IDX_TO_OFF(lobj->size);
+ if (lobj->type == OBJT_VNODE && lobj->handle) {
+ vn_fullpath(td, (struct vnode *)lobj->handle,
+ &name, &freename);
+ ino = ((struct vnode *)
+ lobj->handle)->v_cachedid;
+ }
+ flags = obj->flags;
+ ref_count = obj->ref_count;
+ shadow_count = obj->shadow_count;
+ VM_OBJECT_UNLOCK(lobj);
+ } else {
+ shared = 0;
+ flags = 0;
+ ref_count = 0;
+ shadow_count = 0;
+ }
+
+ /*
+ * format:
+ * start, end, access, offset, major, minor, inode, name.
+ */
+ snprintf(mebuffer, sizeof mebuffer,
+ "%08lx-%08lx %s%s%s%s %08lx %02x:%02x %lu%s%s\n",
+ (u_long)entry->start, (u_long)entry->end,
+ (entry->protection & VM_PROT_READ)?"r":"-",
+ (entry->protection & VM_PROT_WRITE)?"w":"-",
+ (entry->protection & VM_PROT_EXECUTE)?"x":"-",
+ "p",
+ (u_long) off,
+ 0,
+ 0,
+ (u_long) ino,
+ *name ? " " : "",
+ name
+ );
+ if (freename)
+ free(freename, M_TEMP);
+ len = strlen(mebuffer);
+ if (len > uio->uio_resid)
+ len = uio->uio_resid; /*
+ * XXX We should probably return
+ * EFBIG here, as in procfs.
+ */
+ error = uiomove(mebuffer, len, uio);
+ if (error)
+ break;
+ }
+ if (map != &curthread->td_proc->p_vmspace->vm_map)
+ vm_map_unlock_read(map);
+
+ return (error);
+}
+
/*
* Filler function for proc/net/dev
*/
OpenPOWER on IntegriCloud