initialize before use
[unix-history] / usr / src / usr.sbin / pstat / pstat.c
CommitLineData
5ff67f98
DF
1/*
2 * Copyright (c) 1980 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
ae1f9014 7#ifndef lint
5ff67f98
DF
8char copyright[] =
9"@(#) Copyright (c) 1980 Regents of the University of California.\n\
10 All rights reserved.\n";
11#endif not lint
12
13#ifndef lint
76ea98af 14static char sccsid[] = "@(#)pstat.c 5.2 (Berkeley) %G%";
5ff67f98
DF
15#endif not lint
16
ceb84881
BJ
17/*
18 * Print system stuff
19 */
20
21#define mask(x) (x&0377)
22#define clear(x) ((int)x&0x7fffffff)
23
24#include <sys/param.h>
25#include <sys/dir.h>
ae1f9014 26#define KERNEL
ceb84881 27#include <sys/file.h>
ae1f9014 28#undef KERNEL
ceb84881
BJ
29#include <sys/user.h>
30#include <sys/proc.h>
31#include <sys/text.h>
32#include <sys/inode.h>
33#include <sys/map.h>
88a58f27 34#include <sys/ioctl.h>
ceb84881
BJ
35#include <sys/tty.h>
36#include <sys/conf.h>
37#include <sys/vm.h>
38#include <nlist.h>
0bc29a7d 39#include <machine/pte.h>
ceb84881
BJ
40
41char *fcore = "/dev/kmem";
aadf0902 42char *fmem = "/dev/mem";
ceb84881 43char *fnlist = "/vmunix";
aadf0902 44int fc, fm;
ceb84881
BJ
45
46struct nlist nl[] = {
47#define SINODE 0
48 { "_inode" },
49#define STEXT 1
50 { "_text" },
51#define SPROC 2
52 { "_proc" },
53#define SDZ 3
54 { "_dz_tty" },
55#define SNDZ 4
56 { "_dz_cnt" },
57#define SKL 5
58 { "_cons" },
59#define SFIL 6
60 { "_file" },
61#define USRPTMA 7
62 { "_Usrptmap" },
63#define USRPT 8
64 { "_usrpt" },
b94a50ef 65#define SWAPMAP 9
ceb84881 66 { "_swapmap" },
b94a50ef 67#define SDH 10
ceb84881 68 { "_dh11" },
b94a50ef 69#define SNDH 11
ceb84881 70 { "_ndh11" },
b94a50ef 71#define SNPROC 12
69d3d166 72 { "_nproc" },
b94a50ef 73#define SNTEXT 13
69d3d166 74 { "_ntext" },
b94a50ef 75#define SNFILE 14
69d3d166 76 { "_nfile" },
b94a50ef 77#define SNINODE 15
69d3d166 78 { "_ninode" },
b94a50ef 79#define SNSWAPMAP 16
69d3d166 80 { "_nswapmap" },
b94a50ef 81#define SPTY 17
676bc34a 82 { "_pt_tty" },
b94a50ef 83#define SDMMIN 18
e79dc02e 84 { "_dmmin" },
b94a50ef 85#define SDMMAX 19
e79dc02e 86 { "_dmmax" },
b94a50ef 87#define SNSWDEV 20
e79dc02e 88 { "_nswdev" },
b94a50ef
SL
89#define SSWDEVT 21
90 { "_swdevt" },
890571d1
RC
91#define SDMF 22
92 { "_dmf_tty" },
93#define SNDMF 23
94 { "_ndmf" },
13562341
MK
95#define SNPTY 24
96 { "_npty" },
76ea98af
KM
97#define SYSMAP 25
98 { "_Sysmap" },
b94a50ef 99 { "" }
ceb84881
BJ
100};
101
102int inof;
103int txtf;
104int prcf;
105int ttyf;
106int usrf;
107long ubase;
108int filf;
109int swpf;
110int totflg;
111char partab[1];
112struct cdevsw cdevsw[1];
113struct bdevsw bdevsw[1];
114int allflg;
115int kflg;
116struct pte *Usrptma;
117struct pte *usrpt;
118
119main(argc, argv)
120char **argv;
121{
122 register char *argp;
ae1f9014 123 int allflags;
ceb84881
BJ
124
125 argc--, argv++;
126 while (argc > 0 && **argv == '-') {
127 argp = *argv++;
128 argp++;
129 argc--;
130 while (*argp++)
131 switch (argp[-1]) {
132
133 case 'T':
134 totflg++;
135 break;
136
137 case 'a':
138 allflg++;
139 break;
140
141 case 'i':
142 inof++;
143 break;
144
145 case 'k':
146 kflg++;
aadf0902 147 fcore = fmem = "/vmcore";
ceb84881
BJ
148 break;
149
150 case 'x':
151 txtf++;
152 break;
153
154 case 'p':
155 prcf++;
156 break;
157
158 case 't':
159 ttyf++;
160 break;
161
162 case 'u':
163 if (argc == 0)
164 break;
165 argc--;
166 usrf++;
167 sscanf( *argv++, "%x", &ubase);
168 break;
169
170 case 'f':
171 filf++;
172 break;
173 case 's':
174 swpf++;
175 break;
ae1f9014
SL
176 default:
177 usage();
178 exit(1);
ceb84881
BJ
179 }
180 }
ae1f9014 181 if (argc>1)
aadf0902 182 fcore = fmem = argv[1];
ceb84881
BJ
183 if ((fc = open(fcore, 0)) < 0) {
184 printf("Can't find %s\n", fcore);
185 exit(1);
186 }
aadf0902
MK
187 if ((fm = open(fmem, 0)) < 0) {
188 printf("Can't find %s\n", fmem);
189 exit(1);
190 }
ae1f9014
SL
191 if (argc>0)
192 fnlist = argv[0];
ceb84881 193 nlist(fnlist, nl);
ceb84881
BJ
194 usrpt = (struct pte *)nl[USRPT].n_value;
195 Usrptma = (struct pte *)nl[USRPTMA].n_value;
196 if (nl[0].n_type == 0) {
197 printf("no namelist\n");
198 exit(1);
199 }
ae1f9014
SL
200 allflags = filf | totflg | inof | prcf | txtf | ttyf | usrf | swpf;
201 if (allflags == 0) {
202 printf("pstat: one or more of -[aixptfsu] is required\n");
203 exit(1);
204 }
ceb84881 205 if (filf||totflg)
69d3d166 206 dofile();
ceb84881
BJ
207 if (inof||totflg)
208 doinode();
209 if (prcf||totflg)
210 doproc();
211 if (txtf||totflg)
212 dotext();
213 if (ttyf)
214 dotty();
215 if (usrf)
216 dousr();
217 if (swpf||totflg)
218 doswap();
219}
220
ae1f9014
SL
221usage()
222{
223
224 printf("usage: pstat -[aixptfs] [-u [ubase]] [system] [core]\n");
225}
226
ceb84881
BJ
227doinode()
228{
229 register struct inode *ip;
69d3d166
BJ
230 struct inode *xinode, *ainode;
231 register int nin;
232 int ninode;
ceb84881
BJ
233
234 nin = 0;
69d3d166
BJ
235 ninode = getw(nl[SNINODE].n_value);
236 xinode = (struct inode *)calloc(ninode, sizeof (struct inode));
76ea98af
KM
237 ainode = (struct inode *)getw(nl[SINODE].n_value);
238 lseek(fc, mkphys((int)ainode), 0);
69d3d166
BJ
239 read(fc, xinode, ninode * sizeof(struct inode));
240 for (ip = xinode; ip < &xinode[ninode]; ip++)
ceb84881
BJ
241 if (ip->i_count)
242 nin++;
243 if (totflg) {
69d3d166 244 printf("%3d/%3d inodes\n", nin, ninode);
ceb84881
BJ
245 return;
246 }
69d3d166 247 printf("%d/%d active inodes\n", nin, ninode);
ae1f9014 248printf(" LOC FLAGS CNT DEVICE RDC WRC INO MODE NLK UID SIZE/DEV\n");
69d3d166 249 for (ip = xinode; ip < &xinode[ninode]; ip++) {
ceb84881
BJ
250 if (ip->i_count == 0)
251 continue;
69d3d166 252 printf("%8.1x ", ainode + (ip - xinode));
88a58f27 253 putf(ip->i_flag&ILOCKED, 'L');
ceb84881
BJ
254 putf(ip->i_flag&IUPD, 'U');
255 putf(ip->i_flag&IACC, 'A');
256 putf(ip->i_flag&IMOUNT, 'M');
257 putf(ip->i_flag&IWANT, 'W');
258 putf(ip->i_flag&ITEXT, 'T');
ae1f9014
SL
259 putf(ip->i_flag&ICHG, 'C');
260 putf(ip->i_flag&ISHLOCK, 'S');
261 putf(ip->i_flag&IEXLOCK, 'E');
262 putf(ip->i_flag&ILWAIT, 'Z');
ceb84881
BJ
263 printf("%4d", ip->i_count&0377);
264 printf("%4d,%3d", major(ip->i_dev), minor(ip->i_dev));
88a58f27
SL
265 printf("%4d", ip->i_shlockc&0377);
266 printf("%4d", ip->i_exlockc&0377);
ceb84881
BJ
267 printf("%6d", ip->i_number);
268 printf("%6x", ip->i_mode & 0xffff);
269 printf("%4d", ip->i_nlink);
270 printf("%4d", ip->i_uid);
271 if ((ip->i_mode&IFMT)==IFBLK || (ip->i_mode&IFMT)==IFCHR)
a06cf6a1 272 printf("%6d,%3d", major(ip->i_rdev), minor(ip->i_rdev));
ceb84881
BJ
273 else
274 printf("%10ld", ip->i_size);
275 printf("\n");
276 }
69d3d166
BJ
277 free(xinode);
278}
279
280getw(loc)
281 off_t loc;
282{
283 int word;
284
cea9ae1e
BJ
285 if (kflg)
286 loc &= 0x7fffffff;
69d3d166
BJ
287 lseek(fc, loc, 0);
288 read(fc, &word, sizeof (word));
adea9260
BJ
289 if (kflg)
290 word &= 0x7fffffff;
69d3d166 291 return (word);
ceb84881
BJ
292}
293
294putf(v, n)
295{
296 if (v)
297 printf("%c", n);
298 else
69d3d166 299 printf(" ");
ceb84881
BJ
300}
301
302dotext()
303{
304 register struct text *xp;
69d3d166
BJ
305 int ntext;
306 struct text *xtext, *atext;
ceb84881
BJ
307 int ntx;
308
309 ntx = 0;
69d3d166
BJ
310 ntext = getw(nl[SNTEXT].n_value);
311 xtext = (struct text *)calloc(ntext, sizeof (struct text));
76ea98af
KM
312 atext = (struct text *)getw(nl[STEXT].n_value);
313 lseek(fc, mkphys((int)atext), 0);
69d3d166
BJ
314 read(fc, xtext, ntext * sizeof (struct text));
315 for (xp = xtext; xp < &xtext[ntext]; xp++)
ceb84881
BJ
316 if (xp->x_iptr!=NULL)
317 ntx++;
318 if (totflg) {
69d3d166 319 printf("%3d/%3d texts\n", ntx, ntext);
ceb84881
BJ
320 return;
321 }
69d3d166 322 printf("%d/%d active texts\n", ntx, ntext);
54298f71 323 printf(" LOC FLAGS DADDR CADDR RSS SIZE IPTR CNT CCNT\n");
69d3d166 324 for (xp = xtext; xp < &xtext[ntext]; xp++) {
ceb84881
BJ
325 if (xp->x_iptr == NULL)
326 continue;
69d3d166 327 printf("%8.1x", atext + (xp - xtext));
ceb84881
BJ
328 printf(" ");
329 putf(xp->x_flag&XPAGI, 'P');
330 putf(xp->x_flag&XTRC, 'T');
331 putf(xp->x_flag&XWRIT, 'W');
332 putf(xp->x_flag&XLOAD, 'L');
333 putf(xp->x_flag&XLOCK, 'K');
334 putf(xp->x_flag&XWANT, 'w');
ceb84881
BJ
335 printf("%5x", xp->x_daddr[0]);
336 printf("%11x", xp->x_caddr);
337 printf("%5d", xp->x_rssize);
338 printf("%5d", xp->x_size);
339 printf("%10.1x", xp->x_iptr);
340 printf("%5d", xp->x_count&0377);
54298f71 341 printf("%5d", xp->x_ccount);
ceb84881
BJ
342 printf("\n");
343 }
69d3d166 344 free(xtext);
ceb84881
BJ
345}
346
347doproc()
348{
69d3d166
BJ
349 struct proc *xproc, *aproc;
350 int nproc;
ceb84881
BJ
351 register struct proc *pp;
352 register loc, np;
353 struct pte apte;
354
69d3d166
BJ
355 nproc = getw(nl[SNPROC].n_value);
356 xproc = (struct proc *)calloc(nproc, sizeof (struct proc));
76ea98af
KM
357 aproc = (struct proc *)getw(nl[SPROC].n_value);
358 lseek(fc, mkphys((int)aproc), 0);
69d3d166 359 read(fc, xproc, nproc * sizeof (struct proc));
ceb84881 360 np = 0;
69d3d166 361 for (pp=xproc; pp < &xproc[nproc]; pp++)
ceb84881
BJ
362 if (pp->p_stat)
363 np++;
364 if (totflg) {
69d3d166 365 printf("%3d/%3d processes\n", np, nproc);
ceb84881
BJ
366 return;
367 }
69d3d166 368 printf("%d/%d processes\n", np, nproc);
aadf0902 369 printf(" LOC S F POIP PRI SIG UID SLP TIM CPU NI PGRP PID PPID ADDR RSS SRSS SIZE WCHAN LINK TEXTP\n");
69d3d166 370 for (pp=xproc; pp<&xproc[nproc]; pp++) {
ceb84881
BJ
371 if (pp->p_stat==0 && allflg==0)
372 continue;
69d3d166 373 printf("%8x", aproc + (pp - xproc));
ceb84881
BJ
374 printf(" %2d", pp->p_stat);
375 printf(" %4x", pp->p_flag & 0xffff);
376 printf(" %4d", pp->p_poip);
377 printf(" %3d", pp->p_pri);
54298f71 378 printf(" %8x", pp->p_sig);
ceb84881
BJ
379 printf(" %4d", pp->p_uid);
380 printf(" %3d", pp->p_slptime);
381 printf(" %3d", pp->p_time);
382 printf(" %4d", pp->p_cpu&0377);
383 printf(" %3d", pp->p_nice);
384 printf(" %6d", pp->p_pgrp);
385 printf(" %6d", pp->p_pid);
386 printf(" %6d", pp->p_ppid);
387 if (kflg)
388 pp->p_addr = (struct pte *)clear((int)pp->p_addr);
aadf0902
MK
389 if (pp->p_flag & SLOAD) {
390 lseek(fc, (long)pp->p_addr, 0);
391 read(fc, &apte, sizeof(apte));
392 printf(" %8x", apte.pg_pfnum);
393 } else
394 printf(" %8x", pp->p_swaddr);
ceb84881
BJ
395 printf(" %4x", pp->p_rssize);
396 printf(" %4x", pp->p_swrss);
397 printf(" %5x", pp->p_dsize+pp->p_ssize);
398 printf(" %7x", clear(pp->p_wchan));
399 printf(" %7x", clear(pp->p_link));
400 printf(" %7x", clear(pp->p_textp));
ceb84881
BJ
401 printf("\n");
402 }
403}
404
405dotty()
406{
13562341
MK
407 struct tty *tty;
408 int ntty, ttyspace = 128;
ceb84881 409 register struct tty *tp;
13562341 410 extern char *malloc(), *realloc();
8faa0fee
EW
411 static char mesg[] =
412 " # RAW CAN OUT MODE ADDR DEL COL STATE PGRP DISC\n";
ceb84881 413
13562341
MK
414 if ((tty = (struct tty *)malloc(ttyspace * sizeof(*tty))) == 0) {
415 printf("pstat: out of memory\n");
416 return;
417 }
ceb84881 418 printf("1 cons\n");
835c8965
BJ
419 if (kflg)
420 nl[SKL].n_value = clear(nl[SKL].n_value);
ceb84881 421 lseek(fc, (long)nl[SKL].n_value, 0);
13562341 422 read(fc, tty, sizeof(*tty));
ceb84881 423 printf(mesg);
13562341 424 ttyprt(&tty[0], 0);
2a63498c 425 if (nl[SNDZ].n_type == 0)
ceb84881 426 goto dh;
835c8965
BJ
427 if (kflg) {
428 nl[SNDZ].n_value = clear(nl[SNDZ].n_value);
429 nl[SDZ].n_value = clear(nl[SDZ].n_value);
430 }
ceb84881 431 lseek(fc, (long)nl[SNDZ].n_value, 0);
13562341
MK
432 read(fc, &ntty, sizeof(ntty));
433 printf("%d dz lines\n", ntty);
434 if (ntty > ttyspace) {
435 ttyspace = ntty;
436 if ((tty = (struct tty *)realloc(tty, ttyspace * sizeof(*tty))) == 0) {
437 printf("pstat: out of memory\n");
438 return;
439 }
440 }
ceb84881 441 lseek(fc, (long)nl[SDZ].n_value, 0);
13562341 442 read(fc, tty, ntty * sizeof (struct tty));
8faa0fee 443 printf(mesg);
13562341
MK
444 for (tp = tty; tp < &tty[ntty]; tp++)
445 ttyprt(tp, tp - tty);
ceb84881 446dh:
2a63498c 447 if (nl[SNDH].n_type == 0)
890571d1 448 goto dmf;
835c8965
BJ
449 if (kflg) {
450 nl[SNDH].n_value = clear(nl[SNDH].n_value);
451 nl[SDH].n_value = clear(nl[SDH].n_value);
452 }
ceb84881 453 lseek(fc, (long)nl[SNDH].n_value, 0);
13562341
MK
454 read(fc, &ntty, sizeof(ntty));
455 printf("%d dh lines\n", ntty);
456 if (ntty > ttyspace) {
457 ttyspace = ntty;
458 if ((tty = (struct tty *)realloc(tty, ttyspace * sizeof(*tty))) == 0) {
459 printf("pstat: out of memory\n");
460 return;
461 }
462 }
ceb84881 463 lseek(fc, (long)nl[SDH].n_value, 0);
13562341 464 read(fc, tty, ntty * sizeof(struct tty));
8faa0fee 465 printf(mesg);
13562341
MK
466 for (tp = tty; tp < &tty[ntty]; tp++)
467 ttyprt(tp, tp - tty);
890571d1
RC
468dmf:
469 if (nl[SNDMF].n_type == 0)
470 goto pty;
471 if (kflg) {
472 nl[SNDMF].n_value = clear(nl[SNDMF].n_value);
473 nl[SDMF].n_value = clear(nl[SDMF].n_value);
474 }
475 lseek(fc, (long)nl[SNDMF].n_value, 0);
13562341
MK
476 read(fc, &ntty, sizeof(ntty));
477 printf("%d dmf lines\n", ntty);
478 if (ntty > ttyspace) {
479 ttyspace = ntty;
480 if ((tty = (struct tty *)realloc(tty, ttyspace * sizeof(*tty))) == 0) {
481 printf("pstat: out of memory\n");
482 return;
483 }
484 }
890571d1 485 lseek(fc, (long)nl[SDMF].n_value, 0);
13562341 486 read(fc, tty, ntty * sizeof(struct tty));
8faa0fee 487 printf(mesg);
13562341
MK
488 for (tp = tty; tp < &tty[ntty]; tp++)
489 ttyprt(tp, tp - tty);
676bc34a
BJ
490pty:
491 if (nl[SPTY].n_type == 0)
890571d1 492 return;
676bc34a
BJ
493 if (kflg) {
494 nl[SPTY].n_value = clear(nl[SPTY].n_value);
13562341
MK
495 nl[SNPTY].n_value = clear(nl[SNPTY].n_value);
496 }
497 lseek(fc, (long)nl[SNPTY].n_value, 0);
498 read(fc, &ntty, sizeof(ntty));
499 printf("%d pty lines\n", ntty);
500 if (ntty > ttyspace) {
501 ttyspace = ntty;
502 if ((tty = (struct tty *)realloc(tty, ttyspace * sizeof(*tty))) == 0) {
503 printf("pstat: out of memory\n");
504 return;
505 }
676bc34a 506 }
676bc34a 507 lseek(fc, (long)nl[SPTY].n_value, 0);
13562341 508 read(fc, tty, ntty*sizeof(struct tty));
8faa0fee 509 printf(mesg);
13562341
MK
510 for (tp = tty; tp < &tty[ntty]; tp++)
511 ttyprt(tp, tp - tty);
ceb84881
BJ
512}
513
514ttyprt(atp, line)
515struct tty *atp;
516{
517 register struct tty *tp;
518
519 printf("%2d", line);
520 tp = atp;
521 switch (tp->t_line) {
522
676bc34a 523/*
ceb84881
BJ
524 case NETLDISC:
525 if (tp->t_rec)
526 printf("%4d%4d", 0, tp->t_inbuf);
527 else
528 printf("%4d%4d", tp->t_inbuf, 0);
529 break;
676bc34a 530*/
ceb84881
BJ
531
532 default:
8faa0fee 533 printf("%4d%4d", tp->t_rawq.c_cc, tp->t_canq.c_cc);
ceb84881 534 }
8faa0fee
EW
535 printf("%4d %8x %8x%4d%4d", tp->t_outq.c_cc, tp->t_flags,
536 tp->t_addr, tp->t_delct, tp->t_col);
676bc34a
BJ
537 putf(tp->t_state&TS_TIMEOUT, 'T');
538 putf(tp->t_state&TS_WOPEN, 'W');
539 putf(tp->t_state&TS_ISOPEN, 'O');
8faa0fee 540 putf(tp->t_state&TS_FLUSH, 'F');
676bc34a
BJ
541 putf(tp->t_state&TS_CARR_ON, 'C');
542 putf(tp->t_state&TS_BUSY, 'B');
543 putf(tp->t_state&TS_ASLEEP, 'A');
544 putf(tp->t_state&TS_XCLUDE, 'X');
8faa0fee 545 putf(tp->t_state&TS_TTSTOP, 'S');
676bc34a 546 putf(tp->t_state&TS_HUPCLS, 'H');
ceb84881
BJ
547 printf("%6d", tp->t_pgrp);
548 switch (tp->t_line) {
549
8faa0fee
EW
550 case OTTYDISC:
551 printf("\n");
552 break;
553
ceb84881 554 case NTTYDISC:
8faa0fee 555 printf(" ntty\n");
ceb84881
BJ
556 break;
557
558 case NETLDISC:
8faa0fee 559 printf(" net\n");
ceb84881 560 break;
8faa0fee
EW
561
562 case TABLDISC:
563 printf(" tab\n");
564 break;
565
566 case NTABLDISC:
567 printf(" ntab\n");
568 break;
569
570 default:
571 printf(" %d\n", tp->t_line);
ceb84881 572 }
ceb84881
BJ
573}
574
575dousr()
576{
577 struct user U;
578 register i, j, *ip;
a5bcb7fd 579 register struct nameidata *nd = &U.u_nd;
ceb84881 580
aadf0902
MK
581 /* This wins only if CLBYTES >= sizeof (struct user) */
582 lseek(fm, ubase * NBPG, 0);
583 read(fm, &U, sizeof(U));
ceb84881
BJ
584 printf("pcb");
585 ip = (int *)&U.u_pcb;
586 while (ip < &U.u_arg[0]) {
587 if ((ip - (int *)&U.u_pcb) % 4 == 0)
588 printf("\t");
589 printf("%x ", *ip++);
590 if ((ip - (int *)&U.u_pcb) % 4 == 0)
591 printf("\n");
592 }
593 if ((ip - (int *)&U.u_pcb) % 4 != 0)
594 printf("\n");
aadf0902
MK
595 printf("arg");
596 for (i=0; i<sizeof(U.u_arg)/sizeof(U.u_arg[0]); i++) {
ceb84881
BJ
597 if (i%5==0)
598 printf("\t");
aadf0902 599 printf(" %.1x", U.u_arg[i]);
ceb84881
BJ
600 if (i%5==4)
601 printf("\n");
602 }
603 if (i%5)
604 printf("\n");
a5bcb7fd 605 printf("segflg\t%d\nerror %d\n", nd->ni_segflg, U.u_error);
ceb84881
BJ
606 printf("uids\t%d,%d,%d,%d\n", U.u_uid,U.u_gid,U.u_ruid,U.u_rgid);
607 printf("procp\t%.1x\n", U.u_procp);
608 printf("ap\t%.1x\n", U.u_ap);
609 printf("r_val?\t%.1x %.1x\n", U.u_r.r_val1, U.u_r.r_val2);
a5bcb7fd
JB
610 printf("base, count, offset %.1x %.1x %ld\n", nd->ni_base,
611 nd->ni_count, nd->ni_offset);
ceb84881 612 printf("cdir rdir %.1x %.1x\n", U.u_cdir, U.u_rdir);
a5bcb7fd
JB
613 printf("dirp %.1x\n", nd->ni_dirp);
614 printf("dent %d %.14s\n", nd->ni_dent.d_ino, nd->ni_dent.d_name);
615 printf("pdir %.1o\n", nd->ni_pdir);
aadf0902
MK
616 printf("file");
617 for (i=0; i<NOFILE; i++) {
618 if (i % 8 == 0)
619 printf("\t");
ceb84881 620 printf("%9.1x", U.u_ofile[i]);
aadf0902
MK
621 if (i % 8 == 7)
622 printf("\n");
623 }
624 if (i % 8)
625 printf("\n");
626 printf("pofile");
627 for (i=0; i<NOFILE; i++) {
628 if (i % 8 == 0)
629 printf("\t");
ceb84881 630 printf("%9.1x", U.u_pofile[i]);
aadf0902
MK
631 if (i % 8 == 7)
632 printf("\n");
633 }
634 if (i % 8)
635 printf("\n");
88a58f27 636 printf("ssave");
ceb84881
BJ
637 for (i=0; i<sizeof(label_t)/sizeof(int); i++) {
638 if (i%5==0)
639 printf("\t");
88a58f27 640 printf("%9.1x", U.u_ssave.val[i]);
ceb84881
BJ
641 if (i%5==4)
642 printf("\n");
643 }
644 if (i%5)
645 printf("\n");
aadf0902
MK
646 printf("sigs");
647 for (i=0; i<NSIG; i++) {
648 if (i % 8 == 0)
649 printf("\t");
ceb84881 650 printf("%.1x ", U.u_signal[i]);
aadf0902
MK
651 if (i % 8 == 7)
652 printf("\n");
653 }
654 if (i % 8)
655 printf("\n");
df3e00cc 656 printf("code\t%.1x\n", U.u_code);
ceb84881
BJ
657 printf("ar0\t%.1x\n", U.u_ar0);
658 printf("prof\t%X %X %X %X\n", U.u_prof.pr_base, U.u_prof.pr_size,
659 U.u_prof.pr_off, U.u_prof.pr_scale);
660 printf("\neosys\t%d\n", U.u_eosys);
ceb84881
BJ
661 printf("ttyp\t%.1x\n", U.u_ttyp);
662 printf("ttyd\t%d,%d\n", major(U.u_ttyd), minor(U.u_ttyd));
ceb84881
BJ
663 printf("comm %.14s\n", U.u_comm);
664 printf("start\t%D\n", U.u_start);
665 printf("acflag\t%D\n", U.u_acflag);
ceb84881
BJ
666 printf("cmask\t%D\n", U.u_cmask);
667 printf("sizes\t%.1x %.1x %.1x\n", U.u_tsize, U.u_dsize, U.u_ssize);
88a58f27
SL
668 printf("ru\t");
669 ip = (int *)&U.u_ru;
670 for (i = 0; i < sizeof(U.u_ru)/sizeof(int); i++)
ceb84881
BJ
671 printf("%D ", ip[i]);
672 printf("\n");
88a58f27
SL
673 ip = (int *)&U.u_cru;
674 printf("cru\t");
675 for (i = 0; i < sizeof(U.u_cru)/sizeof(int); i++)
ceb84881
BJ
676 printf("%D ", ip[i]);
677 printf("\n");
678/*
679 i = U.u_stack - &U;
680 while (U[++i] == 0);
681 i &= ~07;
682 while (i < 512) {
683 printf("%x ", 0140000+2*i);
684 for (j=0; j<8; j++)
685 printf("%9x", U[i++]);
686 printf("\n");
687 }
688*/
689}
690
691oatoi(s)
692char *s;
693{
694 register v;
695
696 v = 0;
697 while (*s)
698 v = (v<<3) + *s++ - '0';
699 return(v);
700}
701
69d3d166 702dofile()
ceb84881 703{
69d3d166
BJ
704 int nfile;
705 struct file *xfile, *afile;
ceb84881
BJ
706 register struct file *fp;
707 register nf;
708 int loc;
71c73ab0 709 static char *dtypes[] = { "???", "inode", "socket" };
ceb84881
BJ
710
711 nf = 0;
69d3d166
BJ
712 nfile = getw(nl[SNFILE].n_value);
713 xfile = (struct file *)calloc(nfile, sizeof (struct file));
76ea98af
KM
714 afile = (struct file *)getw(nl[SFIL].n_value);
715 lseek(fc, (mkphys((int)afile)), 0);
69d3d166
BJ
716 read(fc, xfile, nfile * sizeof (struct file));
717 for (fp=xfile; fp < &xfile[nfile]; fp++)
ceb84881
BJ
718 if (fp->f_count)
719 nf++;
720 if (totflg) {
69d3d166 721 printf("%3d/%3d files\n", nf, nfile);
ceb84881
BJ
722 return;
723 }
69d3d166 724 printf("%d/%d open files\n", nf, nfile);
192c0cf3 725 printf(" LOC TYPE FLG CNT MSG DATA OFFSET\n");
fd2ae9b6 726 for (fp=xfile,loc=(int)afile; fp < &xfile[nfile]; fp++,loc+=sizeof(xfile[0])) {
ceb84881
BJ
727 if (fp->f_count==0)
728 continue;
729 printf("%8x ", loc);
71c73ab0 730 if (fp->f_type <= DTYPE_SOCKET)
ae1f9014
SL
731 printf("%-8.8s", dtypes[fp->f_type]);
732 else
733 printf("8d", fp->f_type);
ceb84881
BJ
734 putf(fp->f_flag&FREAD, 'R');
735 putf(fp->f_flag&FWRITE, 'W');
ae1f9014 736 putf(fp->f_flag&FAPPEND, 'A');
192c0cf3
SL
737 putf(fp->f_flag&FSHLOCK, 'S');
738 putf(fp->f_flag&FEXLOCK, 'X');
739 putf(fp->f_flag&FASYNC, 'I');
71c73ab0
SL
740 printf(" %3d", mask(fp->f_count));
741 printf(" %3d", mask(fp->f_msgcount));
742 printf(" %8.1x", fp->f_data);
743 if (fp->f_offset < 0)
744 printf(" %x\n", fp->f_offset);
676bc34a
BJ
745 else
746 printf(" %ld\n", fp->f_offset);
ceb84881
BJ
747 }
748}
749
e79dc02e
SL
750int dmmin, dmmax, nswdev;
751
ceb84881
BJ
752doswap()
753{
69d3d166
BJ
754 struct proc *proc;
755 int nproc;
756 struct text *xtext;
757 int ntext;
758 struct map *swapmap;
759 int nswapmap;
b94a50ef 760 struct swdevt *swdevt, *sw;
ceb84881 761 register struct proc *pp;
e79dc02e
SL
762 int nswap, used, tused, free, waste;
763 int db, sb;
df3e00cc 764 register struct mapent *me;
ceb84881 765 register struct text *xp;
e79dc02e 766 int i, j;
ceb84881 767
69d3d166
BJ
768 nproc = getw(nl[SNPROC].n_value);
769 proc = (struct proc *)calloc(nproc, sizeof (struct proc));
b94a50ef
SL
770 ntext = getw(nl[SNTEXT].n_value);
771 xtext = (struct text *)calloc(ntext, sizeof (struct text));
69d3d166
BJ
772 nswapmap = getw(nl[SNSWAPMAP].n_value);
773 swapmap = (struct map *)calloc(nswapmap, sizeof (struct map));
b94a50ef
SL
774 nswdev = getw(nl[SNSWDEV].n_value);
775 swdevt = (struct swdevt *)calloc(nswdev, sizeof (struct swdevt));
776 lseek(fc, nl[SSWDEVT].n_value, L_SET);
777 read(fc, swdevt, nswdev * sizeof (struct swdevt));
778 lseek(fc, getw(nl[SPROC].n_value), 0);
779 read(fc, proc, nproc * sizeof (struct proc));
780 lseek(fc, getw(nl[STEXT].n_value), 0);
781 read(fc, xtext, ntext * sizeof (struct text));
69d3d166
BJ
782 lseek(fc, getw(nl[SWAPMAP].n_value), 0);
783 read(fc, swapmap, nswapmap * sizeof (struct map));
33b2e9da 784 swapmap->m_name = "swap";
e49b41bc 785 swapmap->m_limit = (struct mapent *)&swapmap[nswapmap];
e79dc02e
SL
786 dmmin = getw(nl[SDMMIN].n_value);
787 dmmax = getw(nl[SDMMAX].n_value);
b94a50ef
SL
788 nswap = 0;
789 for (sw = swdevt; sw < &swdevt[nswdev]; sw++)
790 nswap += sw->sw_nblks,
ceb84881 791 free = 0;
df3e00cc
BJ
792 for (me = (struct mapent *)(swapmap+1);
793 me < (struct mapent *)&swapmap[nswapmap]; me++)
794 free += me->m_size;
ceb84881 795 tused = 0;
69d3d166 796 for (xp = xtext; xp < &xtext[ntext]; xp++)
b94a50ef 797 if (xp->x_iptr!=NULL) {
79877ea5 798 tused += ctod(clrnd(xp->x_size));
b94a50ef 799 if (xp->x_flag & XPAGI)
79877ea5 800 tused += ctod(clrnd(ctopt(xp->x_size)));
b94a50ef 801 }
ceb84881 802 used = tused;
e79dc02e 803 waste = 0;
69d3d166 804 for (pp = proc; pp < &proc[nproc]; pp++) {
ceb84881
BJ
805 if (pp->p_stat == 0 || pp->p_stat == SZOMB)
806 continue;
807 if (pp->p_flag & SSYS)
808 continue;
b94a50ef
SL
809 db = ctod(pp->p_dsize), sb = up(db);
810 used += sb;
811 waste += sb - db;
812 db = ctod(pp->p_ssize), sb = up(db);
813 used += sb;
814 waste += sb - db;
ceb84881 815 if ((pp->p_flag&SLOAD) == 0)
13562341 816 used += ctod(vusize(pp));
ceb84881 817 }
ceb84881 818 if (totflg) {
b94a50ef
SL
819#define btok(x) ((x) / (1024 / DEV_BSIZE))
820 printf("%3d/%3d 00k swap\n",
821 btok(used/100), btok((used+free)/100));
ceb84881
BJ
822 return;
823 }
b94a50ef
SL
824 printf("%dk used (%dk text), %dk free, %dk wasted, %dk missing\n",
825 btok(used), btok(tused), btok(free), btok(waste),
826/* a dmmax/2 block goes to argmap */
827 btok(nswap - dmmax/2 - (used + free)));
e79dc02e
SL
828 printf("avail: ");
829 for (i = dmmax; i >= dmmin; i /= 2) {
830 j = 0;
831 while (rmalloc(swapmap, i) != 0)
832 j++;
b94a50ef 833 if (j) printf("%d*%dk ", j, btok(i));
e79dc02e 834 }
b94a50ef
SL
835 free = 0;
836 for (me = (struct mapent *)(swapmap+1);
837 me < (struct mapent *)&swapmap[nswapmap]; me++)
838 free += me->m_size;
839 printf("%d*1k\n", btok(free));
ceb84881
BJ
840}
841
842up(size)
843 register int size;
844{
845 register int i, block;
846
847 i = 0;
e79dc02e 848 block = dmmin;
ceb84881
BJ
849 while (i < size) {
850 i += block;
e79dc02e 851 if (block < dmmax)
ceb84881
BJ
852 block *= 2;
853 }
854 return (i);
855}
856
b94a50ef
SL
857/*
858 * Compute number of pages to be allocated to the u. area
859 * and data and stack area page tables, which are stored on the
860 * disk immediately after the u. area.
861 */
ceb84881 862vusize(p)
b94a50ef 863 register struct proc *p;
ceb84881
BJ
864{
865 register int tsz = p->p_tsize / NPTEPG;
866
b94a50ef
SL
867 /*
868 * We do not need page table space on the disk for page
869 * table pages wholly containing text.
870 */
871 return (clrnd(UPAGES +
872 clrnd(ctopt(p->p_tsize+p->p_dsize+p->p_ssize+UPAGES)) - tsz));
e79dc02e
SL
873}
874
875/*
876 * Allocate 'size' units from the given
877 * map. Return the base of the allocated space.
878 * In a map, the addresses are increasing and the
879 * list is terminated by a 0 size.
880 *
881 * Algorithm is first-fit.
882 *
883 * This routine knows about the interleaving of the swapmap
884 * and handles that.
885 */
886long
887rmalloc(mp, size)
888 register struct map *mp;
889 long size;
890{
891 register struct mapent *ep = (struct mapent *)(mp+1);
892 register int addr;
893 register struct mapent *bp;
894 swblk_t first, rest;
895
896 if (size <= 0 || size > dmmax)
897 return (0);
898 /*
899 * Search for a piece of the resource map which has enough
900 * free space to accomodate the request.
901 */
902 for (bp = ep; bp->m_size; bp++) {
903 if (bp->m_size >= size) {
904 /*
905 * If allocating from swapmap,
906 * then have to respect interleaving
907 * boundaries.
908 */
909 if (nswdev > 1 &&
910 (first = dmmax - bp->m_addr%dmmax) < bp->m_size) {
911 if (bp->m_size - first < size)
912 continue;
913 addr = bp->m_addr + first;
914 rest = bp->m_size - first - size;
915 bp->m_size = first;
916 if (rest)
917 rmfree(mp, rest, addr+size);
918 return (addr);
919 }
920 /*
921 * Allocate from the map.
922 * If there is no space left of the piece
923 * we allocated from, move the rest of
924 * the pieces to the left.
925 */
926 addr = bp->m_addr;
927 bp->m_addr += size;
928 if ((bp->m_size -= size) == 0) {
929 do {
930 bp++;
931 (bp-1)->m_addr = bp->m_addr;
932 } while ((bp-1)->m_size = bp->m_size);
933 }
934 if (addr % CLSIZE)
935 return (0);
936 return (addr);
937 }
938 }
939 return (0);
940}
941
942/*
943 * Free the previously allocated space at addr
944 * of size units into the specified map.
945 * Sort addr into map and combine on
946 * one or both ends if possible.
947 */
948rmfree(mp, size, addr)
949 struct map *mp;
950 long size, addr;
951{
952 struct mapent *firstbp;
953 register struct mapent *bp;
954 register int t;
955
956 /*
957 * Both address and size must be
958 * positive, or the protocol has broken down.
959 */
960 if (addr <= 0 || size <= 0)
961 goto badrmfree;
962 /*
963 * Locate the piece of the map which starts after the
964 * returned space (or the end of the map).
965 */
966 firstbp = bp = (struct mapent *)(mp + 1);
967 for (; bp->m_addr <= addr && bp->m_size != 0; bp++)
968 continue;
969 /*
970 * If the piece on the left abuts us,
971 * then we should combine with it.
972 */
973 if (bp > firstbp && (bp-1)->m_addr+(bp-1)->m_size >= addr) {
974 /*
975 * Check no overlap (internal error).
976 */
977 if ((bp-1)->m_addr+(bp-1)->m_size > addr)
978 goto badrmfree;
979 /*
980 * Add into piece on the left by increasing its size.
981 */
982 (bp-1)->m_size += size;
983 /*
984 * If the combined piece abuts the piece on
985 * the right now, compress it in also,
986 * by shifting the remaining pieces of the map over.
987 */
988 if (bp->m_addr && addr+size >= bp->m_addr) {
989 if (addr+size > bp->m_addr)
990 goto badrmfree;
991 (bp-1)->m_size += bp->m_size;
992 while (bp->m_size) {
993 bp++;
994 (bp-1)->m_addr = bp->m_addr;
995 (bp-1)->m_size = bp->m_size;
996 }
997 }
998 goto done;
999 }
1000 /*
1001 * Don't abut on the left, check for abutting on
1002 * the right.
1003 */
1004 if (addr+size >= bp->m_addr && bp->m_size) {
1005 if (addr+size > bp->m_addr)
1006 goto badrmfree;
1007 bp->m_addr -= size;
1008 bp->m_size += size;
1009 goto done;
1010 }
1011 /*
1012 * Don't abut at all. Make a new entry
1013 * and check for map overflow.
1014 */
1015 do {
1016 t = bp->m_addr;
1017 bp->m_addr = addr;
1018 addr = t;
1019 t = bp->m_size;
1020 bp->m_size = size;
1021 bp++;
1022 } while (size = t);
1023 /*
1024 * Segment at bp is to be the delimiter;
1025 * If there is not room for it
1026 * then the table is too full
1027 * and we must discard something.
1028 */
1029 if (bp+1 > mp->m_limit) {
1030 /*
1031 * Back bp up to last available segment.
1032 * which contains a segment already and must
1033 * be made into the delimiter.
1034 * Discard second to last entry,
1035 * since it is presumably smaller than the last
1036 * and move the last entry back one.
1037 */
1038 bp--;
1039 printf("%s: rmap ovflo, lost [%d,%d)\n", mp->m_name,
1040 (bp-1)->m_addr, (bp-1)->m_addr+(bp-1)->m_size);
1041 bp[-1] = bp[0];
1042 bp[0].m_size = bp[0].m_addr = 0;
1043 }
1044done:
1045 return;
1046badrmfree:
1047 printf("bad rmfree\n");
ceb84881 1048}
76ea98af
KM
1049/*
1050 * "addr" is a kern virt addr and does not correspond
1051 * To a phys addr after zipping out the high bit..
1052 * since it was valloc'd in the kernel.
1053 *
1054 * We return the phys addr by simulating kernel vm (/dev/kmem)
1055 * when we are reading a crash dump.
1056 */
1057mkphys(addr)
1058{
1059 register o;
1060
1061 if (!kflg)
1062 return(addr);
1063 o = addr & PGOFSET;
1064 addr >>= PGSHIFT;
1065 addr &= PG_PFNUM;
1066 addr *= NBPW;
1067 addr = getw(nl[SYSMAP].n_value + addr);
1068 addr = ((addr & PG_PFNUM) << PGSHIFT) | o;
1069 return(addr);
1070}