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