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