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