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 "sparc.h"
8
 
9
char	*file = "k.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
	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
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
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
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
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
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
252
reset(void)
253
{
254
	int i, l, m;
255
	Segment *s;
256
	Breakpoint *b;
257
 
258
	memset(&reg, 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
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
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
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
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
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
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 *
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 *
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
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
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
}