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