|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 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) 1983 Regents of the University of California.\n\ ! 10: All rights reserved.\n"; ! 11: #endif not lint ! 12: ! 13: #ifndef lint ! 14: static char sccsid[] = "@(#)kgmon.c 5.2 (Berkeley) 2/18/86"; ! 15: #endif not lint ! 16: ! 17: #include <sys/param.h> ! 18: #include <machine/pte.h> ! 19: #include <sys/file.h> ! 20: #include <sys/vm.h> ! 21: #include <stdio.h> ! 22: #include <nlist.h> ! 23: #include <ctype.h> ! 24: #include <sys/gprof.h> ! 25: ! 26: #define PROFILING_ON 0 ! 27: #define PROFILING_OFF 3 ! 28: ! 29: /* ! 30: * froms is actually a bunch of unsigned shorts indexing tos ! 31: */ ! 32: u_short *froms; ! 33: struct tostruct *tos; ! 34: char *s_lowpc; ! 35: u_long s_textsize; ! 36: int ssiz; ! 37: off_t sbuf; ! 38: ! 39: struct nlist nl[] = { ! 40: #define N_SYSMAP 0 ! 41: { "_Sysmap" }, ! 42: #define N_SYSSIZE 1 ! 43: { "_Syssize" }, ! 44: #define N_FROMS 2 ! 45: { "_froms" }, ! 46: #define N_PROFILING 3 ! 47: { "_profiling" }, ! 48: #define N_S_LOWPC 4 ! 49: { "_s_lowpc" }, ! 50: #define N_S_TEXTSIZE 5 ! 51: { "_s_textsize" }, ! 52: #define N_SBUF 6 ! 53: { "_sbuf" }, ! 54: #define N_SSIZ 7 ! 55: { "_ssiz" }, ! 56: #define N_TOS 8 ! 57: { "_tos" }, ! 58: 0, ! 59: }; ! 60: ! 61: #if defined(vax) ! 62: #define clear(x) ((x) &~ 0x80000000) ! 63: #endif ! 64: ! 65: struct pte *Sysmap; ! 66: ! 67: char *system = "/vmunix"; ! 68: char *kmemf = "/dev/kmem"; ! 69: int kmem; ! 70: int bflag, hflag, kflag, rflag, pflag; ! 71: int debug = 0; ! 72: ! 73: main(argc, argv) ! 74: int argc; ! 75: char *argv[]; ! 76: { ! 77: int mode, disp, openmode = O_RDONLY; ! 78: ! 79: argc--, argv++; ! 80: while (argc > 0 && argv[0][0] == '-') { ! 81: switch (argv[0][1]) { ! 82: case 'b': ! 83: bflag++; ! 84: openmode = O_RDWR; ! 85: break; ! 86: case 'h': ! 87: hflag++; ! 88: openmode = O_RDWR; ! 89: break; ! 90: case 'r': ! 91: rflag++; ! 92: openmode = O_RDWR; ! 93: break; ! 94: case 'p': ! 95: pflag++; ! 96: openmode = O_RDWR; ! 97: break; ! 98: default: ! 99: printf("Usage: kgmon [ -b -h -r -p system memory ]\n"); ! 100: exit(1); ! 101: } ! 102: argc--, argv++; ! 103: } ! 104: if (argc > 0) { ! 105: system = *argv; ! 106: argv++, argc--; ! 107: } ! 108: nlist(system, nl); ! 109: if (nl[0].n_type == 0) { ! 110: fprintf(stderr, "%s: no namelist\n", system); ! 111: exit(2); ! 112: } ! 113: if (argc > 0) { ! 114: kmemf = *argv; ! 115: kflag++; ! 116: } ! 117: kmem = open(kmemf, openmode); ! 118: if (kmem < 0) { ! 119: openmode = O_RDONLY; ! 120: kmem = open(kmemf, openmode); ! 121: if (kmem < 0) { ! 122: fprintf(stderr, "cannot open "); ! 123: perror(kmemf); ! 124: exit(3); ! 125: } ! 126: fprintf(stderr, "%s opened read-only\n", kmemf); ! 127: if (rflag) ! 128: fprintf(stderr, "-r supressed\n"); ! 129: if (bflag) ! 130: fprintf(stderr, "-b supressed\n"); ! 131: if (hflag) ! 132: fprintf(stderr, "-h supressed\n"); ! 133: rflag = 0; ! 134: bflag = 0; ! 135: hflag = 0; ! 136: } ! 137: if (kflag) { ! 138: off_t off; ! 139: ! 140: off = clear(nl[N_SYSMAP].n_value); ! 141: lseek(kmem, off, L_SET); ! 142: nl[N_SYSSIZE].n_value *= 4; ! 143: Sysmap = (struct pte *)malloc(nl[N_SYSSIZE].n_value); ! 144: if (Sysmap == 0) { ! 145: perror("Sysmap"); ! 146: exit(4); ! 147: } ! 148: read(kmem, Sysmap, nl[N_SYSSIZE].n_value); ! 149: } ! 150: mode = kfetch(N_PROFILING); ! 151: if (hflag) ! 152: disp = PROFILING_OFF; ! 153: else if (bflag) ! 154: disp = PROFILING_ON; ! 155: else ! 156: disp = mode; ! 157: if (pflag) { ! 158: if (openmode == O_RDONLY && mode == PROFILING_ON) ! 159: fprintf(stderr, "data may be inconsistent\n"); ! 160: dumpstate(); ! 161: } ! 162: if (rflag) ! 163: resetstate(); ! 164: turnonoff(disp); ! 165: fprintf(stdout, "kernel profiling is %s.\n", disp ? "off" : "running"); ! 166: } ! 167: ! 168: dumpstate() ! 169: { ! 170: int i; ! 171: int fd; ! 172: off_t kfroms, ktos; ! 173: int fromindex, endfrom, fromssize, tossize; ! 174: u_long frompc; ! 175: int toindex; ! 176: struct rawarc rawarc; ! 177: char buf[BUFSIZ]; ! 178: ! 179: turnonoff(PROFILING_OFF); ! 180: fd = creat("gmon.out", 0666); ! 181: if (fd < 0) { ! 182: perror("gmon.out"); ! 183: return; ! 184: } ! 185: ssiz = kfetch(N_SSIZ); ! 186: sbuf = kfetch(N_SBUF); ! 187: klseek(kmem, (off_t)sbuf, L_SET); ! 188: for (i = ssiz; i > 0; i -= BUFSIZ) { ! 189: read(kmem, buf, i < BUFSIZ ? i : BUFSIZ); ! 190: write(fd, buf, i < BUFSIZ ? i : BUFSIZ); ! 191: } ! 192: s_textsize = kfetch(N_S_TEXTSIZE); ! 193: fromssize = s_textsize / HASHFRACTION; ! 194: froms = (u_short *)malloc(fromssize); ! 195: kfroms = kfetch(N_FROMS); ! 196: klseek(kmem, kfroms, L_SET); ! 197: i = read(kmem, ((char *)(froms)), fromssize); ! 198: if (i != fromssize) { ! 199: fprintf(stderr, "read froms: request %d, got %d", fromssize, i); ! 200: perror(""); ! 201: exit(5); ! 202: } ! 203: tossize = (s_textsize * ARCDENSITY / 100) * sizeof(struct tostruct); ! 204: tos = (struct tostruct *)malloc(tossize); ! 205: ktos = kfetch(N_TOS); ! 206: klseek(kmem, ktos, L_SET); ! 207: i = read(kmem, ((char *)(tos)), tossize); ! 208: if (i != tossize) { ! 209: fprintf(stderr, "read tos: request %d, got %d", tossize, i); ! 210: perror(""); ! 211: exit(6); ! 212: } ! 213: s_lowpc = (char *)kfetch(N_S_LOWPC); ! 214: if (debug) ! 215: fprintf(stderr, "s_lowpc 0x%x, s_textsize 0x%x\n", ! 216: s_lowpc, s_textsize); ! 217: endfrom = fromssize / sizeof(*froms); ! 218: for (fromindex = 0; fromindex < endfrom; fromindex++) { ! 219: if (froms[fromindex] == 0) ! 220: continue; ! 221: frompc = (u_long)s_lowpc + ! 222: (fromindex * HASHFRACTION * sizeof(*froms)); ! 223: for (toindex = froms[fromindex]; toindex != 0; ! 224: toindex = tos[toindex].link) { ! 225: if (debug) ! 226: fprintf(stderr, ! 227: "[mcleanup] frompc 0x%x selfpc 0x%x count %d\n" , ! 228: frompc, tos[toindex].selfpc, tos[toindex].count); ! 229: rawarc.raw_frompc = frompc; ! 230: rawarc.raw_selfpc = (u_long)tos[toindex].selfpc; ! 231: rawarc.raw_count = tos[toindex].count; ! 232: write(fd, &rawarc, sizeof (rawarc)); ! 233: } ! 234: } ! 235: close(fd); ! 236: } ! 237: ! 238: resetstate() ! 239: { ! 240: int i; ! 241: off_t kfroms, ktos; ! 242: int fromssize, tossize; ! 243: char buf[BUFSIZ]; ! 244: ! 245: turnonoff(PROFILING_OFF); ! 246: bzero(buf, BUFSIZ); ! 247: ssiz = kfetch(N_SSIZ); ! 248: sbuf = kfetch(N_SBUF); ! 249: ssiz -= sizeof(struct phdr); ! 250: sbuf += sizeof(struct phdr); ! 251: klseek(kmem, (off_t)sbuf, L_SET); ! 252: for (i = ssiz; i > 0; i -= BUFSIZ) ! 253: if (write(kmem, buf, i < BUFSIZ ? i : BUFSIZ) < 0) { ! 254: perror("sbuf write"); ! 255: exit(7); ! 256: } ! 257: s_textsize = kfetch(N_S_TEXTSIZE); ! 258: fromssize = s_textsize / HASHFRACTION; ! 259: kfroms = kfetch(N_FROMS); ! 260: klseek(kmem, kfroms, L_SET); ! 261: for (i = fromssize; i > 0; i -= BUFSIZ) ! 262: if (write(kmem, buf, i < BUFSIZ ? i : BUFSIZ) < 0) { ! 263: perror("kforms write"); ! 264: exit(8); ! 265: } ! 266: tossize = (s_textsize * ARCDENSITY / 100) * sizeof(struct tostruct); ! 267: ktos = kfetch(N_TOS); ! 268: klseek(kmem, ktos, L_SET); ! 269: for (i = tossize; i > 0; i -= BUFSIZ) ! 270: if (write(kmem, buf, i < BUFSIZ ? i : BUFSIZ) < 0) { ! 271: perror("ktos write"); ! 272: exit(9); ! 273: } ! 274: } ! 275: ! 276: turnonoff(onoff) ! 277: int onoff; ! 278: { ! 279: off_t off; ! 280: ! 281: if ((off = nl[N_PROFILING].n_value) == 0) { ! 282: printf("profiling: not defined in kernel\n"); ! 283: exit(10); ! 284: } ! 285: klseek(kmem, off, L_SET); ! 286: write(kmem, (char *)&onoff, sizeof (onoff)); ! 287: } ! 288: ! 289: kfetch(index) ! 290: int index; ! 291: { ! 292: off_t off; ! 293: int value; ! 294: ! 295: if ((off = nl[index].n_value) == 0) { ! 296: printf("%s: not defined in kernel\n", nl[index].n_name); ! 297: exit(11); ! 298: } ! 299: if (klseek(kmem, off, L_SET) == -1) { ! 300: perror("lseek"); ! 301: exit(12); ! 302: } ! 303: if (read(kmem, (char *)&value, sizeof (value)) != sizeof (value)) { ! 304: perror("read"); ! 305: exit(13); ! 306: } ! 307: return (value); ! 308: } ! 309: ! 310: klseek(fd, base, off) ! 311: int fd, base, off; ! 312: { ! 313: ! 314: if (kflag) { ! 315: /* get kernel pte */ ! 316: base = clear(base); ! 317: base = ((int)ptob(Sysmap[btop(base)].pg_pfnum))+(base&(NBPG-1)); ! 318: } ! 319: return (lseek(fd, base, off)); ! 320: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.