kvm.c revision 1.11.2.2 1 1.11.2.2 mycroft /*-
2 1.11.2.2 mycroft * Copyright (c) 1993 Christopher G. Demetriou
3 1.11.2.2 mycroft * Copyright (c) 1989 The Regents of the University of California.
4 1.11.2.2 mycroft * All rights reserved.
5 1.11.2.2 mycroft *
6 1.11.2.2 mycroft * Redistribution and use in source and binary forms, with or without
7 1.11.2.2 mycroft * modification, are permitted provided that the following conditions
8 1.11.2.2 mycroft * are met:
9 1.11.2.2 mycroft * 1. Redistributions of source code must retain the above copyright
10 1.11.2.2 mycroft * notice, this list of conditions and the following disclaimer.
11 1.11.2.2 mycroft * 2. Redistributions in binary form must reproduce the above copyright
12 1.11.2.2 mycroft * notice, this list of conditions and the following disclaimer in the
13 1.11.2.2 mycroft * documentation and/or other materials provided with the distribution.
14 1.11.2.2 mycroft * 3. All advertising materials mentioning features or use of this software
15 1.11.2.2 mycroft * must display the following acknowledgement:
16 1.11.2.2 mycroft * This product includes software developed by the University of
17 1.11.2.2 mycroft * California, Berkeley and its contributors.
18 1.11.2.2 mycroft * 4. Neither the name of the University nor the names of its contributors
19 1.11.2.2 mycroft * may be used to endorse or promote products derived from this software
20 1.11.2.2 mycroft * without specific prior written permission.
21 1.11.2.2 mycroft *
22 1.11.2.2 mycroft * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 1.11.2.2 mycroft * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 1.11.2.2 mycroft * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 1.11.2.2 mycroft * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 1.11.2.2 mycroft * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 1.11.2.2 mycroft * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 1.11.2.2 mycroft * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 1.11.2.2 mycroft * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 1.11.2.2 mycroft * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 1.11.2.2 mycroft * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 1.11.2.2 mycroft * SUCH DAMAGE.
33 1.11.2.2 mycroft */
34 1.11.2.2 mycroft
35 1.11.2.2 mycroft #if defined(LIBC_SCCS) && !defined(lint)
36 1.11.2.2 mycroft /* from: static char sccsid[] = "@(#)kvm.c 5.18 (Berkeley) 5/7/91"; */
37 1.11.2.2 mycroft static char rcsid[] = "$Id: kvm.c,v 1.11.2.2 1993/07/19 12:37:14 mycroft Exp $";
38 1.11.2.2 mycroft #endif /* LIBC_SCCS and not lint */
39 1.11.2.2 mycroft
40 1.11.2.2 mycroft #include <sys/param.h>
41 1.11.2.2 mycroft #include <sys/user.h>
42 1.11.2.2 mycroft #include <sys/proc.h>
43 1.11.2.2 mycroft #include <sys/ioctl.h>
44 1.11.2.2 mycroft #include <sys/kinfo.h>
45 1.11.2.2 mycroft #include <sys/tty.h>
46 1.11.2.2 mycroft #include <sys/exec.h>
47 1.11.2.2 mycroft #include <machine/vmparam.h>
48 1.11.2.2 mycroft #include <fcntl.h>
49 1.11.2.2 mycroft #include <nlist.h>
50 1.11.2.2 mycroft #include <kvm.h>
51 1.11.2.2 mycroft #include <ndbm.h>
52 1.11.2.2 mycroft #include <limits.h>
53 1.11.2.2 mycroft #include <paths.h>
54 1.11.2.2 mycroft #include <stdio.h>
55 1.11.2.2 mycroft #include <string.h>
56 1.11.2.2 mycroft
57 1.11.2.2 mycroft #ifdef SPPWAIT
58 1.11.2.2 mycroft #define NEWVM
59 1.11.2.2 mycroft #endif
60 1.11.2.2 mycroft
61 1.11.2.2 mycroft #ifdef NEWVM
62 1.11.2.2 mycroft #define btop(x) (((unsigned)(x)) >> PGSHIFT) /* XXX */
63 1.11.2.2 mycroft #define ptob(x) ((caddr_t)((x) << PGSHIFT)) /* XXX */
64 1.11.2.2 mycroft #include <vm/vm.h> /* ??? kinfo_proc currently includes this*/
65 1.11.2.2 mycroft #include <vm/vm_page.h>
66 1.11.2.2 mycroft #include <vm/swap_pager.h>
67 1.11.2.2 mycroft #include <sys/kinfo_proc.h>
68 1.11.2.2 mycroft #ifdef hp300
69 1.11.2.2 mycroft #include <hp300/hp300/pte.h>
70 1.11.2.2 mycroft #endif
71 1.11.2.2 mycroft #else /* NEWVM */
72 1.11.2.2 mycroft #include <machine/pte.h>
73 1.11.2.2 mycroft #include <sys/vmmac.h>
74 1.11.2.2 mycroft #include <sys/text.h>
75 1.11.2.2 mycroft #endif /* NEWVM */
76 1.11.2.2 mycroft
77 1.11.2.2 mycroft /*
78 1.11.2.2 mycroft * files
79 1.11.2.2 mycroft */
80 1.11.2.2 mycroft static const char *unixf, *memf, *kmemf, *swapf;
81 1.11.2.2 mycroft static int unixx, mem, kmem, swap;
82 1.11.2.2 mycroft static DBM *db;
83 1.11.2.2 mycroft /*
84 1.11.2.2 mycroft * flags
85 1.11.2.2 mycroft */
86 1.11.2.2 mycroft static int deadkernel;
87 1.11.2.2 mycroft static int kvminit = 0;
88 1.11.2.2 mycroft static int kvmfilesopen = 0;
89 1.11.2.2 mycroft /*
90 1.11.2.2 mycroft * state
91 1.11.2.2 mycroft */
92 1.11.2.2 mycroft static struct kinfo_proc *kvmprocbase, *kvmprocptr;
93 1.11.2.2 mycroft static int kvmnprocs;
94 1.11.2.2 mycroft /*
95 1.11.2.2 mycroft * u. buffer
96 1.11.2.2 mycroft */
97 1.11.2.2 mycroft static union {
98 1.11.2.2 mycroft struct user user;
99 1.11.2.2 mycroft char upages[UPAGES][NBPG];
100 1.11.2.2 mycroft } user;
101 1.11.2.2 mycroft
102 1.11.2.2 mycroft #ifdef NEWVM
103 1.11.2.2 mycroft struct swapblk {
104 1.11.2.2 mycroft long offset; /* offset in swap device */
105 1.11.2.2 mycroft long size; /* remaining size of block in swap device */
106 1.11.2.2 mycroft };
107 1.11.2.2 mycroft #endif
108 1.11.2.2 mycroft /*
109 1.11.2.2 mycroft * random other stuff
110 1.11.2.2 mycroft */
111 1.11.2.2 mycroft #ifndef NEWVM
112 1.11.2.2 mycroft static struct pte *Usrptmap, *usrpt;
113 1.11.2.2 mycroft static struct pte *Sysmap;
114 1.11.2.2 mycroft static int Syssize;
115 1.11.2.2 mycroft #endif
116 1.11.2.2 mycroft static int dmmin, dmmax;
117 1.11.2.2 mycroft static int pcbpf;
118 1.11.2.2 mycroft static int nswap;
119 1.11.2.2 mycroft static char *tmp;
120 1.11.2.2 mycroft #if defined(hp300)
121 1.11.2.2 mycroft static int lowram;
122 1.11.2.2 mycroft static struct ste *Sysseg;
123 1.11.2.2 mycroft #endif
124 1.11.2.2 mycroft #if defined(i386)
125 1.11.2.2 mycroft static struct pde *PTD;
126 1.11.2.2 mycroft #endif
127 1.11.2.2 mycroft
128 1.11.2.2 mycroft #define basename(cp) ((tmp=rindex((cp), '/')) ? tmp+1 : (cp))
129 1.11.2.2 mycroft #define MAXSYMSIZE 256
130 1.11.2.2 mycroft
131 1.11.2.2 mycroft #if defined(hp300)
132 1.11.2.2 mycroft #define pftoc(f) ((f) - lowram)
133 1.11.2.2 mycroft #define iskva(v) (1)
134 1.11.2.2 mycroft #endif
135 1.11.2.2 mycroft
136 1.11.2.2 mycroft #ifndef pftoc
137 1.11.2.2 mycroft #define pftoc(f) (f)
138 1.11.2.2 mycroft #endif
139 1.11.2.2 mycroft #ifndef iskva
140 1.11.2.2 mycroft #define iskva(v) ((u_long)(v) & KERNBASE)
141 1.11.2.2 mycroft #endif
142 1.11.2.2 mycroft
143 1.11.2.2 mycroft static struct nlist nl[] = {
144 1.11.2.2 mycroft { "_Usrptmap" },
145 1.11.2.2 mycroft #define X_USRPTMAP 0
146 1.11.2.2 mycroft { "_usrpt" },
147 1.11.2.2 mycroft #define X_USRPT 1
148 1.11.2.2 mycroft { "_nswap" },
149 1.11.2.2 mycroft #define X_NSWAP 2
150 1.11.2.2 mycroft { "_dmmin" },
151 1.11.2.2 mycroft #define X_DMMIN 3
152 1.11.2.2 mycroft { "_dmmax" },
153 1.11.2.2 mycroft #define X_DMMAX 4
154 1.11.2.2 mycroft { "_vm_page_buckets" },
155 1.11.2.2 mycroft #define X_VM_PAGE_BUCKETS 5
156 1.11.2.2 mycroft { "_vm_page_hash_mask" },
157 1.11.2.2 mycroft #define X_VM_PAGE_HASH_MASK 6
158 1.11.2.2 mycroft { "_page_shift" },
159 1.11.2.2 mycroft #define X_PAGE_SHIFT 7
160 1.11.2.2 mycroft /*
161 1.11.2.2 mycroft * everything here and down, only if a dead kernel
162 1.11.2.2 mycroft */
163 1.11.2.2 mycroft { "_Sysmap" },
164 1.11.2.2 mycroft #define X_SYSMAP 8
165 1.11.2.2 mycroft #define X_DEADKERNEL X_SYSMAP
166 1.11.2.2 mycroft { "_Syssize" },
167 1.11.2.2 mycroft #define X_SYSSIZE 9
168 1.11.2.2 mycroft { "_allproc" },
169 1.11.2.2 mycroft #define X_ALLPROC 10
170 1.11.2.2 mycroft { "_zombproc" },
171 1.11.2.2 mycroft #define X_ZOMBPROC 11
172 1.11.2.2 mycroft { "_nproc" },
173 1.11.2.2 mycroft #define X_NPROC 12
174 1.11.2.2 mycroft #define X_LAST 12
175 1.11.2.2 mycroft #if defined(hp300)
176 1.11.2.2 mycroft { "_Sysseg" },
177 1.11.2.2 mycroft #define X_SYSSEG (X_LAST+1)
178 1.11.2.2 mycroft { "_lowram" },
179 1.11.2.2 mycroft #define X_LOWRAM (X_LAST+2)
180 1.11.2.2 mycroft #endif
181 1.11.2.2 mycroft #if defined(i386)
182 1.11.2.2 mycroft { "_IdlePTD" },
183 1.11.2.2 mycroft #define X_IdlePTD (X_LAST+1)
184 1.11.2.2 mycroft #endif
185 1.11.2.2 mycroft { "" },
186 1.11.2.2 mycroft };
187 1.11.2.2 mycroft
188 1.11.2.2 mycroft static off_t Vtophys();
189 1.11.2.2 mycroft static void klseek(), seterr(), setsyserr(), vstodb();
190 1.11.2.2 mycroft static int getkvars(), kvm_doprocs(), kvm_init();
191 1.11.2.2 mycroft #ifdef NEWVM
192 1.11.2.2 mycroft static int vatosw();
193 1.11.2.2 mycroft static int findpage();
194 1.11.2.2 mycroft #endif
195 1.11.2.2 mycroft
196 1.11.2.2 mycroft /*
197 1.11.2.2 mycroft * returns 0 if files were opened now,
198 1.11.2.2 mycroft * 1 if files were already opened,
199 1.11.2.2 mycroft * -1 if files could not be opened.
200 1.11.2.2 mycroft */
201 1.11.2.2 mycroft kvm_openfiles(uf, mf, sf)
202 1.11.2.2 mycroft const char *uf, *mf, *sf;
203 1.11.2.2 mycroft {
204 1.11.2.2 mycroft if (kvmfilesopen)
205 1.11.2.2 mycroft return (1);
206 1.11.2.2 mycroft unixx = mem = kmem = swap = -1;
207 1.11.2.2 mycroft unixf = (uf == NULL) ? _PATH_UNIX : uf;
208 1.11.2.2 mycroft memf = (mf == NULL) ? _PATH_MEM : mf;
209 1.11.2.2 mycroft
210 1.11.2.2 mycroft if ((unixx = open(unixf, O_RDONLY, 0)) == -1) {
211 1.11.2.2 mycroft setsyserr("can't open %s", unixf);
212 1.11.2.2 mycroft goto failed;
213 1.11.2.2 mycroft }
214 1.11.2.2 mycroft if ((mem = open(memf, O_RDONLY, 0)) == -1) {
215 1.11.2.2 mycroft setsyserr("can't open %s", memf);
216 1.11.2.2 mycroft goto failed;
217 1.11.2.2 mycroft }
218 1.11.2.2 mycroft if (sf != NULL)
219 1.11.2.2 mycroft swapf = sf;
220 1.11.2.2 mycroft if (mf != NULL) {
221 1.11.2.2 mycroft deadkernel++;
222 1.11.2.2 mycroft kmemf = mf;
223 1.11.2.2 mycroft kmem = mem;
224 1.11.2.2 mycroft swap = -1;
225 1.11.2.2 mycroft } else {
226 1.11.2.2 mycroft kmemf = _PATH_KMEM;
227 1.11.2.2 mycroft if ((kmem = open(kmemf, O_RDONLY, 0)) == -1) {
228 1.11.2.2 mycroft setsyserr("can't open %s", kmemf);
229 1.11.2.2 mycroft goto failed;
230 1.11.2.2 mycroft }
231 1.11.2.2 mycroft swapf = (sf == NULL) ? _PATH_DRUM : sf;
232 1.11.2.2 mycroft /*
233 1.11.2.2 mycroft * live kernel - avoid looking up nlist entries
234 1.11.2.2 mycroft * past X_DEADKERNEL.
235 1.11.2.2 mycroft */
236 1.11.2.2 mycroft nl[X_DEADKERNEL].n_name = "";
237 1.11.2.2 mycroft }
238 1.11.2.2 mycroft if (swapf != NULL && ((swap = open(swapf, O_RDONLY, 0)) == -1)) {
239 1.11.2.2 mycroft seterr("can't open %s", swapf);
240 1.11.2.2 mycroft goto failed;
241 1.11.2.2 mycroft }
242 1.11.2.2 mycroft kvmfilesopen++;
243 1.11.2.2 mycroft if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1) /*XXX*/
244 1.11.2.2 mycroft return (-1);
245 1.11.2.2 mycroft return (0);
246 1.11.2.2 mycroft failed:
247 1.11.2.2 mycroft kvm_close();
248 1.11.2.2 mycroft return (-1);
249 1.11.2.2 mycroft }
250 1.11.2.2 mycroft
251 1.11.2.2 mycroft static
252 1.11.2.2 mycroft kvm_init(uf, mf, sf)
253 1.11.2.2 mycroft char *uf, *mf, *sf;
254 1.11.2.2 mycroft {
255 1.11.2.2 mycroft if (kvmfilesopen == 0 && kvm_openfiles(NULL, NULL, NULL) == -1)
256 1.11.2.2 mycroft return (-1);
257 1.11.2.2 mycroft if (getkvars() == -1)
258 1.11.2.2 mycroft return (-1);
259 1.11.2.2 mycroft kvminit = 1;
260 1.11.2.2 mycroft
261 1.11.2.2 mycroft return (0);
262 1.11.2.2 mycroft }
263 1.11.2.2 mycroft
264 1.11.2.2 mycroft kvm_close()
265 1.11.2.2 mycroft {
266 1.11.2.2 mycroft if (unixx != -1) {
267 1.11.2.2 mycroft close(unixx);
268 1.11.2.2 mycroft unixx = -1;
269 1.11.2.2 mycroft }
270 1.11.2.2 mycroft if (kmem != -1) {
271 1.11.2.2 mycroft if (kmem != mem)
272 1.11.2.2 mycroft close(kmem);
273 1.11.2.2 mycroft /* otherwise kmem is a copy of mem, and will be closed below */
274 1.11.2.2 mycroft kmem = -1;
275 1.11.2.2 mycroft }
276 1.11.2.2 mycroft if (mem != -1) {
277 1.11.2.2 mycroft close(mem);
278 1.11.2.2 mycroft mem = -1;
279 1.11.2.2 mycroft }
280 1.11.2.2 mycroft if (swap != -1) {
281 1.11.2.2 mycroft close(swap);
282 1.11.2.2 mycroft swap = -1;
283 1.11.2.2 mycroft }
284 1.11.2.2 mycroft if (db != NULL) {
285 1.11.2.2 mycroft dbm_close(db);
286 1.11.2.2 mycroft db = NULL;
287 1.11.2.2 mycroft }
288 1.11.2.2 mycroft kvminit = 0;
289 1.11.2.2 mycroft kvmfilesopen = 0;
290 1.11.2.2 mycroft deadkernel = 0;
291 1.11.2.2 mycroft #ifndef NEWVM
292 1.11.2.2 mycroft if (Sysmap) {
293 1.11.2.2 mycroft free(Sysmap);
294 1.11.2.2 mycroft Sysmap = NULL;
295 1.11.2.2 mycroft }
296 1.11.2.2 mycroft #endif
297 1.11.2.2 mycroft }
298 1.11.2.2 mycroft
299 1.11.2.2 mycroft kvm_nlist(nl)
300 1.11.2.2 mycroft struct nlist *nl;
301 1.11.2.2 mycroft {
302 1.11.2.2 mycroft datum key, data;
303 1.11.2.2 mycroft char dbname[MAXPATHLEN];
304 1.11.2.2 mycroft char dbversion[_POSIX2_LINE_MAX];
305 1.11.2.2 mycroft char kversion[_POSIX2_LINE_MAX];
306 1.11.2.2 mycroft int dbversionlen;
307 1.11.2.2 mycroft char symbuf[MAXSYMSIZE];
308 1.11.2.2 mycroft struct nlist nbuf, *n;
309 1.11.2.2 mycroft int num, did;
310 1.11.2.2 mycroft
311 1.11.2.2 mycroft if (kvmfilesopen == 0 && kvm_openfiles(NULL, NULL, NULL) == -1)
312 1.11.2.2 mycroft return (-1);
313 1.11.2.2 mycroft if (deadkernel)
314 1.11.2.2 mycroft goto hard2;
315 1.11.2.2 mycroft /*
316 1.11.2.2 mycroft * initialize key datum
317 1.11.2.2 mycroft */
318 1.11.2.2 mycroft key.dptr = symbuf;
319 1.11.2.2 mycroft
320 1.11.2.2 mycroft if (db != NULL)
321 1.11.2.2 mycroft goto win; /* off to the races */
322 1.11.2.2 mycroft /*
323 1.11.2.2 mycroft * open database
324 1.11.2.2 mycroft */
325 1.11.2.2 mycroft sprintf(dbname, "%s/kvm_%s", _PATH_VARRUN, basename(unixf));
326 1.11.2.2 mycroft if ((db = dbm_open(dbname, O_RDONLY, 0)) == NULL)
327 1.11.2.2 mycroft goto hard2;
328 1.11.2.2 mycroft /*
329 1.11.2.2 mycroft * read version out of database
330 1.11.2.2 mycroft */
331 1.11.2.2 mycroft bcopy("VERSION", symbuf, sizeof ("VERSION")-1);
332 1.11.2.2 mycroft key.dsize = (sizeof ("VERSION") - 1);
333 1.11.2.2 mycroft data = dbm_fetch(db, key);
334 1.11.2.2 mycroft if (data.dptr == NULL)
335 1.11.2.2 mycroft goto hard1;
336 1.11.2.2 mycroft bcopy(data.dptr, dbversion, data.dsize);
337 1.11.2.2 mycroft dbversionlen = data.dsize;
338 1.11.2.2 mycroft /*
339 1.11.2.2 mycroft * read version string from kernel memory
340 1.11.2.2 mycroft */
341 1.11.2.2 mycroft bcopy("_version", symbuf, sizeof ("_version")-1);
342 1.11.2.2 mycroft key.dsize = (sizeof ("_version")-1);
343 1.11.2.2 mycroft data = dbm_fetch(db, key);
344 1.11.2.2 mycroft if (data.dptr == NULL)
345 1.11.2.2 mycroft goto hard1;
346 1.11.2.2 mycroft if (data.dsize != sizeof (struct nlist))
347 1.11.2.2 mycroft goto hard1;
348 1.11.2.2 mycroft bcopy(data.dptr, &nbuf, sizeof (struct nlist));
349 1.11.2.2 mycroft lseek(kmem, nbuf.n_value, 0);
350 1.11.2.2 mycroft if (read(kmem, kversion, dbversionlen) != dbversionlen)
351 1.11.2.2 mycroft goto hard1;
352 1.11.2.2 mycroft /*
353 1.11.2.2 mycroft * if they match, we win - otherwise do it the hard way
354 1.11.2.2 mycroft */
355 1.11.2.2 mycroft if (bcmp(dbversion, kversion, dbversionlen) != 0)
356 1.11.2.2 mycroft goto hard1;
357 1.11.2.2 mycroft /*
358 1.11.2.2 mycroft * getem from the database.
359 1.11.2.2 mycroft */
360 1.11.2.2 mycroft win:
361 1.11.2.2 mycroft num = did = 0;
362 1.11.2.2 mycroft for (n = nl; n->n_name && n->n_name[0]; n++, num++) {
363 1.11.2.2 mycroft int len;
364 1.11.2.2 mycroft /*
365 1.11.2.2 mycroft * clear out fields from users buffer
366 1.11.2.2 mycroft */
367 1.11.2.2 mycroft n->n_type = 0;
368 1.11.2.2 mycroft n->n_other = 0;
369 1.11.2.2 mycroft n->n_desc = 0;
370 1.11.2.2 mycroft n->n_value = 0;
371 1.11.2.2 mycroft /*
372 1.11.2.2 mycroft * query db
373 1.11.2.2 mycroft */
374 1.11.2.2 mycroft if ((len = strlen(n->n_name)) > MAXSYMSIZE) {
375 1.11.2.2 mycroft seterr("symbol too large");
376 1.11.2.2 mycroft return (-1);
377 1.11.2.2 mycroft }
378 1.11.2.2 mycroft (void)strcpy(symbuf, n->n_name);
379 1.11.2.2 mycroft key.dsize = len;
380 1.11.2.2 mycroft data = dbm_fetch(db, key);
381 1.11.2.2 mycroft if (data.dptr == NULL || data.dsize != sizeof (struct nlist))
382 1.11.2.2 mycroft continue;
383 1.11.2.2 mycroft bcopy(data.dptr, &nbuf, sizeof (struct nlist));
384 1.11.2.2 mycroft n->n_value = nbuf.n_value;
385 1.11.2.2 mycroft n->n_type = nbuf.n_type;
386 1.11.2.2 mycroft n->n_desc = nbuf.n_desc;
387 1.11.2.2 mycroft n->n_other = nbuf.n_other;
388 1.11.2.2 mycroft did++;
389 1.11.2.2 mycroft }
390 1.11.2.2 mycroft return (num - did);
391 1.11.2.2 mycroft hard1:
392 1.11.2.2 mycroft dbm_close(db);
393 1.11.2.2 mycroft db = NULL;
394 1.11.2.2 mycroft hard2:
395 1.11.2.2 mycroft num = nlist(unixf, nl);
396 1.11.2.2 mycroft if (num == -1)
397 1.11.2.2 mycroft seterr("nlist (hard way) failed");
398 1.11.2.2 mycroft return (num);
399 1.11.2.2 mycroft }
400 1.11.2.2 mycroft
401 1.11.2.2 mycroft kvm_getprocs(what, arg)
402 1.11.2.2 mycroft int what, arg;
403 1.11.2.2 mycroft {
404 1.11.2.2 mycroft static int ocopysize = -1;
405 1.11.2.2 mycroft
406 1.11.2.2 mycroft if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1)
407 1.11.2.2 mycroft return (NULL);
408 1.11.2.2 mycroft if (!deadkernel) {
409 1.11.2.2 mycroft int ret, copysize;
410 1.11.2.2 mycroft
411 1.11.2.2 mycroft if ((ret = getkerninfo(what, NULL, NULL, arg)) == -1) {
412 1.11.2.2 mycroft setsyserr("can't get estimate for kerninfo");
413 1.11.2.2 mycroft return (-1);
414 1.11.2.2 mycroft }
415 1.11.2.2 mycroft copysize = ret;
416 1.11.2.2 mycroft if (copysize > ocopysize || !kvmprocbase) {
417 1.11.2.2 mycroft if (ocopysize == -1 || !kvmprocbase)
418 1.11.2.2 mycroft kvmprocbase =
419 1.11.2.2 mycroft (struct kinfo_proc *)malloc(copysize);
420 1.11.2.2 mycroft else
421 1.11.2.2 mycroft kvmprocbase =
422 1.11.2.2 mycroft (struct kinfo_proc *)realloc(kvmprocbase,
423 1.11.2.2 mycroft copysize);
424 1.11.2.2 mycroft if (!kvmprocbase) {
425 1.11.2.2 mycroft seterr("out of memory");
426 1.11.2.2 mycroft return (-1);
427 1.11.2.2 mycroft }
428 1.11.2.2 mycroft }
429 1.11.2.2 mycroft ocopysize = copysize;
430 1.11.2.2 mycroft if ((ret = getkerninfo(what, kvmprocbase, ©size,
431 1.11.2.2 mycroft arg)) == -1) {
432 1.11.2.2 mycroft setsyserr("can't get proc list");
433 1.11.2.2 mycroft return (-1);
434 1.11.2.2 mycroft }
435 1.11.2.2 mycroft if (copysize % sizeof (struct kinfo_proc)) {
436 1.11.2.2 mycroft seterr("proc size mismatch (got %d total, kinfo_proc: %d)",
437 1.11.2.2 mycroft copysize, sizeof (struct kinfo_proc));
438 1.11.2.2 mycroft return (-1);
439 1.11.2.2 mycroft }
440 1.11.2.2 mycroft kvmnprocs = copysize / sizeof (struct kinfo_proc);
441 1.11.2.2 mycroft } else {
442 1.11.2.2 mycroft int nproc;
443 1.11.2.2 mycroft
444 1.11.2.2 mycroft if (kvm_read((void *) nl[X_NPROC].n_value, &nproc,
445 1.11.2.2 mycroft sizeof (int)) != sizeof (int)) {
446 1.11.2.2 mycroft seterr("can't read nproc");
447 1.11.2.2 mycroft return (-1);
448 1.11.2.2 mycroft }
449 1.11.2.2 mycroft if ((kvmprocbase = (struct kinfo_proc *)
450 1.11.2.2 mycroft malloc(nproc * sizeof (struct kinfo_proc))) == NULL) {
451 1.11.2.2 mycroft seterr("out of memory (addr: %x nproc = %d)",
452 1.11.2.2 mycroft nl[X_NPROC].n_value, nproc);
453 1.11.2.2 mycroft return (-1);
454 1.11.2.2 mycroft }
455 1.11.2.2 mycroft kvmnprocs = kvm_doprocs(what, arg, kvmprocbase);
456 1.11.2.2 mycroft realloc(kvmprocbase, kvmnprocs * sizeof (struct kinfo_proc));
457 1.11.2.2 mycroft }
458 1.11.2.2 mycroft kvmprocptr = kvmprocbase;
459 1.11.2.2 mycroft
460 1.11.2.2 mycroft return (kvmnprocs);
461 1.11.2.2 mycroft }
462 1.11.2.2 mycroft
463 1.11.2.2 mycroft /*
464 1.11.2.2 mycroft * XXX - should NOT give up so easily - especially since the kernel
465 1.11.2.2 mycroft * may be corrupt (it died). Should gather as much information as possible.
466 1.11.2.2 mycroft * Follows proc ptrs instead of reading table since table may go
467 1.11.2.2 mycroft * away soon.
468 1.11.2.2 mycroft */
469 1.11.2.2 mycroft static
470 1.11.2.2 mycroft kvm_doprocs(what, arg, buff)
471 1.11.2.2 mycroft int what, arg;
472 1.11.2.2 mycroft char *buff;
473 1.11.2.2 mycroft {
474 1.11.2.2 mycroft struct proc *p, proc;
475 1.11.2.2 mycroft register char *bp = buff;
476 1.11.2.2 mycroft int i = 0;
477 1.11.2.2 mycroft int doingzomb = 0;
478 1.11.2.2 mycroft struct eproc eproc;
479 1.11.2.2 mycroft struct pgrp pgrp;
480 1.11.2.2 mycroft struct session sess;
481 1.11.2.2 mycroft struct tty tty;
482 1.11.2.2 mycroft #ifndef NEWVM
483 1.11.2.2 mycroft struct text text;
484 1.11.2.2 mycroft #endif
485 1.11.2.2 mycroft
486 1.11.2.2 mycroft /* allproc */
487 1.11.2.2 mycroft if (kvm_read((void *) nl[X_ALLPROC].n_value, &p,
488 1.11.2.2 mycroft sizeof (struct proc *)) != sizeof (struct proc *)) {
489 1.11.2.2 mycroft seterr("can't read allproc");
490 1.11.2.2 mycroft return (-1);
491 1.11.2.2 mycroft }
492 1.11.2.2 mycroft
493 1.11.2.2 mycroft again:
494 1.11.2.2 mycroft for (; p; p = proc.p_nxt) {
495 1.11.2.2 mycroft if (kvm_read(p, &proc, sizeof (struct proc)) !=
496 1.11.2.2 mycroft sizeof (struct proc)) {
497 1.11.2.2 mycroft seterr("can't read proc at %x", p);
498 1.11.2.2 mycroft return (-1);
499 1.11.2.2 mycroft }
500 1.11.2.2 mycroft #ifdef NEWVM
501 1.11.2.2 mycroft if (kvm_read(proc.p_cred, &eproc.e_pcred,
502 1.11.2.2 mycroft sizeof (struct pcred)) == sizeof (struct pcred))
503 1.11.2.2 mycroft (void) kvm_read(eproc.e_pcred.pc_ucred, &eproc.e_ucred,
504 1.11.2.2 mycroft sizeof (struct ucred));
505 1.11.2.2 mycroft switch(ki_op(what)) {
506 1.11.2.2 mycroft
507 1.11.2.2 mycroft case KINFO_PROC_PID:
508 1.11.2.2 mycroft if (proc.p_pid != (pid_t)arg)
509 1.11.2.2 mycroft continue;
510 1.11.2.2 mycroft break;
511 1.11.2.2 mycroft
512 1.11.2.2 mycroft
513 1.11.2.2 mycroft case KINFO_PROC_UID:
514 1.11.2.2 mycroft if (eproc.e_ucred.cr_uid != (uid_t)arg)
515 1.11.2.2 mycroft continue;
516 1.11.2.2 mycroft break;
517 1.11.2.2 mycroft
518 1.11.2.2 mycroft case KINFO_PROC_RUID:
519 1.11.2.2 mycroft if (eproc.e_pcred.p_ruid != (uid_t)arg)
520 1.11.2.2 mycroft continue;
521 1.11.2.2 mycroft break;
522 1.11.2.2 mycroft }
523 1.11.2.2 mycroft #else
524 1.11.2.2 mycroft switch(ki_op(what)) {
525 1.11.2.2 mycroft
526 1.11.2.2 mycroft case KINFO_PROC_PID:
527 1.11.2.2 mycroft if (proc.p_pid != (pid_t)arg)
528 1.11.2.2 mycroft continue;
529 1.11.2.2 mycroft break;
530 1.11.2.2 mycroft
531 1.11.2.2 mycroft
532 1.11.2.2 mycroft case KINFO_PROC_UID:
533 1.11.2.2 mycroft if (proc.p_uid != (uid_t)arg)
534 1.11.2.2 mycroft continue;
535 1.11.2.2 mycroft break;
536 1.11.2.2 mycroft
537 1.11.2.2 mycroft case KINFO_PROC_RUID:
538 1.11.2.2 mycroft if (proc.p_ruid != (uid_t)arg)
539 1.11.2.2 mycroft continue;
540 1.11.2.2 mycroft break;
541 1.11.2.2 mycroft }
542 1.11.2.2 mycroft #endif
543 1.11.2.2 mycroft /*
544 1.11.2.2 mycroft * gather eproc
545 1.11.2.2 mycroft */
546 1.11.2.2 mycroft eproc.e_paddr = p;
547 1.11.2.2 mycroft if (kvm_read(proc.p_pgrp, &pgrp, sizeof (struct pgrp)) !=
548 1.11.2.2 mycroft sizeof (struct pgrp)) {
549 1.11.2.2 mycroft seterr("can't read pgrp at %x", proc.p_pgrp);
550 1.11.2.2 mycroft return (-1);
551 1.11.2.2 mycroft }
552 1.11.2.2 mycroft eproc.e_sess = pgrp.pg_session;
553 1.11.2.2 mycroft eproc.e_pgid = pgrp.pg_id;
554 1.11.2.2 mycroft eproc.e_jobc = pgrp.pg_jobc;
555 1.11.2.2 mycroft if (kvm_read(pgrp.pg_session, &sess, sizeof (struct session))
556 1.11.2.2 mycroft != sizeof (struct session)) {
557 1.11.2.2 mycroft seterr("can't read session at %x", pgrp.pg_session);
558 1.11.2.2 mycroft return (-1);
559 1.11.2.2 mycroft }
560 1.11.2.2 mycroft if ((proc.p_flag&SCTTY) && sess.s_ttyp != NULL) {
561 1.11.2.2 mycroft if (kvm_read(sess.s_ttyp, &tty, sizeof (struct tty))
562 1.11.2.2 mycroft != sizeof (struct tty)) {
563 1.11.2.2 mycroft seterr("can't read tty at %x", sess.s_ttyp);
564 1.11.2.2 mycroft return (-1);
565 1.11.2.2 mycroft }
566 1.11.2.2 mycroft eproc.e_tdev = tty.t_dev;
567 1.11.2.2 mycroft eproc.e_tsess = tty.t_session;
568 1.11.2.2 mycroft if (tty.t_pgrp != NULL) {
569 1.11.2.2 mycroft if (kvm_read(tty.t_pgrp, &pgrp, sizeof (struct
570 1.11.2.2 mycroft pgrp)) != sizeof (struct pgrp)) {
571 1.11.2.2 mycroft seterr("can't read tpgrp at &x",
572 1.11.2.2 mycroft tty.t_pgrp);
573 1.11.2.2 mycroft return (-1);
574 1.11.2.2 mycroft }
575 1.11.2.2 mycroft eproc.e_tpgid = pgrp.pg_id;
576 1.11.2.2 mycroft } else
577 1.11.2.2 mycroft eproc.e_tpgid = -1;
578 1.11.2.2 mycroft } else
579 1.11.2.2 mycroft eproc.e_tdev = NODEV;
580 1.11.2.2 mycroft if (proc.p_wmesg)
581 1.11.2.2 mycroft kvm_read(proc.p_wmesg, eproc.e_wmesg, WMESGLEN);
582 1.11.2.2 mycroft #ifdef NEWVM
583 1.11.2.2 mycroft (void) kvm_read(proc.p_vmspace, &eproc.e_vm,
584 1.11.2.2 mycroft sizeof (struct vmspace));
585 1.11.2.2 mycroft eproc.e_xsize = eproc.e_xrssize =
586 1.11.2.2 mycroft eproc.e_xccount = eproc.e_xswrss = 0;
587 1.11.2.2 mycroft #else
588 1.11.2.2 mycroft if (proc.p_textp) {
589 1.11.2.2 mycroft kvm_read(proc.p_textp, &text, sizeof (text));
590 1.11.2.2 mycroft eproc.e_xsize = text.x_size;
591 1.11.2.2 mycroft eproc.e_xrssize = text.x_rssize;
592 1.11.2.2 mycroft eproc.e_xccount = text.x_ccount;
593 1.11.2.2 mycroft eproc.e_xswrss = text.x_swrss;
594 1.11.2.2 mycroft } else {
595 1.11.2.2 mycroft eproc.e_xsize = eproc.e_xrssize =
596 1.11.2.2 mycroft eproc.e_xccount = eproc.e_xswrss = 0;
597 1.11.2.2 mycroft }
598 1.11.2.2 mycroft #endif
599 1.11.2.2 mycroft
600 1.11.2.2 mycroft switch(ki_op(what)) {
601 1.11.2.2 mycroft
602 1.11.2.2 mycroft case KINFO_PROC_PGRP:
603 1.11.2.2 mycroft if (eproc.e_pgid != (pid_t)arg)
604 1.11.2.2 mycroft continue;
605 1.11.2.2 mycroft break;
606 1.11.2.2 mycroft
607 1.11.2.2 mycroft case KINFO_PROC_TTY:
608 1.11.2.2 mycroft if ((proc.p_flag&SCTTY) == 0 ||
609 1.11.2.2 mycroft eproc.e_tdev != (dev_t)arg)
610 1.11.2.2 mycroft continue;
611 1.11.2.2 mycroft break;
612 1.11.2.2 mycroft }
613 1.11.2.2 mycroft
614 1.11.2.2 mycroft i++;
615 1.11.2.2 mycroft bcopy(&proc, bp, sizeof (struct proc));
616 1.11.2.2 mycroft bp += sizeof (struct proc);
617 1.11.2.2 mycroft bcopy(&eproc, bp, sizeof (struct eproc));
618 1.11.2.2 mycroft bp+= sizeof (struct eproc);
619 1.11.2.2 mycroft }
620 1.11.2.2 mycroft if (!doingzomb) {
621 1.11.2.2 mycroft /* zombproc */
622 1.11.2.2 mycroft if (kvm_read((void *) nl[X_ZOMBPROC].n_value, &p,
623 1.11.2.2 mycroft sizeof (struct proc *)) != sizeof (struct proc *)) {
624 1.11.2.2 mycroft seterr("can't read zombproc");
625 1.11.2.2 mycroft return (-1);
626 1.11.2.2 mycroft }
627 1.11.2.2 mycroft doingzomb = 1;
628 1.11.2.2 mycroft goto again;
629 1.11.2.2 mycroft }
630 1.11.2.2 mycroft
631 1.11.2.2 mycroft return (i);
632 1.11.2.2 mycroft }
633 1.11.2.2 mycroft
634 1.11.2.2 mycroft struct proc *
635 1.11.2.2 mycroft kvm_nextproc()
636 1.11.2.2 mycroft {
637 1.11.2.2 mycroft
638 1.11.2.2 mycroft if (!kvmprocbase && kvm_getprocs(0, 0) == -1)
639 1.11.2.2 mycroft return (NULL);
640 1.11.2.2 mycroft if (kvmprocptr >= (kvmprocbase + kvmnprocs)) {
641 1.11.2.2 mycroft seterr("end of proc list");
642 1.11.2.2 mycroft return (NULL);
643 1.11.2.2 mycroft }
644 1.11.2.2 mycroft return((struct proc *)(kvmprocptr++));
645 1.11.2.2 mycroft }
646 1.11.2.2 mycroft
647 1.11.2.2 mycroft struct eproc *
648 1.11.2.2 mycroft kvm_geteproc(p)
649 1.11.2.2 mycroft const struct proc *p;
650 1.11.2.2 mycroft {
651 1.11.2.2 mycroft return ((struct eproc *)(((char *)p) + sizeof (struct proc)));
652 1.11.2.2 mycroft }
653 1.11.2.2 mycroft
654 1.11.2.2 mycroft kvm_setproc()
655 1.11.2.2 mycroft {
656 1.11.2.2 mycroft kvmprocptr = kvmprocbase;
657 1.11.2.2 mycroft }
658 1.11.2.2 mycroft
659 1.11.2.2 mycroft kvm_freeprocs()
660 1.11.2.2 mycroft {
661 1.11.2.2 mycroft
662 1.11.2.2 mycroft if (kvmprocbase) {
663 1.11.2.2 mycroft free(kvmprocbase);
664 1.11.2.2 mycroft kvmprocbase = NULL;
665 1.11.2.2 mycroft }
666 1.11.2.2 mycroft }
667 1.11.2.2 mycroft
668 1.11.2.2 mycroft #ifdef NEWVM
669 1.11.2.2 mycroft struct user *
670 1.11.2.2 mycroft kvm_getu(p)
671 1.11.2.2 mycroft const struct proc *p;
672 1.11.2.2 mycroft {
673 1.11.2.2 mycroft register struct kinfo_proc *kp = (struct kinfo_proc *)p;
674 1.11.2.2 mycroft register int i;
675 1.11.2.2 mycroft register char *up;
676 1.11.2.2 mycroft u_int vaddr;
677 1.11.2.2 mycroft struct swapblk swb;
678 1.11.2.2 mycroft
679 1.11.2.2 mycroft if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1)
680 1.11.2.2 mycroft return (NULL);
681 1.11.2.2 mycroft if (p->p_stat == SZOMB) {
682 1.11.2.2 mycroft seterr("zombie process");
683 1.11.2.2 mycroft return (NULL);
684 1.11.2.2 mycroft }
685 1.11.2.2 mycroft
686 1.11.2.2 mycroft if ((p->p_flag & SLOAD) == 0) {
687 1.11.2.2 mycroft vm_offset_t maddr;
688 1.11.2.2 mycroft
689 1.11.2.2 mycroft if (swap < 0) {
690 1.11.2.2 mycroft seterr("no swap");
691 1.11.2.2 mycroft return (NULL);
692 1.11.2.2 mycroft }
693 1.11.2.2 mycroft /*
694 1.11.2.2 mycroft * Costly operation, better set enable_swap to zero
695 1.11.2.2 mycroft * in vm/vm_glue.c, since paging of user pages isn't
696 1.11.2.2 mycroft * done yet anyway.
697 1.11.2.2 mycroft */
698 1.11.2.2 mycroft if (vatosw(p, USRSTACK + i * NBPG, &maddr, &swb) == 0)
699 1.11.2.2 mycroft return NULL;
700 1.11.2.2 mycroft
701 1.11.2.2 mycroft if (maddr == 0 && swb.size < UPAGES * NBPG)
702 1.11.2.2 mycroft return NULL;
703 1.11.2.2 mycroft
704 1.11.2.2 mycroft for (i = 0; i < UPAGES; i++) {
705 1.11.2.2 mycroft if (maddr) {
706 1.11.2.2 mycroft (void) lseek(mem, maddr + i * NBPG, 0);
707 1.11.2.2 mycroft if (read(mem,
708 1.11.2.2 mycroft (char *)user.upages[i], NBPG) != NBPG) {
709 1.11.2.2 mycroft seterr(
710 1.11.2.2 mycroft "can't read u for pid %d from %s",
711 1.11.2.2 mycroft p->p_pid, swapf);
712 1.11.2.2 mycroft return NULL;
713 1.11.2.2 mycroft }
714 1.11.2.2 mycroft } else {
715 1.11.2.2 mycroft (void) lseek(swap, swb.offset + i * NBPG, 0);
716 1.11.2.2 mycroft if (read(swap,
717 1.11.2.2 mycroft (char *)user.upages[i], NBPG) != NBPG) {
718 1.11.2.2 mycroft seterr(
719 1.11.2.2 mycroft "can't read u for pid %d from %s",
720 1.11.2.2 mycroft p->p_pid, swapf);
721 1.11.2.2 mycroft return NULL;
722 1.11.2.2 mycroft }
723 1.11.2.2 mycroft }
724 1.11.2.2 mycroft }
725 1.11.2.2 mycroft return(&user.user);
726 1.11.2.2 mycroft }
727 1.11.2.2 mycroft /*
728 1.11.2.2 mycroft * Read u-area one page at a time for the benefit of post-mortems
729 1.11.2.2 mycroft */
730 1.11.2.2 mycroft up = (char *) p->p_addr;
731 1.11.2.2 mycroft for (i = 0; i < UPAGES; i++) {
732 1.11.2.2 mycroft klseek(kmem, (long)up, 0);
733 1.11.2.2 mycroft if (read(kmem, user.upages[i], CLBYTES) != CLBYTES) {
734 1.11.2.2 mycroft seterr("cant read page %x of u of pid %d from %s",
735 1.11.2.2 mycroft up, p->p_pid, kmemf);
736 1.11.2.2 mycroft return(NULL);
737 1.11.2.2 mycroft }
738 1.11.2.2 mycroft up += CLBYTES;
739 1.11.2.2 mycroft }
740 1.11.2.2 mycroft pcbpf = (int) btop(p->p_addr); /* what should this be really? */
741 1.11.2.2 mycroft
742 1.11.2.2 mycroft kp->kp_eproc.e_vm.vm_rssize =
743 1.11.2.2 mycroft kp->kp_eproc.e_vm.vm_pmap.pm_stats.resident_count; /* XXX */
744 1.11.2.2 mycroft return(&user.user);
745 1.11.2.2 mycroft }
746 1.11.2.2 mycroft #else
747 1.11.2.2 mycroft struct user *
748 1.11.2.2 mycroft kvm_getu(p)
749 1.11.2.2 mycroft const struct proc *p;
750 1.11.2.2 mycroft {
751 1.11.2.2 mycroft struct pte *pteaddr, apte;
752 1.11.2.2 mycroft struct pte arguutl[HIGHPAGES+(CLSIZE*2)];
753 1.11.2.2 mycroft register int i;
754 1.11.2.2 mycroft int ncl;
755 1.11.2.2 mycroft
756 1.11.2.2 mycroft if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1)
757 1.11.2.2 mycroft return (NULL);
758 1.11.2.2 mycroft if (p->p_stat == SZOMB) {
759 1.11.2.2 mycroft seterr("zombie process");
760 1.11.2.2 mycroft return (NULL);
761 1.11.2.2 mycroft }
762 1.11.2.2 mycroft if ((p->p_flag & SLOAD) == 0) {
763 1.11.2.2 mycroft if (swap < 0) {
764 1.11.2.2 mycroft seterr("no swap");
765 1.11.2.2 mycroft return (NULL);
766 1.11.2.2 mycroft }
767 1.11.2.2 mycroft (void) lseek(swap, (long)dtob(p->p_swaddr), 0);
768 1.11.2.2 mycroft if (read(swap, (char *)&user.user, sizeof (struct user)) !=
769 1.11.2.2 mycroft sizeof (struct user)) {
770 1.11.2.2 mycroft seterr("can't read u for pid %d from %s",
771 1.11.2.2 mycroft p->p_pid, swapf);
772 1.11.2.2 mycroft return (NULL);
773 1.11.2.2 mycroft }
774 1.11.2.2 mycroft pcbpf = 0;
775 1.11.2.2 mycroft argaddr0 = 0;
776 1.11.2.2 mycroft argaddr1 = 0;
777 1.11.2.2 mycroft return (&user.user);
778 1.11.2.2 mycroft }
779 1.11.2.2 mycroft pteaddr = &Usrptmap[btokmx(p->p_p0br) + p->p_szpt - 1];
780 1.11.2.2 mycroft klseek(kmem, (long)pteaddr, 0);
781 1.11.2.2 mycroft if (read(kmem, (char *)&apte, sizeof(apte)) != sizeof(apte)) {
782 1.11.2.2 mycroft seterr("can't read indir pte to get u for pid %d from %s",
783 1.11.2.2 mycroft p->p_pid, kmemf);
784 1.11.2.2 mycroft return (NULL);
785 1.11.2.2 mycroft }
786 1.11.2.2 mycroft lseek(mem, (long)ctob(pftoc(apte.pg_pfnum+1)) - sizeof(arguutl), 0);
787 1.11.2.2 mycroft if (read(mem, (char *)arguutl, sizeof(arguutl)) != sizeof(arguutl)) {
788 1.11.2.2 mycroft seterr("can't read page table for u of pid %d from %s",
789 1.11.2.2 mycroft p->p_pid, memf);
790 1.11.2.2 mycroft return (NULL);
791 1.11.2.2 mycroft }
792 1.11.2.2 mycroft if (arguutl[0].pg_fod == 0 && arguutl[0].pg_pfnum)
793 1.11.2.2 mycroft argaddr0 = ctob(pftoc(arguutl[0].pg_pfnum));
794 1.11.2.2 mycroft else
795 1.11.2.2 mycroft argaddr0 = 0;
796 1.11.2.2 mycroft if (arguutl[CLSIZE*1].pg_fod == 0 && arguutl[CLSIZE*1].pg_pfnum)
797 1.11.2.2 mycroft argaddr1 = ctob(pftoc(arguutl[CLSIZE*1].pg_pfnum));
798 1.11.2.2 mycroft else
799 1.11.2.2 mycroft argaddr1 = 0;
800 1.11.2.2 mycroft pcbpf = arguutl[CLSIZE*2].pg_pfnum;
801 1.11.2.2 mycroft ncl = (sizeof (struct user) + CLBYTES - 1) / CLBYTES;
802 1.11.2.2 mycroft while (--ncl >= 0) {
803 1.11.2.2 mycroft i = ncl * CLSIZE;
804 1.11.2.2 mycroft lseek(mem,
805 1.11.2.2 mycroft (long)ctob(pftoc(arguutl[(CLSIZE*2)+i].pg_pfnum)), 0);
806 1.11.2.2 mycroft if (read(mem, user.upages[i], CLBYTES) != CLBYTES) {
807 1.11.2.2 mycroft seterr("can't read page %d of u of pid %d from %s",
808 1.11.2.2 mycroft arguutl[(CLSIZE*2)+i].pg_pfnum, p->p_pid, memf);
809 1.11.2.2 mycroft return(NULL);
810 1.11.2.2 mycroft }
811 1.11.2.2 mycroft }
812 1.11.2.2 mycroft return (&user.user);
813 1.11.2.2 mycroft }
814 1.11.2.2 mycroft #endif
815 1.11.2.2 mycroft
816 1.11.2.2 mycroft int
817 1.11.2.2 mycroft kvm_procread(p, addr, buf, len)
818 1.11.2.2 mycroft const struct proc *p;
819 1.11.2.2 mycroft const unsigned addr, len;
820 1.11.2.2 mycroft char *buf;
821 1.11.2.2 mycroft {
822 1.11.2.2 mycroft register struct kinfo_proc *kp = (struct kinfo_proc *) p;
823 1.11.2.2 mycroft struct swapblk swb;
824 1.11.2.2 mycroft vm_offset_t swaddr = 0, memaddr = 0;
825 1.11.2.2 mycroft unsigned real_len;
826 1.11.2.2 mycroft
827 1.11.2.2 mycroft real_len = len < (CLBYTES - (addr & CLOFSET)) ? len : (CLBYTES - (addr & CLOFSET));
828 1.11.2.2 mycroft
829 1.11.2.2 mycroft #if defined(hp300)
830 1.11.2.2 mycroft /*
831 1.11.2.2 mycroft * XXX DANGER WILL ROBINSON -- i have *no* idea to what extent this
832 1.11.2.2 mycroft * works... -- cgd
833 1.11.2.2 mycroft */
834 1.11.2.2 mycroft BREAK HERE!!!
835 1.11.2.2 mycroft #endif
836 1.11.2.2 mycroft #if defined(i386)
837 1.11.2.2 mycroft if (kp->kp_eproc.e_vm.vm_pmap.pm_pdir) {
838 1.11.2.2 mycroft struct pde pde;
839 1.11.2.2 mycroft
840 1.11.2.2 mycroft klseek(kmem,
841 1.11.2.2 mycroft (long)(&kp->kp_eproc.e_vm.vm_pmap.pm_pdir[pdei(addr)]), 0);
842 1.11.2.2 mycroft
843 1.11.2.2 mycroft if (read(kmem, (char *)&pde, sizeof pde) == sizeof pde
844 1.11.2.2 mycroft && pde.pd_v) {
845 1.11.2.2 mycroft
846 1.11.2.2 mycroft struct pte pte;
847 1.11.2.2 mycroft
848 1.11.2.2 mycroft if (lseek(mem, (long)ctob(pde.pd_pfnum) +
849 1.11.2.2 mycroft (ptei(addr) * sizeof pte), 0) == -1)
850 1.11.2.2 mycroft seterr("kvm_procread: lseek");
851 1.11.2.2 mycroft if (read(mem, (char *)&pte, sizeof pte) == sizeof pte) {
852 1.11.2.2 mycroft if (pte.pg_v) {
853 1.11.2.2 mycroft memaddr = (long)ctob(pte.pg_pfnum) +
854 1.11.2.2 mycroft (addr % (1 << PGSHIFT));
855 1.11.2.2 mycroft }
856 1.11.2.2 mycroft } else {
857 1.11.2.2 mycroft seterr("kvm_procread: read");
858 1.11.2.2 mycroft }
859 1.11.2.2 mycroft }
860 1.11.2.2 mycroft }
861 1.11.2.2 mycroft #endif /* i386 */
862 1.11.2.2 mycroft
863 1.11.2.2 mycroft if (memaddr == 0 && vatosw(p, addr & ~CLOFSET, &memaddr, &swb)) {
864 1.11.2.2 mycroft if (memaddr != 0) {
865 1.11.2.2 mycroft memaddr += addr & CLOFSET;
866 1.11.2.2 mycroft } else {
867 1.11.2.2 mycroft swaddr = swb.offset + (addr & CLOFSET);
868 1.11.2.2 mycroft swb.size -= addr & CLOFSET;
869 1.11.2.2 mycroft }
870 1.11.2.2 mycroft }
871 1.11.2.2 mycroft
872 1.11.2.2 mycroft if (memaddr) {
873 1.11.2.2 mycroft if (lseek(mem, memaddr, 0) == -1)
874 1.11.2.2 mycroft seterr("kvm_getu: lseek");
875 1.11.2.2 mycroft real_len = read(mem, buf, real_len);
876 1.11.2.2 mycroft if (real_len == -1) {
877 1.11.2.2 mycroft seterr("kvm_procread: read");
878 1.11.2.2 mycroft return 0;
879 1.11.2.2 mycroft }
880 1.11.2.2 mycroft } else if (swaddr) {
881 1.11.2.2 mycroft char bouncebuf[CLBYTES];
882 1.11.2.2 mycroft unsigned len;
883 1.11.2.2 mycroft if (lseek(swap, swaddr & ~CLOFSET, 0) == -1) {
884 1.11.2.2 mycroft seterr("kvm_procread: lseek");
885 1.11.2.2 mycroft return 0;
886 1.11.2.2 mycroft }
887 1.11.2.2 mycroft len = read(swap, bouncebuf, CLBYTES);
888 1.11.2.2 mycroft if (len == -1 || len <= (swaddr & CLOFSET)) {
889 1.11.2.2 mycroft seterr("kvm_procread: read");
890 1.11.2.2 mycroft return 0;
891 1.11.2.2 mycroft }
892 1.11.2.2 mycroft len = MIN(len - (swaddr & CLOFSET), real_len);
893 1.11.2.2 mycroft memcpy(buf, &bouncebuf[swaddr & CLOFSET], len);
894 1.11.2.2 mycroft return len;
895 1.11.2.2 mycroft } else
896 1.11.2.2 mycroft real_len = 0;
897 1.11.2.2 mycroft
898 1.11.2.2 mycroft return real_len;
899 1.11.2.2 mycroft }
900 1.11.2.2 mycroft
901 1.11.2.2 mycroft int
902 1.11.2.2 mycroft kvm_procreadstr(p, addr, buf, len)
903 1.11.2.2 mycroft const struct proc *p;
904 1.11.2.2 mycroft const unsigned addr;
905 1.11.2.2 mycroft char *buf;
906 1.11.2.2 mycroft unsigned len;
907 1.11.2.2 mycroft {
908 1.11.2.2 mycroft int done, little;
909 1.11.2.2 mycroft char copy[200], *pb;
910 1.11.2.2 mycroft char a;
911 1.11.2.2 mycroft
912 1.11.2.2 mycroft done = 0;
913 1.11.2.2 mycroft while (len) {
914 1.11.2.2 mycroft little = kvm_procread(p, addr+done, copy, MIN(len, sizeof copy));
915 1.11.2.2 mycroft if (little<1)
916 1.11.2.2 mycroft break;
917 1.11.2.2 mycroft pb = copy;
918 1.11.2.2 mycroft while (little--) {
919 1.11.2.2 mycroft len--;
920 1.11.2.2 mycroft if( (*buf++ = *pb++) == '\0' )
921 1.11.2.2 mycroft return done;
922 1.11.2.2 mycroft done++;
923 1.11.2.2 mycroft }
924 1.11.2.2 mycroft }
925 1.11.2.2 mycroft return done;
926 1.11.2.2 mycroft }
927 1.11.2.2 mycroft
928 1.11.2.2 mycroft char *
929 1.11.2.2 mycroft kvm_getargs(p, up)
930 1.11.2.2 mycroft const struct proc *p;
931 1.11.2.2 mycroft const struct user *up;
932 1.11.2.2 mycroft {
933 1.11.2.2 mycroft static char cmdbuf[ARG_MAX + sizeof(p->p_comm) + 5];
934 1.11.2.2 mycroft register char *cp, *acp;
935 1.11.2.2 mycroft int left, rv;
936 1.11.2.2 mycroft struct ps_strings arginfo;
937 1.11.2.2 mycroft
938 1.11.2.2 mycroft if (up == NULL || p->p_pid == 0 || p->p_pid == 2)
939 1.11.2.2 mycroft goto retucomm;
940 1.11.2.2 mycroft
941 1.11.2.2 mycroft if (kvm_procread(p, PS_STRINGS, (char *)&arginfo, sizeof(arginfo)) !=
942 1.11.2.2 mycroft sizeof(arginfo))
943 1.11.2.2 mycroft goto bad;
944 1.11.2.2 mycroft
945 1.11.2.2 mycroft cp = cmdbuf;
946 1.11.2.2 mycroft acp = arginfo.ps_argvstr;
947 1.11.2.2 mycroft left = ARG_MAX + 1;
948 1.11.2.2 mycroft while (arginfo.ps_nargvstr--) {
949 1.11.2.2 mycroft if ((rv = kvm_procreadstr(p, acp, cp, left)) >= 0) {
950 1.11.2.2 mycroft acp += rv + 1;
951 1.11.2.2 mycroft left -= rv + 1;
952 1.11.2.2 mycroft cp += rv;
953 1.11.2.2 mycroft *cp++ = ' ';
954 1.11.2.2 mycroft *cp = '\0';
955 1.11.2.2 mycroft } else
956 1.11.2.2 mycroft goto bad;
957 1.11.2.2 mycroft }
958 1.11.2.2 mycroft cp-- ; *cp = '\0';
959 1.11.2.2 mycroft
960 1.11.2.2 mycroft if (cmdbuf[0] == '-' || cmdbuf[0] == '?' || cmdbuf[0] <= ' ') {
961 1.11.2.2 mycroft (void) strcat(cmdbuf, " (");
962 1.11.2.2 mycroft (void) strncat(cmdbuf, p->p_comm, sizeof(p->p_comm));
963 1.11.2.2 mycroft (void) strcat(cmdbuf, ")");
964 1.11.2.2 mycroft }
965 1.11.2.2 mycroft return (cmdbuf);
966 1.11.2.2 mycroft
967 1.11.2.2 mycroft bad:
968 1.11.2.2 mycroft seterr("error locating command name for pid %d", p->p_pid);
969 1.11.2.2 mycroft retucomm:
970 1.11.2.2 mycroft (void) strcpy(cmdbuf, "(");
971 1.11.2.2 mycroft (void) strncat(cmdbuf, p->p_comm, sizeof (p->p_comm));
972 1.11.2.2 mycroft (void) strcat(cmdbuf, ")");
973 1.11.2.2 mycroft return (cmdbuf);
974 1.11.2.2 mycroft }
975 1.11.2.2 mycroft
976 1.11.2.2 mycroft char *
977 1.11.2.2 mycroft kvm_getenv(p, up)
978 1.11.2.2 mycroft const struct proc *p;
979 1.11.2.2 mycroft const struct user *up;
980 1.11.2.2 mycroft {
981 1.11.2.2 mycroft static char envbuf[ARG_MAX + 1];
982 1.11.2.2 mycroft register char *cp, *acp;
983 1.11.2.2 mycroft int left, rv;
984 1.11.2.2 mycroft struct ps_strings arginfo;
985 1.11.2.2 mycroft
986 1.11.2.2 mycroft if (up == NULL || p->p_pid == 0 || p->p_pid == 2)
987 1.11.2.2 mycroft goto retemptyenv;
988 1.11.2.2 mycroft
989 1.11.2.2 mycroft if (kvm_procread(p, PS_STRINGS, (char *)&arginfo, sizeof(arginfo)) !=
990 1.11.2.2 mycroft sizeof(arginfo))
991 1.11.2.2 mycroft goto bad;
992 1.11.2.2 mycroft
993 1.11.2.2 mycroft cp = envbuf;
994 1.11.2.2 mycroft acp = arginfo.ps_envstr;
995 1.11.2.2 mycroft left = ARG_MAX + 1;
996 1.11.2.2 mycroft while (arginfo.ps_nenvstr--) {
997 1.11.2.2 mycroft if ((rv = kvm_procreadstr(p, acp, cp, left)) >= 0) {
998 1.11.2.2 mycroft acp += rv + 1;
999 1.11.2.2 mycroft left -= rv + 1;
1000 1.11.2.2 mycroft cp += rv;
1001 1.11.2.2 mycroft *cp++ = ' ';
1002 1.11.2.2 mycroft *cp = '\0';
1003 1.11.2.2 mycroft } else
1004 1.11.2.2 mycroft goto bad;
1005 1.11.2.2 mycroft }
1006 1.11.2.2 mycroft cp-- ; *cp = '\0';
1007 1.11.2.2 mycroft return (envbuf);
1008 1.11.2.2 mycroft
1009 1.11.2.2 mycroft bad:
1010 1.11.2.2 mycroft seterr("error locating environment for pid %d", p->p_pid);
1011 1.11.2.2 mycroft retemptyenv:
1012 1.11.2.2 mycroft envbuf[0] = '\0';
1013 1.11.2.2 mycroft return (envbuf);
1014 1.11.2.2 mycroft }
1015 1.11.2.2 mycroft
1016 1.11.2.2 mycroft static
1017 1.11.2.2 mycroft getkvars()
1018 1.11.2.2 mycroft {
1019 1.11.2.2 mycroft if (kvm_nlist(nl) == -1)
1020 1.11.2.2 mycroft return (-1);
1021 1.11.2.2 mycroft if (deadkernel) {
1022 1.11.2.2 mycroft /* We must do the sys map first because klseek uses it */
1023 1.11.2.2 mycroft long addr;
1024 1.11.2.2 mycroft
1025 1.11.2.2 mycroft #ifndef NEWVM
1026 1.11.2.2 mycroft Syssize = nl[X_SYSSIZE].n_value;
1027 1.11.2.2 mycroft Sysmap = (struct pte *)
1028 1.11.2.2 mycroft calloc((unsigned) Syssize, sizeof (struct pte));
1029 1.11.2.2 mycroft if (Sysmap == NULL) {
1030 1.11.2.2 mycroft seterr("out of space for Sysmap");
1031 1.11.2.2 mycroft return (-1);
1032 1.11.2.2 mycroft }
1033 1.11.2.2 mycroft addr = (long) nl[X_SYSMAP].n_value;
1034 1.11.2.2 mycroft addr &= ~KERNBASE;
1035 1.11.2.2 mycroft (void) lseek(kmem, addr, 0);
1036 1.11.2.2 mycroft if (read(kmem, (char *) Sysmap, Syssize * sizeof (struct pte))
1037 1.11.2.2 mycroft != Syssize * sizeof (struct pte)) {
1038 1.11.2.2 mycroft seterr("can't read Sysmap");
1039 1.11.2.2 mycroft return (-1);
1040 1.11.2.2 mycroft }
1041 1.11.2.2 mycroft #endif
1042 1.11.2.2 mycroft #if defined(hp300)
1043 1.11.2.2 mycroft addr = (long) nl[X_LOWRAM].n_value;
1044 1.11.2.2 mycroft (void) lseek(kmem, addr, 0);
1045 1.11.2.2 mycroft if (read(kmem, (char *) &lowram, sizeof (lowram))
1046 1.11.2.2 mycroft != sizeof (lowram)) {
1047 1.11.2.2 mycroft seterr("can't read lowram");
1048 1.11.2.2 mycroft return (-1);
1049 1.11.2.2 mycroft }
1050 1.11.2.2 mycroft lowram = btop(lowram);
1051 1.11.2.2 mycroft Sysseg = (struct ste *) malloc(NBPG);
1052 1.11.2.2 mycroft if (Sysseg == NULL) {
1053 1.11.2.2 mycroft seterr("out of space for Sysseg");
1054 1.11.2.2 mycroft return (-1);
1055 1.11.2.2 mycroft }
1056 1.11.2.2 mycroft addr = (long) nl[X_SYSSEG].n_value;
1057 1.11.2.2 mycroft (void) lseek(kmem, addr, 0);
1058 1.11.2.2 mycroft read(kmem, (char *)&addr, sizeof(addr));
1059 1.11.2.2 mycroft (void) lseek(kmem, (long)addr, 0);
1060 1.11.2.2 mycroft if (read(kmem, (char *) Sysseg, NBPG) != NBPG) {
1061 1.11.2.2 mycroft seterr("can't read Sysseg");
1062 1.11.2.2 mycroft return (-1);
1063 1.11.2.2 mycroft }
1064 1.11.2.2 mycroft #endif
1065 1.11.2.2 mycroft #if defined(i386)
1066 1.11.2.2 mycroft PTD = (struct pde *) malloc(NBPG);
1067 1.11.2.2 mycroft if (PTD == NULL) {
1068 1.11.2.2 mycroft seterr("out of space for PTD");
1069 1.11.2.2 mycroft return (-1);
1070 1.11.2.2 mycroft }
1071 1.11.2.2 mycroft addr = (long) nl[X_IdlePTD].n_value;
1072 1.11.2.2 mycroft (void) lseek(kmem, addr, 0);
1073 1.11.2.2 mycroft read(kmem, (char *)&addr, sizeof(addr));
1074 1.11.2.2 mycroft (void) lseek(kmem, (long)addr, 0);
1075 1.11.2.2 mycroft if (read(kmem, (char *) PTD, NBPG) != NBPG) {
1076 1.11.2.2 mycroft seterr("can't read PTD");
1077 1.11.2.2 mycroft return (-1);
1078 1.11.2.2 mycroft }
1079 1.11.2.2 mycroft #endif
1080 1.11.2.2 mycroft }
1081 1.11.2.2 mycroft #ifndef NEWVM
1082 1.11.2.2 mycroft usrpt = (struct pte *)nl[X_USRPT].n_value;
1083 1.11.2.2 mycroft Usrptmap = (struct pte *)nl[X_USRPTMAP].n_value;
1084 1.11.2.2 mycroft #endif
1085 1.11.2.2 mycroft if (kvm_read((void *) nl[X_NSWAP].n_value, &nswap, sizeof (long)) !=
1086 1.11.2.2 mycroft sizeof (long)) {
1087 1.11.2.2 mycroft seterr("can't read nswap");
1088 1.11.2.2 mycroft return (-1);
1089 1.11.2.2 mycroft }
1090 1.11.2.2 mycroft if (kvm_read((void *) nl[X_DMMIN].n_value, &dmmin, sizeof (long)) !=
1091 1.11.2.2 mycroft sizeof (long)) {
1092 1.11.2.2 mycroft seterr("can't read dmmin");
1093 1.11.2.2 mycroft return (-1);
1094 1.11.2.2 mycroft }
1095 1.11.2.2 mycroft if (kvm_read((void *) nl[X_DMMAX].n_value, &dmmax, sizeof (long)) !=
1096 1.11.2.2 mycroft sizeof (long)) {
1097 1.11.2.2 mycroft seterr("can't read dmmax");
1098 1.11.2.2 mycroft return (-1);
1099 1.11.2.2 mycroft }
1100 1.11.2.2 mycroft return (0);
1101 1.11.2.2 mycroft }
1102 1.11.2.2 mycroft
1103 1.11.2.2 mycroft kvm_read(loc, buf, len)
1104 1.11.2.2 mycroft void *loc;
1105 1.11.2.2 mycroft void *buf;
1106 1.11.2.2 mycroft {
1107 1.11.2.2 mycroft if (kvmfilesopen == 0 && kvm_openfiles(NULL, NULL, NULL) == -1)
1108 1.11.2.2 mycroft return (-1);
1109 1.11.2.2 mycroft if (iskva(loc)) {
1110 1.11.2.2 mycroft klseek(kmem, (off_t) loc, 0);
1111 1.11.2.2 mycroft if (read(kmem, buf, len) != len) {
1112 1.11.2.2 mycroft seterr("error reading kmem at %x", loc);
1113 1.11.2.2 mycroft return (-1);
1114 1.11.2.2 mycroft }
1115 1.11.2.2 mycroft } else {
1116 1.11.2.2 mycroft lseek(mem, (off_t) loc, 0);
1117 1.11.2.2 mycroft if (read(mem, buf, len) != len) {
1118 1.11.2.2 mycroft seterr("error reading mem at %x", loc);
1119 1.11.2.2 mycroft return (-1);
1120 1.11.2.2 mycroft }
1121 1.11.2.2 mycroft }
1122 1.11.2.2 mycroft return (len);
1123 1.11.2.2 mycroft }
1124 1.11.2.2 mycroft
1125 1.11.2.2 mycroft static void
1126 1.11.2.2 mycroft klseek(fd, loc, off)
1127 1.11.2.2 mycroft int fd;
1128 1.11.2.2 mycroft off_t loc;
1129 1.11.2.2 mycroft int off;
1130 1.11.2.2 mycroft {
1131 1.11.2.2 mycroft
1132 1.11.2.2 mycroft if (deadkernel) {
1133 1.11.2.2 mycroft if ((loc = Vtophys(loc)) == -1)
1134 1.11.2.2 mycroft return;
1135 1.11.2.2 mycroft }
1136 1.11.2.2 mycroft (void) lseek(fd, (off_t)loc, off);
1137 1.11.2.2 mycroft }
1138 1.11.2.2 mycroft
1139 1.11.2.2 mycroft #ifndef NEWVM
1140 1.11.2.2 mycroft /*
1141 1.11.2.2 mycroft * Given a base/size pair in virtual swap area,
1142 1.11.2.2 mycroft * return a physical base/size pair which is the
1143 1.11.2.2 mycroft * (largest) initial, physically contiguous block.
1144 1.11.2.2 mycroft */
1145 1.11.2.2 mycroft static void
1146 1.11.2.2 mycroft vstodb(vsbase, vssize, dmp, dbp, rev)
1147 1.11.2.2 mycroft register int vsbase;
1148 1.11.2.2 mycroft int vssize;
1149 1.11.2.2 mycroft struct dmap *dmp;
1150 1.11.2.2 mycroft register struct dblock *dbp;
1151 1.11.2.2 mycroft {
1152 1.11.2.2 mycroft register int blk = dmmin;
1153 1.11.2.2 mycroft register swblk_t *ip = dmp->dm_map;
1154 1.11.2.2 mycroft
1155 1.11.2.2 mycroft vsbase = ctod(vsbase);
1156 1.11.2.2 mycroft vssize = ctod(vssize);
1157 1.11.2.2 mycroft if (vsbase < 0 || vsbase + vssize > dmp->dm_size)
1158 1.11.2.2 mycroft /*panic("vstodb")*/;
1159 1.11.2.2 mycroft while (vsbase >= blk) {
1160 1.11.2.2 mycroft vsbase -= blk;
1161 1.11.2.2 mycroft if (blk < dmmax)
1162 1.11.2.2 mycroft blk *= 2;
1163 1.11.2.2 mycroft ip++;
1164 1.11.2.2 mycroft }
1165 1.11.2.2 mycroft if (*ip <= 0 || *ip + blk > nswap)
1166 1.11.2.2 mycroft /*panic("vstodb")*/;
1167 1.11.2.2 mycroft dbp->db_size = MIN(vssize, blk - vsbase);
1168 1.11.2.2 mycroft dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase);
1169 1.11.2.2 mycroft }
1170 1.11.2.2 mycroft #endif
1171 1.11.2.2 mycroft
1172 1.11.2.2 mycroft #ifdef NEWVM
1173 1.11.2.2 mycroft static off_t
1174 1.11.2.2 mycroft Vtophys(loc)
1175 1.11.2.2 mycroft u_long loc;
1176 1.11.2.2 mycroft {
1177 1.11.2.2 mycroft off_t newloc = (off_t) -1;
1178 1.11.2.2 mycroft #ifdef hp300
1179 1.11.2.2 mycroft int p, ste, pte;
1180 1.11.2.2 mycroft
1181 1.11.2.2 mycroft ste = *(int *)&Sysseg[loc >> SG_ISHIFT];
1182 1.11.2.2 mycroft if ((ste & SG_V) == 0) {
1183 1.11.2.2 mycroft seterr("vtophys: segment not valid");
1184 1.11.2.2 mycroft return((off_t) -1);
1185 1.11.2.2 mycroft }
1186 1.11.2.2 mycroft p = btop(loc & SG_PMASK);
1187 1.11.2.2 mycroft newloc = (ste & SG_FRAME) + (p * sizeof(struct pte));
1188 1.11.2.2 mycroft (void) lseek(kmem, (long)(newloc-(off_t)ptob(lowram)), 0);
1189 1.11.2.2 mycroft if (read(kmem, (char *)&pte, sizeof pte) != sizeof pte) {
1190 1.11.2.2 mycroft seterr("vtophys: cannot locate pte");
1191 1.11.2.2 mycroft return((off_t) -1);
1192 1.11.2.2 mycroft }
1193 1.11.2.2 mycroft newloc = pte & PG_FRAME;
1194 1.11.2.2 mycroft if (pte == PG_NV || newloc < (off_t)ptob(lowram)) {
1195 1.11.2.2 mycroft seterr("vtophys: page not valid");
1196 1.11.2.2 mycroft return((off_t) -1);
1197 1.11.2.2 mycroft }
1198 1.11.2.2 mycroft newloc = (newloc - (off_t)ptob(lowram)) + (loc & PGOFSET);
1199 1.11.2.2 mycroft #endif
1200 1.11.2.2 mycroft #ifdef i386
1201 1.11.2.2 mycroft struct pde pde;
1202 1.11.2.2 mycroft struct pte pte;
1203 1.11.2.2 mycroft int p;
1204 1.11.2.2 mycroft
1205 1.11.2.2 mycroft pde = PTD[loc >> PD_SHIFT];
1206 1.11.2.2 mycroft if (pde.pd_v == 0) {
1207 1.11.2.2 mycroft seterr("vtophys: page directory entry not valid");
1208 1.11.2.2 mycroft return((off_t) -1);
1209 1.11.2.2 mycroft }
1210 1.11.2.2 mycroft p = btop(loc & PT_MASK);
1211 1.11.2.2 mycroft newloc = pde.pd_pfnum + (p * sizeof(struct pte));
1212 1.11.2.2 mycroft (void) lseek(kmem, (long)newloc, 0);
1213 1.11.2.2 mycroft if (read(kmem, (char *)&pte, sizeof pte) != sizeof pte) {
1214 1.11.2.2 mycroft seterr("vtophys: cannot obtain desired pte");
1215 1.11.2.2 mycroft return((off_t) -1);
1216 1.11.2.2 mycroft }
1217 1.11.2.2 mycroft newloc = pte.pg_pfnum;
1218 1.11.2.2 mycroft if (pte.pg_v == 0) {
1219 1.11.2.2 mycroft seterr("vtophys: page table entry not valid");
1220 1.11.2.2 mycroft return((off_t) -1);
1221 1.11.2.2 mycroft }
1222 1.11.2.2 mycroft newloc += (loc & PGOFSET);
1223 1.11.2.2 mycroft #endif
1224 1.11.2.2 mycroft return((off_t) newloc);
1225 1.11.2.2 mycroft }
1226 1.11.2.2 mycroft #else
1227 1.11.2.2 mycroft static off_t
1228 1.11.2.2 mycroft vtophys(loc)
1229 1.11.2.2 mycroft long loc;
1230 1.11.2.2 mycroft {
1231 1.11.2.2 mycroft int p;
1232 1.11.2.2 mycroft off_t newloc;
1233 1.11.2.2 mycroft register struct pte *pte;
1234 1.11.2.2 mycroft
1235 1.11.2.2 mycroft newloc = loc & ~KERNBASE;
1236 1.11.2.2 mycroft p = btop(newloc);
1237 1.11.2.2 mycroft #if defined(vax) || defined(tahoe)
1238 1.11.2.2 mycroft if ((loc & KERNBASE) == 0) {
1239 1.11.2.2 mycroft seterr("vtophys: translating non-kernel address");
1240 1.11.2.2 mycroft return((off_t) -1);
1241 1.11.2.2 mycroft }
1242 1.11.2.2 mycroft #endif
1243 1.11.2.2 mycroft if (p >= Syssize) {
1244 1.11.2.2 mycroft seterr("vtophys: page out of bound (%d>=%d)", p, Syssize);
1245 1.11.2.2 mycroft return((off_t) -1);
1246 1.11.2.2 mycroft }
1247 1.11.2.2 mycroft pte = &Sysmap[p];
1248 1.11.2.2 mycroft if (pte->pg_v == 0 && (pte->pg_fod || pte->pg_pfnum == 0)) {
1249 1.11.2.2 mycroft seterr("vtophys: page not valid");
1250 1.11.2.2 mycroft return((off_t) -1);
1251 1.11.2.2 mycroft }
1252 1.11.2.2 mycroft #if defined(hp300)
1253 1.11.2.2 mycroft if (pte->pg_pfnum < lowram) {
1254 1.11.2.2 mycroft seterr("vtophys: non-RAM page (%d<%d)", pte->pg_pfnum, lowram);
1255 1.11.2.2 mycroft return((off_t) -1);
1256 1.11.2.2 mycroft }
1257 1.11.2.2 mycroft #endif
1258 1.11.2.2 mycroft loc = (long) (ptob(pftoc(pte->pg_pfnum)) + (loc & PGOFSET));
1259 1.11.2.2 mycroft return(loc);
1260 1.11.2.2 mycroft }
1261 1.11.2.2 mycroft #endif
1262 1.11.2.2 mycroft
1263 1.11.2.2 mycroft
1264 1.11.2.2 mycroft #ifdef NEWVM
1265 1.11.2.2 mycroft /*
1266 1.11.2.2 mycroft * locate address of unwired or swapped page
1267 1.11.2.2 mycroft */
1268 1.11.2.2 mycroft
1269 1.11.2.2 mycroft #define DEBUG 0
1270 1.11.2.2 mycroft
1271 1.11.2.2 mycroft #define KREAD(off, addr, len) \
1272 1.11.2.2 mycroft (kvm_read((void *)(off), (char *)(addr), (len)) == (len))
1273 1.11.2.2 mycroft
1274 1.11.2.2 mycroft
1275 1.11.2.2 mycroft static int
1276 1.11.2.2 mycroft vatosw(p, vaddr, maddr, swb)
1277 1.11.2.2 mycroft struct proc *p ;
1278 1.11.2.2 mycroft vm_offset_t vaddr;
1279 1.11.2.2 mycroft vm_offset_t *maddr;
1280 1.11.2.2 mycroft struct swapblk *swb;
1281 1.11.2.2 mycroft {
1282 1.11.2.2 mycroft register struct kinfo_proc *kp = (struct kinfo_proc *)p;
1283 1.11.2.2 mycroft vm_map_t mp = &kp->kp_eproc.e_vm.vm_map;
1284 1.11.2.2 mycroft struct vm_object vm_object;
1285 1.11.2.2 mycroft struct vm_map_entry vm_entry;
1286 1.11.2.2 mycroft struct pager_struct pager;
1287 1.11.2.2 mycroft struct swpager swpager;
1288 1.11.2.2 mycroft struct swblock swblock;
1289 1.11.2.2 mycroft long addr, off;
1290 1.11.2.2 mycroft int i;
1291 1.11.2.2 mycroft
1292 1.11.2.2 mycroft if (p->p_pid == 0 || p->p_pid == 2)
1293 1.11.2.2 mycroft return 0;
1294 1.11.2.2 mycroft
1295 1.11.2.2 mycroft addr = (long)mp->header.next;
1296 1.11.2.2 mycroft for (i = 0; i < mp->nentries; i++) {
1297 1.11.2.2 mycroft /* Weed through map entries until vaddr in range */
1298 1.11.2.2 mycroft if (!KREAD(addr, &vm_entry, sizeof(vm_entry))) {
1299 1.11.2.2 mycroft setsyserr("vatosw: read vm_map_entry");
1300 1.11.2.2 mycroft return 0;
1301 1.11.2.2 mycroft }
1302 1.11.2.2 mycroft if ((vaddr >= vm_entry.start) && (vaddr <= vm_entry.end) &&
1303 1.11.2.2 mycroft (vm_entry.object.vm_object != 0))
1304 1.11.2.2 mycroft break;
1305 1.11.2.2 mycroft
1306 1.11.2.2 mycroft addr = (long)vm_entry.next;
1307 1.11.2.2 mycroft }
1308 1.11.2.2 mycroft if (i == mp->nentries) {
1309 1.11.2.2 mycroft seterr("%u: map not found\n", p->p_pid);
1310 1.11.2.2 mycroft return 0;
1311 1.11.2.2 mycroft }
1312 1.11.2.2 mycroft
1313 1.11.2.2 mycroft if (vm_entry.is_a_map || vm_entry.is_sub_map) {
1314 1.11.2.2 mycroft seterr("%u: Is a map\n", p->p_pid);
1315 1.11.2.2 mycroft return 0;
1316 1.11.2.2 mycroft }
1317 1.11.2.2 mycroft
1318 1.11.2.2 mycroft /* Locate memory object */
1319 1.11.2.2 mycroft off = (vaddr - vm_entry.start) + vm_entry.offset;
1320 1.11.2.2 mycroft addr = (long)vm_entry.object.vm_object;
1321 1.11.2.2 mycroft while (1) {
1322 1.11.2.2 mycroft if (!KREAD(addr, &vm_object, sizeof vm_object)) {
1323 1.11.2.2 mycroft setsyserr("vatosw: read vm_object");
1324 1.11.2.2 mycroft return 0;
1325 1.11.2.2 mycroft }
1326 1.11.2.2 mycroft
1327 1.11.2.2 mycroft #if DEBUG
1328 1.11.2.2 mycroft fprintf(stderr, "%u: find page: object %#x offset %x\n",
1329 1.11.2.2 mycroft p->p_pid, addr, off);
1330 1.11.2.2 mycroft #endif
1331 1.11.2.2 mycroft
1332 1.11.2.2 mycroft /* Lookup in page queue */
1333 1.11.2.2 mycroft if (findpage(addr, off, maddr))
1334 1.11.2.2 mycroft return 1;
1335 1.11.2.2 mycroft
1336 1.11.2.2 mycroft if (vm_object.shadow == 0)
1337 1.11.2.2 mycroft break;
1338 1.11.2.2 mycroft
1339 1.11.2.2 mycroft #if DEBUG
1340 1.11.2.2 mycroft fprintf(stderr, "%u: shadow obj at %x: offset %x+%x\n",
1341 1.11.2.2 mycroft p->p_pid, addr, off, vm_object.shadow_offset);
1342 1.11.2.2 mycroft #endif
1343 1.11.2.2 mycroft
1344 1.11.2.2 mycroft addr = (long)vm_object.shadow;
1345 1.11.2.2 mycroft off += vm_object.shadow_offset;
1346 1.11.2.2 mycroft }
1347 1.11.2.2 mycroft
1348 1.11.2.2 mycroft if (!vm_object.pager) {
1349 1.11.2.2 mycroft seterr("%u: no pager\n", p->p_pid);
1350 1.11.2.2 mycroft return 0;
1351 1.11.2.2 mycroft }
1352 1.11.2.2 mycroft
1353 1.11.2.2 mycroft /* Find address in swap space */
1354 1.11.2.2 mycroft if (!KREAD(vm_object.pager, &pager, sizeof pager)) {
1355 1.11.2.2 mycroft setsyserr("vatosw: read pager");
1356 1.11.2.2 mycroft return 0;
1357 1.11.2.2 mycroft }
1358 1.11.2.2 mycroft if (pager.pg_type != PG_SWAP) {
1359 1.11.2.2 mycroft seterr("%u: weird pager\n", p->p_pid);
1360 1.11.2.2 mycroft return 0;
1361 1.11.2.2 mycroft }
1362 1.11.2.2 mycroft
1363 1.11.2.2 mycroft /* Get swap pager data */
1364 1.11.2.2 mycroft if (!KREAD(pager.pg_data, &swpager, sizeof swpager)) {
1365 1.11.2.2 mycroft setsyserr("vatosw: read swpager");
1366 1.11.2.2 mycroft return 0;
1367 1.11.2.2 mycroft }
1368 1.11.2.2 mycroft
1369 1.11.2.2 mycroft off += vm_object.paging_offset;
1370 1.11.2.2 mycroft
1371 1.11.2.2 mycroft /* Read swap block array */
1372 1.11.2.2 mycroft if (!KREAD((long)swpager.sw_blocks +
1373 1.11.2.2 mycroft (off/dbtob(swpager.sw_bsize)) * sizeof swblock,
1374 1.11.2.2 mycroft &swblock, sizeof swblock)) {
1375 1.11.2.2 mycroft setsyserr("vatosw: read swblock");
1376 1.11.2.2 mycroft return 0;
1377 1.11.2.2 mycroft }
1378 1.11.2.2 mycroft swb->offset = dbtob(swblock.swb_block)+ (off % dbtob(swpager.sw_bsize));
1379 1.11.2.2 mycroft swb->size = dbtob(swpager.sw_bsize) - (off % dbtob(swpager.sw_bsize));
1380 1.11.2.2 mycroft return 1;
1381 1.11.2.2 mycroft }
1382 1.11.2.2 mycroft
1383 1.11.2.2 mycroft
1384 1.11.2.2 mycroft #define atop(x) (((unsigned)(x)) >> page_shift)
1385 1.11.2.2 mycroft #define vm_page_hash(object, offset) \
1386 1.11.2.2 mycroft (((unsigned)object+(unsigned)atop(offset))&vm_page_hash_mask)
1387 1.11.2.2 mycroft
1388 1.11.2.2 mycroft static int
1389 1.11.2.2 mycroft findpage(object, offset, maddr)
1390 1.11.2.2 mycroft long object;
1391 1.11.2.2 mycroft long offset;
1392 1.11.2.2 mycroft vm_offset_t *maddr;
1393 1.11.2.2 mycroft {
1394 1.11.2.2 mycroft static long vm_page_hash_mask;
1395 1.11.2.2 mycroft static long vm_page_buckets;
1396 1.11.2.2 mycroft static long page_shift;
1397 1.11.2.2 mycroft queue_head_t bucket;
1398 1.11.2.2 mycroft struct vm_page mem;
1399 1.11.2.2 mycroft long addr, baddr;
1400 1.11.2.2 mycroft
1401 1.11.2.2 mycroft if (vm_page_hash_mask == 0 && !KREAD(nl[X_VM_PAGE_HASH_MASK].n_value,
1402 1.11.2.2 mycroft &vm_page_hash_mask, sizeof (long))) {
1403 1.11.2.2 mycroft seterr("can't read vm_page_hash_mask");
1404 1.11.2.2 mycroft return 0;
1405 1.11.2.2 mycroft }
1406 1.11.2.2 mycroft if (page_shift == 0 && !KREAD(nl[X_PAGE_SHIFT].n_value,
1407 1.11.2.2 mycroft &page_shift, sizeof (long))) {
1408 1.11.2.2 mycroft seterr("can't read page_shift");
1409 1.11.2.2 mycroft return 0;
1410 1.11.2.2 mycroft }
1411 1.11.2.2 mycroft if (vm_page_buckets == 0 && !KREAD(nl[X_VM_PAGE_BUCKETS].n_value,
1412 1.11.2.2 mycroft &vm_page_buckets, sizeof (long))) {
1413 1.11.2.2 mycroft seterr("can't read vm_page_buckets");
1414 1.11.2.2 mycroft return 0;
1415 1.11.2.2 mycroft }
1416 1.11.2.2 mycroft
1417 1.11.2.2 mycroft baddr = vm_page_buckets + vm_page_hash(object,offset) * sizeof(queue_head_t);
1418 1.11.2.2 mycroft if (!KREAD(baddr, &bucket, sizeof (bucket))) {
1419 1.11.2.2 mycroft seterr("can't read vm_page_bucket");
1420 1.11.2.2 mycroft return 0;
1421 1.11.2.2 mycroft }
1422 1.11.2.2 mycroft
1423 1.11.2.2 mycroft addr = (long)bucket.next;
1424 1.11.2.2 mycroft while (addr != baddr) {
1425 1.11.2.2 mycroft if (!KREAD(addr, &mem, sizeof (mem))) {
1426 1.11.2.2 mycroft seterr("can't read vm_page");
1427 1.11.2.2 mycroft return 0;
1428 1.11.2.2 mycroft }
1429 1.11.2.2 mycroft if ((long)mem.object == object && mem.offset == offset) {
1430 1.11.2.2 mycroft *maddr = (long)mem.phys_addr;
1431 1.11.2.2 mycroft return 1;
1432 1.11.2.2 mycroft }
1433 1.11.2.2 mycroft addr = (long)mem.hashq.next;
1434 1.11.2.2 mycroft }
1435 1.11.2.2 mycroft return 0;
1436 1.11.2.2 mycroft }
1437 1.11.2.2 mycroft #endif /* NEWVM */
1438 1.11.2.2 mycroft
1439 1.11.2.2 mycroft #include <varargs.h>
1440 1.11.2.2 mycroft static char errbuf[_POSIX2_LINE_MAX];
1441 1.11.2.2 mycroft
1442 1.11.2.2 mycroft static void
1443 1.11.2.2 mycroft seterr(va_alist)
1444 1.11.2.2 mycroft va_dcl
1445 1.11.2.2 mycroft {
1446 1.11.2.2 mycroft char *fmt;
1447 1.11.2.2 mycroft va_list ap;
1448 1.11.2.2 mycroft
1449 1.11.2.2 mycroft va_start(ap);
1450 1.11.2.2 mycroft fmt = va_arg(ap, char *);
1451 1.11.2.2 mycroft (void) vsnprintf(errbuf, _POSIX2_LINE_MAX, fmt, ap);
1452 1.11.2.2 mycroft #if DEBUG
1453 1.11.2.2 mycroft (void) vfprintf(stderr, fmt, ap);
1454 1.11.2.2 mycroft #endif
1455 1.11.2.2 mycroft va_end(ap);
1456 1.11.2.2 mycroft }
1457 1.11.2.2 mycroft
1458 1.11.2.2 mycroft static void
1459 1.11.2.2 mycroft setsyserr(va_alist)
1460 1.11.2.2 mycroft va_dcl
1461 1.11.2.2 mycroft {
1462 1.11.2.2 mycroft char *fmt, *cp;
1463 1.11.2.2 mycroft va_list ap;
1464 1.11.2.2 mycroft extern int errno;
1465 1.11.2.2 mycroft
1466 1.11.2.2 mycroft va_start(ap);
1467 1.11.2.2 mycroft fmt = va_arg(ap, char *);
1468 1.11.2.2 mycroft (void) vsnprintf(errbuf, _POSIX2_LINE_MAX, fmt, ap);
1469 1.11.2.2 mycroft for (cp=errbuf; *cp; cp++)
1470 1.11.2.2 mycroft ;
1471 1.11.2.2 mycroft snprintf(cp, _POSIX2_LINE_MAX - (cp - errbuf), ": %s", strerror(errno));
1472 1.11.2.2 mycroft va_end(ap);
1473 1.11.2.2 mycroft }
1474 1.11.2.2 mycroft
1475 1.11.2.2 mycroft char *
1476 1.11.2.2 mycroft kvm_geterr()
1477 1.11.2.2 mycroft {
1478 1.11.2.2 mycroft return (errbuf);
1479 1.11.2.2 mycroft }
1480