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

Defined functions

dofile defined in line 699; used 1 times
doinode defined in line 240; used 1 times
doproc defined in line 383; used 1 times
doswap defined in line 759; used 1 times
dotext defined in line 323; used 1 times
dotty defined in line 456; used 1 times
dottytype defined in line 485; used 6 times
dousr defined in line 572; used 1 times
getw defined in line 302; used 19 times
main defined in line 130; never used
mkphys defined in line 1086; used 9 times
oatoi defined in line 688; never used
putf defined in line 315; used 32 times
rmalloc defined in line 915; used 1 times
rmfree defined in line 977; used 1 times
ttyprt defined in line 515; used 2 times
up defined in line 871; used 2 times
usage defined in line 234; used 1 times
vusize defined in line 891; used 1 times

Defined variables

Usrptma defined in line 125; used 1 times
allflg defined in line 123; used 2 times
bdevsw defined in line 122; never used
cdevsw defined in line 121; never used
copyright defined in line 8; never used
dmmax defined in line 757; used 7 times
dmmin defined in line 757; used 3 times
fc defined in line 45; used 27 times
fcore defined in line 42; used 4 times
filf defined in line 117; used 3 times
fm defined in line 45; used 3 times
fmem defined in line 43; used 4 times
fnlist defined in line 44; used 2 times
inof defined in line 111; used 3 times
kflg defined in line 124; used 7 times
mesg defined in line 451; used 2 times
nl defined in line 47; used 38 times
nswdev defined in line 757; used 5 times
partab defined in line 120; never used
prcf defined in line 113; used 3 times
sccsid defined in line 14; never used
swpf defined in line 118; used 3 times
totflg defined in line 119; used 12 times
tty defined in line 454; used 13 times
ttyf defined in line 114; used 3 times
ttyspace defined in line 453; used 4 times
txtf defined in line 112; used 3 times
ubase defined in line 116; used 2 times
usrf defined in line 115; used 3 times
usrpt defined in line 126; used 1 times

Defined macros

KERNEL defined in line 26; used 1 times
  • in line 28
SDH defined in line 68; used 1 times
SDHU defined in line 98; used 1 times
SDMF defined in line 92; used 1 times
SDMMAX defined in line 86; used 1 times
SDMMIN defined in line 84; used 1 times
SDMZ defined in line 104; used 1 times
SDZ defined in line 54; used 1 times
SFIL defined in line 60; used 1 times
SINODE defined in line 48; used 1 times
SKL defined in line 58; used 3 times
SNDH defined in line 70; used 2 times
SNDHU defined in line 100; used 2 times
SNDMF defined in line 94; used 2 times
SNDMZ defined in line 106; used 2 times
SNDZ defined in line 56; used 2 times
SNFILE defined in line 76; used 1 times
SNINODE defined in line 78; used 1 times
SNPROC defined in line 72; used 2 times
SNPTY defined in line 96; used 2 times
SNSWAPMAP defined in line 80; used 1 times
SNSWDEV defined in line 88; used 1 times
SNTEXT defined in line 74; used 2 times
SPROC defined in line 52; used 2 times
SPTY defined in line 82; used 1 times
SSWDEVT defined in line 90; used 1 times
STEXT defined in line 50; used 2 times
SWAPMAP defined in line 66; used 1 times
SYSMAP defined in line 102; used 1 times
USRPT defined in line 64; used 1 times
USRPTMA defined in line 62; used 1 times
btok defined in line 848; used 9 times
clear defined in line 22; used 7 times
mask defined in line 21; used 2 times
Last modified: 1986-05-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3450
Valid CSS Valid XHTML 1.0 Strict