Home | History | Annotate | Line # | Download | only in uvm
uvm_coredump.c revision 1.1.18.1
      1  1.1.18.1  jruoho /*	$NetBSD: uvm_coredump.c,v 1.1.18.1 2011/06/06 09:10:21 jruoho Exp $	*/
      2       1.1      ad 
      3       1.1      ad /*
      4       1.1      ad  * Copyright (c) 1997 Charles D. Cranor and Washington University.
      5       1.1      ad  * Copyright (c) 1991, 1993, The Regents of the University of California.
      6       1.1      ad  *
      7       1.1      ad  * All rights reserved.
      8       1.1      ad  *
      9       1.1      ad  * This code is derived from software contributed to Berkeley by
     10       1.1      ad  * The Mach Operating System project at Carnegie-Mellon University.
     11       1.1      ad  *
     12       1.1      ad  * Redistribution and use in source and binary forms, with or without
     13       1.1      ad  * modification, are permitted provided that the following conditions
     14       1.1      ad  * are met:
     15       1.1      ad  * 1. Redistributions of source code must retain the above copyright
     16       1.1      ad  *    notice, this list of conditions and the following disclaimer.
     17       1.1      ad  * 2. Redistributions in binary form must reproduce the above copyright
     18       1.1      ad  *    notice, this list of conditions and the following disclaimer in the
     19       1.1      ad  *    documentation and/or other materials provided with the distribution.
     20  1.1.18.1  jruoho  * 3. Neither the name of the University nor the names of its contributors
     21       1.1      ad  *    may be used to endorse or promote products derived from this software
     22       1.1      ad  *    without specific prior written permission.
     23       1.1      ad  *
     24       1.1      ad  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     25       1.1      ad  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     26       1.1      ad  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     27       1.1      ad  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     28       1.1      ad  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     29       1.1      ad  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     30       1.1      ad  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     31       1.1      ad  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     32       1.1      ad  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     33       1.1      ad  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     34       1.1      ad  * SUCH DAMAGE.
     35       1.1      ad  *
     36       1.1      ad  *	@(#)vm_glue.c	8.6 (Berkeley) 1/5/94
     37       1.1      ad  * from: Id: uvm_glue.c,v 1.1.2.8 1998/02/07 01:16:54 chs Exp
     38       1.1      ad  *
     39       1.1      ad  *
     40       1.1      ad  * Copyright (c) 1987, 1990 Carnegie-Mellon University.
     41       1.1      ad  * All rights reserved.
     42       1.1      ad  *
     43       1.1      ad  * Permission to use, copy, modify and distribute this software and
     44       1.1      ad  * its documentation is hereby granted, provided that both the copyright
     45       1.1      ad  * notice and this permission notice appear in all copies of the
     46       1.1      ad  * software, derivative works or modified versions, and any portions
     47       1.1      ad  * thereof, and that both notices appear in supporting documentation.
     48       1.1      ad  *
     49       1.1      ad  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     50       1.1      ad  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
     51       1.1      ad  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     52       1.1      ad  *
     53       1.1      ad  * Carnegie Mellon requests users of this software to return to
     54       1.1      ad  *
     55       1.1      ad  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     56       1.1      ad  *  School of Computer Science
     57       1.1      ad  *  Carnegie Mellon University
     58       1.1      ad  *  Pittsburgh PA 15213-3890
     59       1.1      ad  *
     60       1.1      ad  * any improvements or extensions that they make and grant Carnegie the
     61       1.1      ad  * rights to redistribute these changes.
     62       1.1      ad  */
     63       1.1      ad 
     64       1.1      ad #include <sys/cdefs.h>
     65  1.1.18.1  jruoho __KERNEL_RCSID(0, "$NetBSD: uvm_coredump.c,v 1.1.18.1 2011/06/06 09:10:21 jruoho Exp $");
     66       1.1      ad 
     67       1.1      ad /*
     68       1.1      ad  * uvm_coredump.c: glue functions for coredump
     69       1.1      ad  */
     70       1.1      ad 
     71       1.1      ad #include <sys/param.h>
     72       1.1      ad #include <sys/systm.h>
     73       1.1      ad #include <sys/proc.h>
     74       1.1      ad 
     75       1.1      ad #include <uvm/uvm.h>
     76       1.1      ad 
     77       1.1      ad /*
     78       1.1      ad  * uvm_coredump_walkmap: walk a process's map for the purpose of dumping
     79       1.1      ad  * a core file.
     80       1.1      ad  */
     81       1.1      ad 
     82       1.1      ad int
     83       1.1      ad uvm_coredump_walkmap(struct proc *p, void *iocookie,
     84       1.1      ad     int (*func)(struct proc *, void *, struct uvm_coredump_state *),
     85       1.1      ad     void *cookie)
     86       1.1      ad {
     87       1.1      ad 	struct uvm_coredump_state state;
     88       1.1      ad 	struct vmspace *vm = p->p_vmspace;
     89       1.1      ad 	struct vm_map *map = &vm->vm_map;
     90       1.1      ad 	struct vm_map_entry *entry;
     91       1.1      ad 	int error;
     92       1.1      ad 
     93       1.1      ad 	entry = NULL;
     94       1.1      ad 	vm_map_lock_read(map);
     95       1.1      ad 	state.end = 0;
     96       1.1      ad 	for (;;) {
     97       1.1      ad 		if (entry == NULL)
     98       1.1      ad 			entry = map->header.next;
     99       1.1      ad 		else if (!uvm_map_lookup_entry(map, state.end, &entry))
    100       1.1      ad 			entry = entry->next;
    101       1.1      ad 		if (entry == &map->header)
    102       1.1      ad 			break;
    103       1.1      ad 
    104       1.1      ad 		state.cookie = cookie;
    105       1.1      ad 		if (state.end > entry->start) {
    106       1.1      ad 			state.start = state.end;
    107       1.1      ad 		} else {
    108       1.1      ad 			state.start = entry->start;
    109       1.1      ad 		}
    110       1.1      ad 		state.realend = entry->end;
    111       1.1      ad 		state.end = entry->end;
    112       1.1      ad 		state.prot = entry->protection;
    113       1.1      ad 		state.flags = 0;
    114       1.1      ad 
    115       1.1      ad 		/*
    116       1.1      ad 		 * Dump the region unless one of the following is true:
    117       1.1      ad 		 *
    118       1.1      ad 		 * (1) the region has neither object nor amap behind it
    119       1.1      ad 		 *     (ie. it has never been accessed).
    120       1.1      ad 		 *
    121       1.1      ad 		 * (2) the region has no amap and is read-only
    122       1.1      ad 		 *     (eg. an executable text section).
    123       1.1      ad 		 *
    124       1.1      ad 		 * (3) the region's object is a device.
    125       1.1      ad 		 *
    126       1.1      ad 		 * (4) the region is unreadable by the process.
    127       1.1      ad 		 */
    128       1.1      ad 
    129       1.1      ad 		KASSERT(!UVM_ET_ISSUBMAP(entry));
    130       1.1      ad 		KASSERT(state.start < VM_MAXUSER_ADDRESS);
    131       1.1      ad 		KASSERT(state.end <= VM_MAXUSER_ADDRESS);
    132       1.1      ad 		if (entry->object.uvm_obj == NULL &&
    133       1.1      ad 		    entry->aref.ar_amap == NULL) {
    134       1.1      ad 			state.realend = state.start;
    135       1.1      ad 		} else if ((entry->protection & VM_PROT_WRITE) == 0 &&
    136       1.1      ad 		    entry->aref.ar_amap == NULL) {
    137       1.1      ad 			state.realend = state.start;
    138       1.1      ad 		} else if (entry->object.uvm_obj != NULL &&
    139       1.1      ad 		    UVM_OBJ_IS_DEVICE(entry->object.uvm_obj)) {
    140       1.1      ad 			state.realend = state.start;
    141       1.1      ad 		} else if ((entry->protection & VM_PROT_READ) == 0) {
    142       1.1      ad 			state.realend = state.start;
    143       1.1      ad 		} else {
    144       1.1      ad 			if (state.start >= (vaddr_t)vm->vm_maxsaddr)
    145       1.1      ad 				state.flags |= UVM_COREDUMP_STACK;
    146       1.1      ad 
    147       1.1      ad 			/*
    148       1.1      ad 			 * If this an anonymous entry, only dump instantiated
    149       1.1      ad 			 * pages.
    150       1.1      ad 			 */
    151       1.1      ad 			if (entry->object.uvm_obj == NULL) {
    152       1.1      ad 				vaddr_t end;
    153       1.1      ad 
    154       1.1      ad 				amap_lock(entry->aref.ar_amap);
    155       1.1      ad 				for (end = state.start;
    156       1.1      ad 				     end < state.end; end += PAGE_SIZE) {
    157       1.1      ad 					struct vm_anon *anon;
    158       1.1      ad 					anon = amap_lookup(&entry->aref,
    159       1.1      ad 					    end - entry->start);
    160       1.1      ad 					/*
    161       1.1      ad 					 * If we have already encountered an
    162       1.1      ad 					 * uninstantiated page, stop at the
    163       1.1      ad 					 * first instantied page.
    164       1.1      ad 					 */
    165       1.1      ad 					if (anon != NULL &&
    166       1.1      ad 					    state.realend != state.end) {
    167       1.1      ad 						state.end = end;
    168       1.1      ad 						break;
    169       1.1      ad 					}
    170       1.1      ad 
    171       1.1      ad 					/*
    172       1.1      ad 					 * If this page is the first
    173       1.1      ad 					 * uninstantiated page, mark this as
    174       1.1      ad 					 * the real ending point.  Continue to
    175       1.1      ad 					 * counting uninstantiated pages.
    176       1.1      ad 					 */
    177       1.1      ad 					if (anon == NULL &&
    178       1.1      ad 					    state.realend == state.end) {
    179       1.1      ad 						state.realend = end;
    180       1.1      ad 					}
    181       1.1      ad 				}
    182       1.1      ad 				amap_unlock(entry->aref.ar_amap);
    183       1.1      ad 			}
    184       1.1      ad 		}
    185       1.1      ad 
    186       1.1      ad 
    187       1.1      ad 		vm_map_unlock_read(map);
    188       1.1      ad 		error = (*func)(p, iocookie, &state);
    189       1.1      ad 		if (error)
    190       1.1      ad 			return (error);
    191       1.1      ad 		vm_map_lock_read(map);
    192       1.1      ad 	}
    193       1.1      ad 	vm_map_unlock_read(map);
    194       1.1      ad 
    195       1.1      ad 	return (0);
    196       1.1      ad }
    197