1 /* Copyright (c) 1982 Regents of the University of California */ 2 3 #ifndef lint 4 static char sccsid[] = "@(#)kgmon.c 4.1 82/06/21"; 5 #endif 6 7 #include <sys/param.h> 8 #include <sys/pte.h> 9 #include <stdio.h> 10 #include <nlist.h> 11 #include <ctype.h> 12 #include <sys/crt0.h> 13 14 #define PROFILING_ON 0 15 #define PROFILING_OFF 3 16 17 /* 18 * froms is actually a bunch of unsigned shorts indexing tos 19 */ 20 u_short *froms; 21 struct tostruct *tos; 22 char *s_lowpc; 23 u_long s_textsize; 24 int ssiz; 25 off_t sbuf; 26 27 struct nlist nl[] = { 28 #define N_SYSMAP 0 29 { "_Sysmap" }, 30 #define N_SYSSIZE 1 31 { "_Syssize" }, 32 #define N_FROMS 2 33 { "_froms" }, 34 #define N_PROFILING 3 35 { "_profiling" }, 36 #define N_S_LOWPC 4 37 { "_s_lowpc" }, 38 #define N_S_TEXTSIZE 5 39 { "_s_textsize" }, 40 #define N_SBUF 6 41 { "_sbuf" }, 42 #define N_SSIZ 7 43 { "_ssiz" }, 44 #define N_TOS 8 45 { "_tos" }, 46 0, 47 }; 48 49 struct pte *Sysmap; 50 51 char *system = "/vmunix"; 52 char *kmemf = "/dev/kmem"; 53 int kmem; 54 int kflg; 55 56 main(argc, argv) 57 int argc; 58 char *argv[]; 59 { 60 int i, j, k; 61 char *cp; 62 long conptr; 63 int fd; 64 int fromindex; 65 u_long frompc; 66 int toindex; 67 struct rawarc rawarc; 68 off_t kfroms, ktos; 69 char buf[BUFSIZ]; 70 int debug = 0; 71 72 argc--, argv++; 73 if (argc > 0) { 74 system = *argv; 75 argv++, argc--; 76 } 77 nlist(system, nl); 78 if (nl[0].n_type == 0) { 79 fprintf(stderr, "%s: no namelist\n", system); 80 exit(1); 81 } 82 if (argc > 0) { 83 kmemf = *argv; 84 kflg++; 85 } 86 kmem = open(kmemf, 2); 87 if (kmem < 0) { 88 kmem = open(kmemf, 0); 89 if (kmem < 0) { 90 fprintf(stderr, "cannot open "); 91 perror(kmemf); 92 exit(1); 93 } 94 fprintf(stderr, 95 "%s opened read-only, data may be inconsistent\n", 96 kmemf); 97 } 98 if (kflg) { 99 off_t off; 100 101 off = nl[N_SYSMAP].n_value & 0x7fffffff; 102 lseek(kmem, off, 0); 103 nl[N_SYSSIZE].n_value *= 4; 104 Sysmap = (struct pte *)malloc(nl[N_SYSSIZE].n_value); 105 if (Sysmap == 0) { 106 perror("Sysmap"); 107 exit(1); 108 } 109 read(kmem, Sysmap, nl[N_SYSSIZE].n_value); 110 } 111 turnonoff(PROFILING_OFF); 112 fd = creat("gmon.out", 0666); 113 if (fd < 0) { 114 perror("gmon.out"); 115 return; 116 } 117 ssiz = kfetch(N_SSIZ); 118 sbuf = kfetch(N_SBUF); 119 klseek(kmem, (off_t)sbuf, 0); 120 for (i = ssiz; i > 0; i -= BUFSIZ) { 121 read(kmem, buf, i < BUFSIZ ? i : BUFSIZ); 122 write(fd, buf, i < BUFSIZ ? i : BUFSIZ); 123 } 124 s_textsize = kfetch(N_S_TEXTSIZE); 125 froms = (u_short *)malloc(s_textsize); 126 kfroms = kfetch(N_FROMS); 127 klseek(kmem, kfroms, 0); 128 for (i = 0; i < s_textsize; i += BUFSIZ) { 129 j = s_textsize - i; 130 if (j > BUFSIZ) 131 j = BUFSIZ; 132 k = read(kmem, ((char *)(froms)) + i, j); 133 if (j != k) { 134 fprintf(stderr, "read tos: loc %d, request %d, got %d", 135 i, j, k); 136 perror(""); 137 exit(5); 138 } 139 } 140 tos = (struct tostruct *)malloc(s_textsize); 141 ktos = kfetch(N_TOS); 142 klseek(kmem, ktos, 0); 143 for (i = 0; i < s_textsize; i += BUFSIZ) { 144 j = s_textsize - i; 145 if (j > BUFSIZ) 146 j = BUFSIZ; 147 k = read(kmem, ((char *)(tos)) + i, j); 148 if (j != k) { 149 fprintf(stderr, "read tos: loc %d, request %d, got %d", 150 i, j, k); 151 perror(""); 152 exit(6); 153 } 154 } 155 s_lowpc = (char *)kfetch(N_S_LOWPC); 156 if (debug) 157 fprintf(stderr, "s_lowpc 0x%x, s_textsize 0x%x\n", 158 s_lowpc, s_textsize); 159 for (fromindex = 0; fromindex < s_textsize>>1; fromindex++) { 160 if (froms[fromindex] == 0) 161 continue; 162 frompc = (u_long)s_lowpc + (fromindex<<1); 163 for (toindex = froms[fromindex]; toindex != 0; 164 toindex = tos[toindex].link) { 165 if (debug) 166 fprintf(stderr, 167 "[mcleanup] frompc 0x%x selfpc 0x%x count %d\n" , 168 frompc, tos[toindex].selfpc, tos[toindex].count); 169 rawarc.raw_frompc = frompc; 170 rawarc.raw_selfpc = (u_long)tos[toindex].selfpc; 171 rawarc.raw_count = tos[toindex].count; 172 write(fd, &rawarc, sizeof (rawarc)); 173 } 174 } 175 close(fd); 176 turnonoff(PROFILING_ON); 177 } 178 179 turnonoff(onoff) 180 int onoff; 181 { 182 off_t off; 183 184 if ((off = nl[N_PROFILING].n_value) == 0) { 185 printf("profiling: not defined in kernel\n"); 186 exit(1); 187 } 188 klseek(kmem, off, 0); 189 write(kmem, (char *)&onoff, sizeof (onoff)); 190 } 191 192 kfetch(index) 193 int index; 194 { 195 off_t off; 196 int value; 197 198 if ((off = nl[index].n_value) == 0) { 199 printf("%s: not defined in kernel\n", nl[index].n_name); 200 exit(1); 201 } 202 if (klseek(kmem, off, 0) == -1) { 203 perror("lseek"); 204 exit(2); 205 } 206 if (read(kmem, (char *)&value, sizeof (value)) != sizeof (value)) { 207 perror("read"); 208 exit(3); 209 } 210 return (value); 211 } 212 213 klseek(fd, base, off) 214 int fd, base, off; 215 { 216 217 if (kflg) { 218 /* get kernel pte */ 219 base &= 0x7fffffff; 220 base = Sysmap[base >> 9].pg_pfnum * 512 + (base & 0x1ff); 221 } 222 return (lseek(fd, base, off)); 223 } 224