xref: /plan9/sys/src/cmd/qi/qi.c (revision ff579efb6d9c16f03df7f0fbdbd7810dcb61813e)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <mach.h>
5 #define Extern
6 #include "power.h"
7 
8 char	*file = "q.out";
9 int	datasize;
10 ulong	textbase;
11 Biobuf	bp, bi;
12 Fhdr	fhdr;
13 ulong	bits[32];
14 
15 void
16 main(int argc, char **argv)
17 {
18 	int pid, i;
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, "qi\n");
44 	inithdr(text);
45 	initstk(argc, argv);
46 
47 	for(i=0; i<32; i++)
48 		bits[i] = 1L << (31-i);
49 
50 	fpreginit();
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 	iprofsize = (s->end-s->base)/PROFGRAN;
75 	iprof = emalloc(iprofsize*sizeof(long));
76 	textbase = s->base;
77 
78 	s = &memory.seg[Data];
79 	s->type = Data;
80 	s->base = t;
81 	s->end = t+(d-t);
82 	s->fileoff = fhdr.datoff;
83 	s->fileend = s->fileoff + fhdr.datsz;
84 	datasize = fhdr.datsz;
85 	s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
86 
87 	s = &memory.seg[Bss];
88 	s->type = Bss;
89 	s->base = d;
90 	s->end = d+(b-d);
91 	s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
92 
93 	s = &memory.seg[Stack];
94 	s->type = Stack;
95 	s->base = STACKTOP-STACKSIZE;
96 	s->end = STACKTOP;
97 	s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
98 
99 	reg.pc = fhdr.entry;
100 }
101 
102 void
103 inithdr(int fd)
104 {
105 	Symbol s;
106 
107 	extern Machdata powermach;
108 
109 	seek(fd, 0, 0);
110 	if (!crackhdr(fd, &fhdr))
111 		fatal(0, "read text header");
112 
113 	if(fhdr.type != FPOWER)
114 		fatal(0, "bad magic number");
115 
116 	if(syminit(fd, &fhdr) < 0)
117 		fatal(0, "%r\n");
118 	symmap = loadmap(symmap, fd, &fhdr);
119 	if (mach->sbreg && lookup(0, mach->sbreg, &s))
120 		mach->sb = s.value;
121 	machdata = &powermach;
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(r0),
146 	REGOFF(r1),	REGOFF(r2),	REGOFF(r3),
147 	REGOFF(r4),	REGOFF(r5),	REGOFF(r6),
148 	REGOFF(r7),	REGOFF(r8),	REGOFF(r9),
149 	REGOFF(r10),	REGOFF(r11),	REGOFF(r12),
150 	REGOFF(r13),	REGOFF(r14),	REGOFF(r15),
151 	REGOFF(r16),	REGOFF(r17),	REGOFF(r18),
152 	REGOFF(r19),	REGOFF(r20),	REGOFF(r21),
153 	REGOFF(r22),	REGOFF(r23),	REGOFF(r24),
154 	REGOFF(r25),	REGOFF(r26),	REGOFF(r27),
155 	REGOFF(r28),	REGOFF(r29),	REGOFF(r30),
156 	REGOFF(r31),
157 };
158 
159 void
160 seginit(int fd, Segment *s, int idx, ulong vastart, ulong vaend)
161 {
162 	int n;
163 
164 	while(vastart < vaend) {
165 		seek(fd, vastart, 0);
166 		s->table[idx] = emalloc(BY2PG);
167 		n = read(fd, s->table[idx], BY2PG);
168 		if(n != BY2PG)
169 			fatal(1, "data read");
170 		vastart += BY2PG;
171 		idx++;
172 	}
173 }
174 
175 void
176 procinit(int pid)
177 {
178 	char *p;
179 	Segment *s;
180 	int n, m, sg, i;
181 	ulong vastart, vaend;
182 	char mfile[128], tfile[128], sfile[1024];
183 
184 	sprint(mfile, "/proc/%d/mem", pid);
185 	sprint(tfile, "/proc/%d/text", pid);
186 	sprint(sfile, "/proc/%d/segment", pid);
187 
188 	text = open(tfile, OREAD);
189 	if(text < 0)
190 		fatal(1, "open text %s", tfile);
191 	inithdr(text);
192 
193 	sg = open(sfile, OREAD);
194 	if(sg < 0)
195 		fatal(1, "open text %s", sfile);
196 
197 	n = read(sg, sfile, sizeof(sfile));
198 	if(n >= sizeof(sfile))
199 		fatal(0, "segment file buffer too small");
200 	close(sg);
201 
202 	m = open(mfile, OREAD);
203 	if(m < 0)
204 		fatal(1, "open %s", mfile);
205 
206 	initmap();
207 
208 	p = strstr(sfile, "Data");
209 	if(p == 0)
210 		fatal(0, "no data");
211 
212 	vastart = strtoul(p+9, 0, 16);
213 	vaend = strtoul(p+18, 0, 16);
214 	s = &memory.seg[Data];
215 	if(s->base != vastart || s->end != vaend) {
216 		s->base = vastart;
217 		s->end = vaend;
218 		free(s->table);
219 		s->table = malloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
220 	}
221 	seginit(m, s, 0, vastart, vaend);
222 
223 	p = strstr(sfile, "Bss");
224 	if(p == 0)
225 		fatal(0, "no bss");
226 
227 	vastart = strtoul(p+9, 0, 16);
228 	vaend = strtoul(p+18, 0, 16);
229 	s = &memory.seg[Bss];
230 	if(s->base != vastart || s->end != vaend) {
231 		s->base = vastart;
232 		s->end = vaend;
233 		free(s->table);
234 		s->table = malloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
235 	}
236 	seginit(m, s, 0, vastart, vaend);
237 
238 	reg.pc = greg(m, REGOFF(pc));
239 	reg.r[1] = greg(m, REGOFF(sp));
240 	reg.r[2] = greg(m, REGOFF(r2));
241 	reg.r[30] = greg(m, REGOFF(r30));
242 	reg.r[31] = greg(m, REGOFF(r31));
243 
244 	for(i = 0; i < 32; i++)
245 		reg.r[i] = greg(m, roff[i-1]);
246 
247 	s = &memory.seg[Stack];
248 	vastart = reg.r[1] & ~(BY2PG-1);
249 	seginit(m, s, (vastart-s->base)/BY2PG, vastart, STACKTOP);
250 	close(m);
251 	Bprint(bioout, "qi\n");
252 }
253 
254 void
255 reset(void)
256 {
257 	int i, l, m;
258 	Segment *s;
259 	Breakpoint *b;
260 
261 	memset(&reg, 0, sizeof(Registers));
262 	fpreginit();
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;
282 	int i;
283 	char *p;
284 
285 	initmap();
286 	sp = STACKTOP - 4;
287 
288 	/* Build exec stack */
289 	size = strlen(file)+1+BY2WD+BY2WD+(BY2WD*2);
290 	for(i = 0; i < argc; i++)
291 		size += strlen(argv[i])+BY2WD+1;
292 
293 	sp -= size;
294 	sp &= ~7;
295 	reg.r[1] = sp;
296 	reg.r[3] = STACKTOP-4;	/* Plan 9 profiling clock */
297 
298 	/* Push argc */
299 	putmem_w(sp, argc+1);
300 	sp += BY2WD;
301 
302 	/* Compute sizeof(argv) and push argv[0] */
303 	ap = sp+((argc+1)*BY2WD)+BY2WD;
304 	putmem_w(sp, ap);
305 	sp += BY2WD;
306 
307 	/* Build argv[0] string into stack */
308 	for(p = file; *p; p++)
309 		putmem_b(ap++, *p);
310 
311 	putmem_b(ap++, '\0');
312 
313 	/* Loop through pushing the arguments */
314 	for(i = 0; i < argc; i++) {
315 		putmem_w(sp, ap);
316 		sp += BY2WD;
317 		for(p = argv[i]; *p; p++)
318 			putmem_b(ap++, *p);
319 		putmem_b(ap++, '\0');
320 	}
321 	/* Null terminate argv */
322 	putmem_w(sp, 0);
323 
324 }
325 
326 void
327 fatal(int syserr, char *fmt, ...)
328 {
329 	char buf[ERRMAX], *s;
330 	va_list ap;
331 
332 	va_start(ap, fmt);
333 	vseprint(buf, buf+sizeof(buf), fmt, ap);
334 	va_end(ap);
335 	s = "qi: %s\n";
336 	if(syserr)
337 		s = "qi: %s: %r\n";
338 	fprint(2, s, buf);
339 	exits(buf);
340 }
341 
342 void
343 itrace(char *fmt, ...)
344 {
345 	char buf[128];
346 	va_list ap;
347 
348 	va_start(ap, fmt);
349 	vseprint(buf, buf+sizeof(buf), fmt, ap);
350 	va_end(ap);
351 	Bprint(bioout, "%8lux %.8lux %s\n", reg.pc, reg.ir, buf);
352 Bflush(bioout);
353 }
354 
355 void
356 dumpreg(void)
357 {
358 	int i;
359 
360 	Bprint(bioout, "PC  #%-8lux SP  #%-8lux CR #%-8lux LR #%-8lux CTR #%-8lux XER #%-8lux\n",
361 				reg.pc, reg.r[1], reg.cr, reg.lr, reg.ctr, reg.xer);
362 
363 	for(i = 0; i < 32; i++) {
364 		if((i%4) == 0 && i != 0)
365 			Bprint(bioout, "\n");
366 		Bprint(bioout, "R%-2d #%-8lux ", i, reg.r[i]);
367 	}
368 	Bprint(bioout, "\n");
369 }
370 
371 void
372 dumpfreg(void)
373 {
374 	dumpdreg();
375 }
376 
377 void
378 dumpdreg(void)
379 {
380 	int i;
381 	char buf[64];
382 	FPdbleword d;
383 
384 	i = 0;
385 	while(i < 32) {
386 		d.x = reg.fd[i];
387 		ieeedftos(buf, sizeof(buf), d.hi, d.lo);
388 		Bprint(bioout, "F%-2d %s\t", i, buf);
389 		i++;
390 		d.x = reg.fd[i];
391 		ieeedftos(buf, sizeof(buf), d.hi, d.lo);
392 		Bprint(bioout, "\tF%-2d %s\n", i, buf);
393 		i++;
394 	}
395 }
396 
397 void *
398 emalloc(ulong size)
399 {
400 	void *a;
401 
402 	a = malloc(size);
403 	if(a == 0)
404 		fatal(0, "no memory");
405 
406 	memset(a, 0, size);
407 	return a;
408 }
409 
410 void *
411 erealloc(void *a, ulong oldsize, ulong size)
412 {
413 	void *n;
414 
415 	n = malloc(size);
416 	if(n == 0)
417 		fatal(0, "no memory");
418 	memset(n, 0, size);
419 	if(size > oldsize)
420 		size = oldsize;
421 	memmove(n, a, size);
422 	return n;
423 }
424