procfs_map.c revision 16468
116468Sdyson/*
216468Sdyson * Copyright (c) 1993 Jan-Simon Pendry
316468Sdyson * Copyright (c) 1993
416468Sdyson *	The Regents of the University of California.  All rights reserved.
516468Sdyson *
616468Sdyson * This code is derived from software contributed to Berkeley by
716468Sdyson * Jan-Simon Pendry.
816468Sdyson *
916468Sdyson * Redistribution and use in source and binary forms, with or without
1016468Sdyson * modification, are permitted provided that the following conditions
1116468Sdyson * are met:
1216468Sdyson * 1. Redistributions of source code must retain the above copyright
1316468Sdyson *    notice, this list of conditions and the following disclaimer.
1416468Sdyson * 2. Redistributions in binary form must reproduce the above copyright
1516468Sdyson *    notice, this list of conditions and the following disclaimer in the
1616468Sdyson *    documentation and/or other materials provided with the distribution.
1716468Sdyson * 3. All advertising materials mentioning features or use of this software
1816468Sdyson *    must display the following acknowledgement:
1916468Sdyson *	This product includes software developed by the University of
2016468Sdyson *	California, Berkeley and its contributors.
2116468Sdyson * 4. Neither the name of the University nor the names of its contributors
2216468Sdyson *    may be used to endorse or promote products derived from this software
2316468Sdyson *    without specific prior written permission.
2416468Sdyson *
2516468Sdyson * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2616468Sdyson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2716468Sdyson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2816468Sdyson * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2916468Sdyson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3016468Sdyson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3116468Sdyson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3216468Sdyson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3316468Sdyson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3416468Sdyson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3516468Sdyson * SUCH DAMAGE.
3616468Sdyson *
3716468Sdyson *	@(#)procfs_status.c	8.3 (Berkeley) 2/17/94
3816468Sdyson *
3916468Sdyson *	$Id: procfs_status.c,v 1.5 1996/02/02 05:19:20 wosch Exp $
4016468Sdyson */
4116468Sdyson
4216468Sdyson#include <sys/param.h>
4316468Sdyson#include <sys/systm.h>
4416468Sdyson#include <sys/time.h>
4516468Sdyson#include <sys/kernel.h>
4616468Sdyson#include <sys/proc.h>
4716468Sdyson#include <sys/vnode.h>
4816468Sdyson#include <sys/ioctl.h>
4916468Sdyson#include <sys/tty.h>
5016468Sdyson#include <sys/resource.h>
5116468Sdyson#include <sys/resourcevar.h>
5216468Sdyson#include <miscfs/procfs/procfs.h>
5316468Sdyson#include <sys/queue.h>
5416468Sdyson#include <sys/vmmeter.h>
5516468Sdyson#include <sys/mman.h>
5616468Sdyson
5716468Sdyson#include <vm/vm.h>
5816468Sdyson#include <vm/vm_param.h>
5916468Sdyson#include <vm/vm_prot.h>
6016468Sdyson#include <vm/vm_inherit.h>
6116468Sdyson#include <vm/lock.h>
6216468Sdyson#include <vm/pmap.h>
6316468Sdyson#include <vm/vm_map.h>
6416468Sdyson#include <vm/vm_page.h>
6516468Sdyson#include <vm/vm_object.h>
6616468Sdyson#include <vm/vm_kern.h>
6716468Sdyson#include <vm/vm_pager.h>
6816468Sdyson#include <vm/vm_extern.h>
6916468Sdyson#include <vm/default_pager.h>
7016468Sdyson
7116468Sdyson
7216468Sdyson#define MAXKBUFFER 16384
7316468Sdyson
7416468Sdysonint
7516468Sdysonprocfs_domap(curp, p, pfs, uio)
7616468Sdyson	struct proc *curp;
7716468Sdyson	struct proc *p;
7816468Sdyson	struct pfsnode *pfs;
7916468Sdyson	struct uio *uio;
8016468Sdyson{
8116468Sdyson	int len;
8216468Sdyson	int error;
8316468Sdyson	/*
8416468Sdyson	 * dynamically allocated buffer for entire snapshot
8516468Sdyson	 */
8616468Sdyson	char *kbuffer, *kbufferp;
8716468Sdyson	/*
8816468Sdyson	 * buffer for each map entry
8916468Sdyson	 */
9016468Sdyson	char mebuffer[256];
9116468Sdyson	vm_map_t map = &p->p_vmspace->vm_map;
9216468Sdyson	pmap_t pmap = &p->p_vmspace->vm_pmap;
9316468Sdyson	vm_map_entry_t entry;
9416468Sdyson
9516468Sdyson	if (uio->uio_rw != UIO_READ)
9616468Sdyson		return (EOPNOTSUPP);
9716468Sdyson
9816468Sdyson	if (uio->uio_offset != 0)
9916468Sdyson		return (0);
10016468Sdyson
10116468Sdyson	kbuffer = (char *)kmem_alloc_pageable(kernel_map, MAXKBUFFER);
10216468Sdyson	kbufferp = kbuffer;
10316468Sdyson	vm_map_lock(map);
10416468Sdyson	for (entry = map->header.next; entry != &map->header;
10516468Sdyson		entry = entry->next) {
10616468Sdyson		vm_object_t obj, tobj, lobj;
10716468Sdyson		vm_offset_t addr;
10816468Sdyson		int resident, privateresident;
10916468Sdyson		char *type;
11016468Sdyson
11116468Sdyson		if (entry->is_a_map || entry->is_sub_map)
11216468Sdyson			continue;
11316468Sdyson
11416468Sdyson		obj = entry->object.vm_object;
11516468Sdyson		if (obj && (obj->ref_count == 1))
11616468Sdyson			privateresident = obj->resident_page_count;
11716468Sdyson		else
11816468Sdyson			privateresident = 0;
11916468Sdyson
12016468Sdyson		resident = 0;
12116468Sdyson		addr = entry->start;
12216468Sdyson		while (addr < entry->end) {
12316468Sdyson			if (pmap_extract( pmap, addr))
12416468Sdyson				resident++;
12516468Sdyson			addr += PAGE_SIZE;
12616468Sdyson		}
12716468Sdyson
12816468Sdyson		for( lobj = tobj = obj; tobj; tobj = tobj->backing_object)
12916468Sdyson			lobj = tobj;
13016468Sdyson
13116468Sdyson		switch(lobj->type) {
13216468Sdyson
13316468Sdysondefault:
13416468Sdysoncase OBJT_DEFAULT:
13516468Sdyson			type = "default";
13616468Sdyson			break;
13716468Sdysoncase OBJT_VNODE:
13816468Sdyson			type = "vnode";
13916468Sdyson			break;
14016468Sdysoncase OBJT_SWAP:
14116468Sdyson			type = "swap";
14216468Sdyson			break;
14316468Sdysoncase OBJT_DEVICE:
14416468Sdyson			type = "device";
14516468Sdyson			break;
14616468Sdyson		}
14716468Sdyson
14816468Sdyson		/*
14916468Sdyson		 * format:
15016468Sdyson		 *  start, end, resident, private resident, cow, access, type.
15116468Sdyson		 */
15216468Sdyson		sprintf(mebuffer, "0x%-8.8x 0x%-8.8x %9d %9d %s %s %s\n",
15316468Sdyson			entry->start, entry->end,
15416468Sdyson			resident, privateresident,
15516468Sdyson			(entry->protection & VM_PROT_WRITE)?"RW":"RO",
15616468Sdyson			entry->copy_on_write?"COW":"   ",
15716468Sdyson			type);
15816468Sdyson
15916468Sdyson		len = strlen(mebuffer);
16016468Sdyson		if (len + (kbufferp - kbuffer) < MAXKBUFFER) {
16116468Sdyson			memcpy(kbufferp, mebuffer, len);
16216468Sdyson			kbufferp += len;
16316468Sdyson		}
16416468Sdyson	}
16516468Sdyson	vm_map_unlock(map);
16616468Sdyson	error = uiomove(kbuffer, (kbufferp - kbuffer), uio);
16716468Sdyson	kmem_free(kernel_map, (vm_offset_t)kbuffer, MAXKBUFFER);
16816468Sdyson	return error;
16916468Sdyson}
170