Subversion Repositories planix.SVN

Rev

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