Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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