]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/ki/ki.c
kernel: keep segment locked for data2txt
[plan9front.git] / sys / src / cmd / ki / ki.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <mach.h>
5 #define Extern
6 #include "sparc.h"
7
8 char    *file = "k.out";
9 int     datasize;
10 ulong   textbase;
11 Biobuf  bp, bi;
12 Fhdr    fhdr;
13
14 void
15 main(int argc, char **argv)
16 {
17         int pid;
18
19         argc--;
20         argv++;
21
22         bioout = &bp;
23         bin = &bi;
24         Binit(bioout, 1, OWRITE);
25         Binit(bin, 0, OREAD);
26
27         if(argc) {
28                 pid = atoi(argv[0]);
29                 if(pid != 0) {
30                         procinit(pid);
31                         cmd();
32                 }
33                 file = argv[0];
34         }
35         argc--;
36         argv++;
37
38         text = open(file, OREAD);
39         if(text < 0)
40                 fatal(1, "open text '%s'", file);
41
42         Bprint(bioout, "ki\n");
43         inithdr(text);
44         initstk(argc, argv);
45
46         reg.fd[13] = 0.5;       /* Normally initialised by the kernel */
47         reg.fd[12] = 0.0;
48         reg.fd[14] = 1.0;
49         reg.fd[15] = 2.0;
50         cmd();
51 }
52
53 void
54 initmap(void)
55 {
56
57         ulong t, d, b, bssend;
58         Segment *s;
59
60         t = (fhdr.txtaddr+fhdr.txtsz+(BY2PG-1)) & ~(BY2PG-1);
61         d = (t + fhdr.datsz + (BY2PG-1)) & ~(BY2PG-1);
62         bssend = t + fhdr.datsz + fhdr.bsssz;
63         b = (bssend + (BY2PG-1)) & ~(BY2PG-1);
64
65         s = &memory.seg[Text];
66         s->type = Text;
67         s->base = fhdr.txtaddr - fhdr.hdrsz;
68         s->end = t;
69         s->fileoff = fhdr.txtoff - fhdr.hdrsz;
70         s->fileend = s->fileoff + fhdr.txtsz;
71         s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
72
73         iprof = emalloc(((s->end-s->base)/PROFGRAN)*sizeof(long));
74         textbase = s->base;
75
76         s = &memory.seg[Data];
77         s->type = Data;
78         s->base = t;
79         s->end = t+(d-t);
80         s->fileoff = fhdr.datoff;
81         s->fileend = s->fileoff + fhdr.datsz;
82         datasize = fhdr.datsz;
83         s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
84
85         s = &memory.seg[Bss];
86         s->type = Bss;
87         s->base = d;
88         s->end = d+(b-d);
89         s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
90
91         s = &memory.seg[Stack];
92         s->type = Stack;
93         s->base = STACKTOP-STACKSIZE;
94         s->end = STACKTOP;
95         s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
96
97         reg.pc = fhdr.entry;
98 }
99
100 void
101 inithdr(int fd)
102 {
103         Symbol s;
104
105         extern Machdata sparcmach;
106
107         seek(fd, 0, 0);
108         if (!crackhdr(fd, &fhdr))
109                 fatal(0, "read text header");
110
111         if(fhdr.type != FSPARC)
112                 fatal(0, "bad magic number");
113
114         if(syminit(fd, &fhdr) < 0)
115                 fatal(0, "%r\n");
116         symmap = loadmap(symmap, fd, &fhdr);
117         if (mach->sbreg && lookup(0, mach->sbreg, &s))
118                 mach->sb = s.value;
119         machdata = &sparcmach;
120         asstype = ASUNSPARC;
121 }
122
123 ulong
124 greg(int f, ulong off)
125 {
126         int n;
127         ulong l;
128         uchar wd[BY2WD];
129         
130         seek(f, off, 0);
131         n = read(f, wd, BY2WD);
132         if(n != BY2WD)
133                 fatal(1, "read register");
134
135         l  = wd[0]<<24;
136         l |= wd[1]<<16;
137         l |= wd[2]<<8;
138         l |= wd[3];
139         return l;
140 }
141
142 ulong
143 roff[] = {
144         REGOFF(r1),     REGOFF(r2),     REGOFF(r3),
145         REGOFF(r4),     REGOFF(r5),     REGOFF(r6),
146         REGOFF(r7),     REGOFF(r8),     REGOFF(r9),
147         REGOFF(r10),    REGOFF(r11),    REGOFF(r12),
148         REGOFF(r13),    REGOFF(r14),    REGOFF(r15),
149         REGOFF(r16),    REGOFF(r17),    REGOFF(r18),
150         REGOFF(r19),    REGOFF(r20),    REGOFF(r21),
151         REGOFF(r22),    REGOFF(r23),    REGOFF(r24),
152         REGOFF(r25),    REGOFF(r26),    REGOFF(r27),
153         REGOFF(r28)
154 };
155
156 void
157 seginit(int fd, Segment *s, int idx, ulong vastart, ulong vaend)
158 {
159         int n;
160
161         while(vastart < vaend) {
162                 seek(fd, vastart, 0);
163                 s->table[idx] = emalloc(BY2PG);
164                 n = read(fd, s->table[idx], BY2PG);
165                 if(n != BY2PG)
166                         fatal(1, "data read");
167                 vastart += BY2PG;
168                 idx++;
169         }
170 }
171
172 void
173 procinit(int pid)
174 {
175         char *p;
176         Segment *s;
177         int n, m, sg, i;
178         ulong vastart, vaend;
179         char mfile[128], tfile[128], sfile[1024];
180
181         sprint(mfile, "/proc/%d/mem", pid);
182         sprint(tfile, "/proc/%d/text", pid);
183         sprint(sfile, "/proc/%d/segment", pid);
184
185         text = open(tfile, OREAD);
186         if(text < 0)
187                 fatal(1, "open text %s", tfile);
188         inithdr(text);
189
190         sg = open(sfile, OREAD);
191         if(sg < 0)
192                 fatal(1, "open text %s", sfile);
193
194         n = read(sg, sfile, sizeof(sfile));
195         if(n >= sizeof(sfile))
196                 fatal(0, "segment file buffer too small");
197         close(sg);
198
199         m = open(mfile, OREAD);
200         if(m < 0)
201                 fatal(1, "open %s", mfile);
202
203         initmap();
204
205         p = strstr(sfile, "Data");
206         if(p == 0)
207                 fatal(0, "no data");
208
209         vastart = strtoul(p+9, 0, 16);
210         vaend = strtoul(p+18, 0, 16);
211         s = &memory.seg[Data];
212         if(s->base != vastart || s->end != vaend) {
213                 s->base = vastart;
214                 s->end = vaend;
215                 free(s->table);
216                 s->table = malloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
217         }
218         seginit(m, s, 0, vastart, vaend);
219         
220         p = strstr(sfile, "Bss");
221         if(p == 0)
222                 fatal(0, "no bss");
223
224         vastart = strtoul(p+9, 0, 16);
225         vaend = strtoul(p+18, 0, 16);
226         s = &memory.seg[Bss];
227         if(s->base != vastart || s->end != vaend) {
228                 s->base = vastart;
229                 s->end = vaend;
230                 free(s->table);
231                 s->table = malloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
232         }
233         seginit(m, s, 0, vastart, vaend);
234
235         reg.pc = greg(m, REGOFF(pc));
236         reg.r[1] = greg(m, REGOFF(sp));
237         reg.r[30] = greg(m, REGOFF(r30));
238         reg.r[31] = greg(m, REGOFF(r31));
239
240         for(i = 1; i < 29; i++)
241                 reg.r[i] = greg(m, roff[i-1]);
242
243         s = &memory.seg[Stack];
244         vastart = reg.r[1] & ~(BY2PG-1);
245         seginit(m, s, (vastart-s->base)/BY2PG, vastart, STACKTOP);
246         close(m);
247         Bprint(bioout, "ki\n"); 
248 }
249
250 void
251 reset(void)
252 {
253         int i, l, m;
254         Segment *s;
255         Breakpoint *b;
256
257         memset(&reg, 0, sizeof(Registers));
258         reg.fd[13] = 0.5;       /* Normally initialised by the kernel */
259         reg.fd[12] = 0.0;
260         reg.fd[14] = 1.0;
261         reg.fd[15] = 2.0;
262         for(i = 0; i > Nseg; i++) {
263                 s = &memory.seg[i];
264                 l = ((s->end-s->base)/BY2PG)*sizeof(uchar*);
265                 for(m = 0; m < l; m++)
266                         if(s->table[m])
267                                 free(s->table[m]);
268                 free(s->table);
269         }
270         free(iprof);
271         memset(&memory, 0, sizeof(memory));
272
273         for(b = bplist; b; b = b->next)
274                 b->done = b->count;
275 }
276
277 void
278 initstk(int argc, char *argv[])
279 {
280         ulong size, sp, ap;
281         int i;
282         char *p;
283
284         initmap();
285         sp = STACKTOP - 4;
286
287         /* Build exec stack */
288         size = strlen(file)+1+BY2WD+BY2WD+(BY2WD*2);    
289         for(i = 0; i < argc; i++)
290                 size += strlen(argv[i])+BY2WD+1;
291
292         sp -= size;
293         sp &= ~7;
294         reg.r[1] = sp;
295         reg.r[7] = STACKTOP-4;  /* Plan 9 profiling clock */
296
297         /* Push argc */
298         putmem_w(sp, argc+1);
299         sp += BY2WD;
300
301         /* Compute sizeof(argv) and push argv[0] */
302         ap = sp+((argc+1)*BY2WD)+BY2WD;
303         putmem_w(sp, ap);
304         sp += BY2WD;
305         
306         /* Build argv[0] string into stack */
307         for(p = file; *p; p++)
308                 putmem_b(ap++, *p);
309
310         putmem_b(ap++, '\0');
311
312         /* Loop through pushing the arguments */
313         for(i = 0; i < argc; i++) {
314                 putmem_w(sp, ap);
315                 sp += BY2WD;
316                 for(p = argv[i]; *p; p++)
317                         putmem_b(ap++, *p);
318                 putmem_b(ap++, '\0');
319         }
320         /* Null terminate argv */
321         putmem_w(sp, 0);
322
323 }
324
325 void
326 fatal(int syserr, char *fmt, ...)
327 {
328         char buf[ERRMAX], *s;
329         va_list arg;
330
331         va_start(arg, fmt);
332         vseprint(buf, buf+sizeof(buf), fmt, arg);
333         va_end(arg);
334         s = "ki: %s\n";
335         if(syserr)
336                 s = "ki: %s: %r\n";
337         fprint(2, s, buf);
338         exits(buf);
339 }
340
341 void
342 itrace(char *fmt, ...)
343 {
344         char buf[128];
345         va_list arg;
346
347         va_start(arg, fmt);
348         vseprint(buf, buf+sizeof(buf), fmt, arg);
349         va_end(arg);
350         Bprint(bioout, "%8lux %.8lux %s\n", reg.pc, reg.ir, buf);       
351 }
352
353 void
354 dumpreg(void)
355 {
356         int i;
357
358         Bprint(bioout, "PC  #%-8lux SP  #%-8lux Y   #%-8lux PSR #%-8lux\n",
359                                 reg.pc, reg.r[1], reg.Y, reg.psr);
360
361         for(i = 0; i < 32; i++) {
362                 if((i%4) == 0 && i != 0)
363                         Bprint(bioout, "\n");
364                 Bprint(bioout, "R%-2d #%-8lux ", i, reg.r[i]);
365         }
366         Bprint(bioout, "\n");
367 }
368
369 void
370 dumpfreg(void)
371 {
372         int i;
373         char buf[64];
374
375         i = 0;
376         while(i < 32) {
377                 ieeesftos(buf, sizeof(buf), reg.di[i]);
378                 Bprint(bioout, "F%-2d %s\t", i, buf);
379                 i++;
380                 ieeesftos(buf, sizeof(buf), reg.di[i]);
381                 Bprint(bioout, "\tF%-2d %s\n", i, buf);
382                 i++;
383         }
384 }
385
386 void
387 dumpdreg(void)
388 {
389         int i;
390         char buf[64];
391
392         i = 0;
393         while(i < 32) {
394                 ieeedftos(buf, sizeof(buf), reg.di[i] ,reg.di[i+1]);
395                 Bprint(bioout, "F%-2d %s\t", i, buf);
396                 i += 2;
397                 ieeedftos(buf, sizeof(buf), reg.di[i] ,reg.di[i+1]);
398                 Bprint(bioout, "\tF%-2d %s\n", i, buf);
399                 i += 2;
400         }
401 }
402
403 void *
404 emalloc(ulong size)
405 {
406         void *a;
407
408         a = malloc(size);
409         if(a == 0)
410                 fatal(0, "no memory");
411
412         memset(a, 0, size);
413         return a;
414 }
415
416 void *
417 erealloc(void *a, ulong oldsize, ulong size)
418 {
419         void *n;
420
421         n = malloc(size);
422         if(n == 0)
423                 fatal(0, "no memory");
424         memset(n, 0, size);
425         if(size > oldsize)
426                 size = oldsize;
427         memmove(n, a, size);
428         return n;
429 }
430
431 Mulu
432 mulu(ulong u1, ulong u2)
433 {
434         ulong lo1, lo2, hi1, hi2, lo, hi, t1, t2, t;
435
436         lo1 = u1 & 0xffff;
437         lo2 = u2 & 0xffff;
438         hi1 = u1 >> 16;
439         hi2 = u2 >> 16;
440
441         lo = lo1 * lo2;
442         t1 = lo1 * hi2;
443         t2 = lo2 * hi1;
444         hi = hi1 * hi2;
445         t = lo;
446         lo += t1 << 16;
447         if(lo < t)
448                 hi++;
449         t = lo;
450         lo += t2 << 16;
451         if(lo < t)
452                 hi++;
453         hi += (t1 >> 16) + (t2 >> 16);
454         return (Mulu){lo, hi};
455 }
456
457 Mul
458 mul(long l1, long l2)
459 {
460         Mulu m;
461         ulong t, lo, hi;
462         int sign;
463
464         sign = 0;
465         if(l1 < 0){
466                 sign ^= 1;
467                 l1 = -l1;
468         }
469         if(l2 < 0){
470                 sign ^= 1;
471                 l2 = -l2;
472         }
473         m = mulu(l1, l2);
474         lo = m.lo;
475         hi = m.hi;
476         if(sign){
477                 t = lo = ~lo;
478                 hi = ~hi;
479                 lo++;
480                 if(lo < t)
481                         hi++;
482         }
483         return (Mul){lo, hi};
484 }