|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.