xref: /netbsd-src/sys/kern/core_netbsd.c (revision ba65fde2d7fefa7d39838fa5fa855e62bd606b5e)
1 /*	$NetBSD: core_netbsd.c,v 1.18 2011/02/02 20:10:09 chuck Exp $	*/
2 
3 /*
4  * Copyright (c) 1997 Charles D. Cranor and Washington University.
5  * Copyright (c) 1991, 1993 The Regents of the University of California.
6  * Copyright (c) 1988 University of Utah.
7  *
8  * All rights reserved.
9  *
10  * This code is derived from software contributed to Berkeley by
11  * the Systems Programming Group of the University of Utah Computer
12  * Science Department.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  * 3. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  * from: Utah $Hdr: vm_unix.c 1.1 89/11/07$
39  *      @(#)vm_unix.c   8.1 (Berkeley) 6/11/93
40  * from: NetBSD: uvm_unix.c,v 1.25 2001/11/10 07:37:01 lukem Exp
41  */
42 
43 /*
44  * core_netbsd.c: Support for the historic NetBSD core file format.
45  */
46 
47 #include <sys/cdefs.h>
48 __KERNEL_RCSID(0, "$NetBSD: core_netbsd.c,v 1.18 2011/02/02 20:10:09 chuck Exp $");
49 
50 #ifdef _KERNEL_OPT
51 #include "opt_coredump.h"
52 #endif
53 
54 #include <sys/param.h>
55 #include <sys/systm.h>
56 #include <sys/exec.h>
57 #include <sys/proc.h>
58 #include <sys/vnode.h>
59 #include <sys/core.h>
60 
61 #include <uvm/uvm_extern.h>
62 
63 #ifndef CORENAME
64 #define	CORENAME(x)	x
65 #endif
66 #ifdef COREINC
67 #include COREINC
68 #endif
69 
70 #ifdef COREDUMP
71 
72 struct coredump_state {
73 	struct CORENAME(core) core;
74 };
75 
76 static int	CORENAME(coredump_countsegs_netbsd)(struct proc *, void *,
77 		    struct uvm_coredump_state *);
78 static int	CORENAME(coredump_writesegs_netbsd)(struct proc *, void *,
79 		    struct uvm_coredump_state *);
80 
81 int
82 CORENAME(coredump_netbsd)(struct lwp *l, void *iocookie)
83 {
84 	struct coredump_state cs;
85 	struct proc *p = l->l_proc;
86 	struct vmspace *vm = p->p_vmspace;
87 	int error;
88 
89 	cs.core.c_midmag = 0;
90 	strncpy(cs.core.c_name, p->p_comm, MAXCOMLEN);
91 	cs.core.c_nseg = 0;
92 	cs.core.c_signo = p->p_sigctx.ps_signo;
93 	cs.core.c_ucode = p->p_sigctx.ps_code;
94 	cs.core.c_cpusize = 0;
95 	cs.core.c_tsize = (u_long)ctob(vm->vm_tsize);
96 	cs.core.c_dsize = (u_long)ctob(vm->vm_dsize);
97 	cs.core.c_ssize = (u_long)round_page(ctob(vm->vm_ssize));
98 
99 	error = CORENAME(cpu_coredump)(l, NULL, &cs.core);
100 	if (error)
101 		return (error);
102 	error = uvm_coredump_walkmap(p, NULL,
103 	    CORENAME(coredump_countsegs_netbsd), &cs);
104 	if (error)
105 		return (error);
106 
107 	/* First write out the core header. */
108 	error = coredump_write(iocookie, UIO_SYSSPACE, &cs.core,
109 	    cs.core.c_hdrsize);
110 	if (error)
111 		return (error);
112 
113 	/* Then the CPU specific stuff */
114 	error = CORENAME(cpu_coredump)(l, iocookie, &cs.core);
115 	if (error)
116 		return (error);
117 
118 	/* Finally, the address space dump */
119 	return uvm_coredump_walkmap(p, iocookie,
120 	    CORENAME(coredump_writesegs_netbsd), &cs);
121 }
122 
123 static int
124 CORENAME(coredump_countsegs_netbsd)(struct proc *p, void *iocookie,
125     struct uvm_coredump_state *us)
126 {
127 	struct coredump_state *cs = us->cookie;
128 
129 	if (us->start != us->realend)
130 		cs->core.c_nseg++;
131 
132 	return (0);
133 }
134 
135 static int
136 CORENAME(coredump_writesegs_netbsd)(struct proc *p, void *iocookie,
137     struct uvm_coredump_state *us)
138 {
139 	struct coredump_state *cs = us->cookie;
140 	struct CORENAME(coreseg) cseg;
141 	int flag, error;
142 
143 	if (us->start == us->realend)
144 		return (0);
145 
146 	if (us->flags & UVM_COREDUMP_STACK)
147 		flag = CORE_STACK;
148 	else
149 		flag = CORE_DATA;
150 
151 	/*
152 	 * Set up a new core file segment.
153 	 */
154 	CORE_SETMAGIC(cseg, CORESEGMAGIC, CORE_GETMID(cs->core), flag);
155 	cseg.c_addr = us->start;
156 	cseg.c_size = us->end - us->start;
157 
158 	error = coredump_write(iocookie, UIO_SYSSPACE,
159 	    &cseg, cs->core.c_seghdrsize);
160 	if (error)
161 		return (error);
162 
163 	return coredump_write(iocookie, UIO_USERSPACE,
164 	    (void *)(vaddr_t)us->start, cseg.c_size);
165 }
166 
167 #else	/* COREDUMP */
168 
169 int
170 CORENAME(coredump_netbsd)(struct lwp *l, void *cookie)
171 {
172 
173 	return ENOSYS;
174 }
175 
176 #endif	/* COREDUMP */
177