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: }

Defined functions

dumpstate defined in line 168; used 1 times
kfetch defined in line 289; used 12 times
klseek defined in line 310; used 8 times
main defined in line 73; never used
resetstate defined in line 238; used 1 times
turnonoff defined in line 276; used 3 times

Defined variables

Sysmap defined in line 65; used 4 times
bflag defined in line 70; used 4 times
copyright defined in line 8; never used
debug defined in line 71; used 2 times
hflag defined in line 70; used 4 times
kflag defined in line 70; used 3 times
kmem defined in line 69; used 22 times
kmemf defined in line 68; used 5 times
nl defined in line 39; used 9 times
pflag defined in line 70; used 2 times
rflag defined in line 70; used 4 times
s_lowpc defined in line 34; used 3 times
sccsid defined in line 14; never used
ssiz defined in line 36; used 5 times
system defined in line 67; used 3 times
tos defined in line 33; used 7 times

Defined macros

N_FROMS defined in line 44; used 2 times
N_PROFILING defined in line 46; used 2 times
N_SBUF defined in line 52; used 2 times
N_SSIZ defined in line 54; used 2 times
N_SYSMAP defined in line 40; used 1 times
N_SYSSIZE defined in line 42; used 3 times
N_S_LOWPC defined in line 48; used 1 times
N_S_TEXTSIZE defined in line 50; used 2 times
N_TOS defined in line 56; used 2 times
PROFILING_OFF defined in line 27; used 3 times
PROFILING_ON defined in line 26; used 2 times
clear defined in line 62; used 2 times
Last modified: 1986-02-19
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1861
Valid CSS Valid XHTML 1.0 Strict