xref: /plan9-contrib/sys/src/cmd/qi/qi.c (revision bb43afe423a7a925fe6bf0f50e9f0e6b24a63d80)
17d9195a7SDavid du Colombier #include <u.h>
27d9195a7SDavid du Colombier #include <libc.h>
37d9195a7SDavid du Colombier #include <bio.h>
47d9195a7SDavid du Colombier #include <mach.h>
5*bb43afe4SDavid du Colombier #include <tos.h>
67d9195a7SDavid du Colombier #define Extern
77d9195a7SDavid du Colombier #include "power.h"
87d9195a7SDavid du Colombier 
97d9195a7SDavid du Colombier char	*file = "q.out";
107d9195a7SDavid du Colombier int	datasize;
117d9195a7SDavid du Colombier ulong	textbase;
127d9195a7SDavid du Colombier Biobuf	bp, bi;
137d9195a7SDavid du Colombier Fhdr	fhdr;
147d9195a7SDavid du Colombier ulong	bits[32];
157d9195a7SDavid du Colombier 
167d9195a7SDavid du Colombier void
main(int argc,char ** argv)177d9195a7SDavid du Colombier main(int argc, char **argv)
187d9195a7SDavid du Colombier {
197d9195a7SDavid du Colombier 	int pid, i;
207d9195a7SDavid du Colombier 
217d9195a7SDavid du Colombier 	argc--;
227d9195a7SDavid du Colombier 	argv++;
237d9195a7SDavid du Colombier 
247d9195a7SDavid du Colombier 	bioout = &bp;
257d9195a7SDavid du Colombier 	bin = &bi;
267d9195a7SDavid du Colombier 	Binit(bioout, 1, OWRITE);
277d9195a7SDavid du Colombier 	Binit(bin, 0, OREAD);
287d9195a7SDavid du Colombier 
297d9195a7SDavid du Colombier 	if(argc) {
307d9195a7SDavid du Colombier 		pid = atoi(argv[0]);
317d9195a7SDavid du Colombier 		if(pid != 0) {
327d9195a7SDavid du Colombier 			procinit(pid);
337d9195a7SDavid du Colombier 			cmd();
347d9195a7SDavid du Colombier 		}
357d9195a7SDavid du Colombier 		file = argv[0];
367d9195a7SDavid du Colombier 	}
377d9195a7SDavid du Colombier 	argc--;
387d9195a7SDavid du Colombier 	argv++;
397d9195a7SDavid du Colombier 
407d9195a7SDavid du Colombier 	text = open(file, OREAD);
417d9195a7SDavid du Colombier 	if(text < 0)
427d9195a7SDavid du Colombier 		fatal(1, "open text '%s'", file);
437d9195a7SDavid du Colombier 
447d9195a7SDavid du Colombier 	Bprint(bioout, "qi\n");
457d9195a7SDavid du Colombier 	inithdr(text);
467d9195a7SDavid du Colombier 	initstk(argc, argv);
477d9195a7SDavid du Colombier 
487d9195a7SDavid du Colombier 	for(i=0; i<32; i++)
497d9195a7SDavid du Colombier 		bits[i] = 1L << (31-i);
507d9195a7SDavid du Colombier 
516891d857SDavid du Colombier 	fpreginit();
527d9195a7SDavid du Colombier 	cmd();
537d9195a7SDavid du Colombier }
547d9195a7SDavid du Colombier 
55*bb43afe4SDavid du Colombier /*
56*bb43afe4SDavid du Colombier  * we're rounding segment boundaries to the nearest 1MB on power now,
57*bb43afe4SDavid du Colombier  * and mach->pgsize is actually what to round segment boundaries up to.
58*bb43afe4SDavid du Colombier  */
59*bb43afe4SDavid du Colombier #define SEGROUND mach->pgsize
60*bb43afe4SDavid du Colombier 
617d9195a7SDavid du Colombier void
initmap(void)627d9195a7SDavid du Colombier initmap(void)
637d9195a7SDavid du Colombier {
647d9195a7SDavid du Colombier 
657d9195a7SDavid du Colombier 	ulong t, d, b, bssend;
667d9195a7SDavid du Colombier 	Segment *s;
677d9195a7SDavid du Colombier 
68*bb43afe4SDavid du Colombier 	t = (fhdr.txtaddr+fhdr.txtsz+(SEGROUND-1)) & ~(SEGROUND-1);
69*bb43afe4SDavid du Colombier 	d = (t + fhdr.datsz + (SEGROUND-1)) & ~(SEGROUND-1);
707d9195a7SDavid du Colombier 	bssend = t + fhdr.datsz + fhdr.bsssz;
71*bb43afe4SDavid du Colombier 	b = (bssend + (SEGROUND-1)) & ~(SEGROUND-1);
727d9195a7SDavid du Colombier 
737d9195a7SDavid du Colombier 	s = &memory.seg[Text];
747d9195a7SDavid du Colombier 	s->type = Text;
757d9195a7SDavid du Colombier 	s->base = fhdr.txtaddr - fhdr.hdrsz;
767d9195a7SDavid du Colombier 	s->end = t;
777d9195a7SDavid du Colombier 	s->fileoff = fhdr.txtoff - fhdr.hdrsz;
787d9195a7SDavid du Colombier 	s->fileend = s->fileoff + fhdr.txtsz;
790ce5db6cSDavid du Colombier 	s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
807d9195a7SDavid du Colombier 
817d9195a7SDavid du Colombier 	iprofsize = (s->end-s->base)/PROFGRAN;
827d9195a7SDavid du Colombier 	iprof = emalloc(iprofsize*sizeof(long));
837d9195a7SDavid du Colombier 	textbase = s->base;
847d9195a7SDavid du Colombier 
857d9195a7SDavid du Colombier 	s = &memory.seg[Data];
867d9195a7SDavid du Colombier 	s->type = Data;
877d9195a7SDavid du Colombier 	s->base = t;
887d9195a7SDavid du Colombier 	s->end = t+(d-t);
897d9195a7SDavid du Colombier 	s->fileoff = fhdr.datoff;
907d9195a7SDavid du Colombier 	s->fileend = s->fileoff + fhdr.datsz;
917d9195a7SDavid du Colombier 	datasize = fhdr.datsz;
920ce5db6cSDavid du Colombier 	s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
937d9195a7SDavid du Colombier 
947d9195a7SDavid du Colombier 	s = &memory.seg[Bss];
957d9195a7SDavid du Colombier 	s->type = Bss;
967d9195a7SDavid du Colombier 	s->base = d;
977d9195a7SDavid du Colombier 	s->end = d+(b-d);
980ce5db6cSDavid du Colombier 	s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
997d9195a7SDavid du Colombier 
1007d9195a7SDavid du Colombier 	s = &memory.seg[Stack];
1017d9195a7SDavid du Colombier 	s->type = Stack;
1027d9195a7SDavid du Colombier 	s->base = STACKTOP-STACKSIZE;
1037d9195a7SDavid du Colombier 	s->end = STACKTOP;
1040ce5db6cSDavid du Colombier 	s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
1057d9195a7SDavid du Colombier 
1067d9195a7SDavid du Colombier 	reg.pc = fhdr.entry;
1077d9195a7SDavid du Colombier }
1087d9195a7SDavid du Colombier 
1097d9195a7SDavid du Colombier void
inithdr(int fd)1107d9195a7SDavid du Colombier inithdr(int fd)
1117d9195a7SDavid du Colombier {
1127d9195a7SDavid du Colombier 	Symbol s;
1137d9195a7SDavid du Colombier 
1147d9195a7SDavid du Colombier 	extern Machdata powermach;
1157d9195a7SDavid du Colombier 
1167d9195a7SDavid du Colombier 	seek(fd, 0, 0);
1177d9195a7SDavid du Colombier 	if (!crackhdr(fd, &fhdr))
1187d9195a7SDavid du Colombier 		fatal(0, "read text header");
1197d9195a7SDavid du Colombier 
1207d9195a7SDavid du Colombier 	if(fhdr.type != FPOWER)
1217d9195a7SDavid du Colombier 		fatal(0, "bad magic number");
1227d9195a7SDavid du Colombier 
1237d9195a7SDavid du Colombier 	if(syminit(fd, &fhdr) < 0)
1247d9195a7SDavid du Colombier 		fatal(0, "%r\n");
1257d9195a7SDavid du Colombier 	symmap = loadmap(symmap, fd, &fhdr);
1267d9195a7SDavid du Colombier 	if (mach->sbreg && lookup(0, mach->sbreg, &s))
1277d9195a7SDavid du Colombier 		mach->sb = s.value;
1287d9195a7SDavid du Colombier 	machdata = &powermach;
1297d9195a7SDavid du Colombier }
1307d9195a7SDavid du Colombier 
1317d9195a7SDavid du Colombier ulong
greg(int f,ulong off)1327d9195a7SDavid du Colombier greg(int f, ulong off)
1337d9195a7SDavid du Colombier {
1347d9195a7SDavid du Colombier 	int n;
1357d9195a7SDavid du Colombier 	ulong l;
1367d9195a7SDavid du Colombier 	uchar wd[BY2WD];
1377d9195a7SDavid du Colombier 
1387d9195a7SDavid du Colombier 	seek(f, off, 0);
1397d9195a7SDavid du Colombier 	n = read(f, wd, BY2WD);
1407d9195a7SDavid du Colombier 	if(n != BY2WD)
1417d9195a7SDavid du Colombier 		fatal(1, "read register");
1427d9195a7SDavid du Colombier 
1437d9195a7SDavid du Colombier 	l  = wd[0]<<24;
1447d9195a7SDavid du Colombier 	l |= wd[1]<<16;
1457d9195a7SDavid du Colombier 	l |= wd[2]<<8;
1467d9195a7SDavid du Colombier 	l |= wd[3];
1477d9195a7SDavid du Colombier 	return l;
1487d9195a7SDavid du Colombier }
1497d9195a7SDavid du Colombier 
1507d9195a7SDavid du Colombier ulong
1517d9195a7SDavid du Colombier roff[] = {
1527d9195a7SDavid du Colombier 	REGOFF(r0),
1537d9195a7SDavid du Colombier 	REGOFF(r1),	REGOFF(r2),	REGOFF(r3),
1547d9195a7SDavid du Colombier 	REGOFF(r4),	REGOFF(r5),	REGOFF(r6),
1557d9195a7SDavid du Colombier 	REGOFF(r7),	REGOFF(r8),	REGOFF(r9),
1567d9195a7SDavid du Colombier 	REGOFF(r10),	REGOFF(r11),	REGOFF(r12),
1577d9195a7SDavid du Colombier 	REGOFF(r13),	REGOFF(r14),	REGOFF(r15),
1587d9195a7SDavid du Colombier 	REGOFF(r16),	REGOFF(r17),	REGOFF(r18),
1597d9195a7SDavid du Colombier 	REGOFF(r19),	REGOFF(r20),	REGOFF(r21),
1607d9195a7SDavid du Colombier 	REGOFF(r22),	REGOFF(r23),	REGOFF(r24),
1617d9195a7SDavid du Colombier 	REGOFF(r25),	REGOFF(r26),	REGOFF(r27),
1627d9195a7SDavid du Colombier 	REGOFF(r28),	REGOFF(r29),	REGOFF(r30),
1637d9195a7SDavid du Colombier 	REGOFF(r31),
1647d9195a7SDavid du Colombier };
1657d9195a7SDavid du Colombier 
1667d9195a7SDavid du Colombier void
seginit(int fd,Segment * s,int idx,ulong vastart,ulong vaend)1677d9195a7SDavid du Colombier seginit(int fd, Segment *s, int idx, ulong vastart, ulong vaend)
1687d9195a7SDavid du Colombier {
1697d9195a7SDavid du Colombier 	int n;
1707d9195a7SDavid du Colombier 
1717d9195a7SDavid du Colombier 	while(vastart < vaend) {
1727d9195a7SDavid du Colombier 		seek(fd, vastart, 0);
1737d9195a7SDavid du Colombier 		s->table[idx] = emalloc(BY2PG);
1747d9195a7SDavid du Colombier 		n = read(fd, s->table[idx], BY2PG);
1757d9195a7SDavid du Colombier 		if(n != BY2PG)
1767d9195a7SDavid du Colombier 			fatal(1, "data read");
1777d9195a7SDavid du Colombier 		vastart += BY2PG;
1787d9195a7SDavid du Colombier 		idx++;
1797d9195a7SDavid du Colombier 	}
1807d9195a7SDavid du Colombier }
1817d9195a7SDavid du Colombier 
1827d9195a7SDavid du Colombier void
procinit(int pid)1837d9195a7SDavid du Colombier procinit(int pid)
1847d9195a7SDavid du Colombier {
1857d9195a7SDavid du Colombier 	char *p;
1867d9195a7SDavid du Colombier 	Segment *s;
1877d9195a7SDavid du Colombier 	int n, m, sg, i;
1887d9195a7SDavid du Colombier 	ulong vastart, vaend;
1897d9195a7SDavid du Colombier 	char mfile[128], tfile[128], sfile[1024];
1907d9195a7SDavid du Colombier 
1917d9195a7SDavid du Colombier 	sprint(mfile, "/proc/%d/mem", pid);
1927d9195a7SDavid du Colombier 	sprint(tfile, "/proc/%d/text", pid);
1937d9195a7SDavid du Colombier 	sprint(sfile, "/proc/%d/segment", pid);
1947d9195a7SDavid du Colombier 
1957d9195a7SDavid du Colombier 	text = open(tfile, OREAD);
1967d9195a7SDavid du Colombier 	if(text < 0)
1977d9195a7SDavid du Colombier 		fatal(1, "open text %s", tfile);
1987d9195a7SDavid du Colombier 	inithdr(text);
1997d9195a7SDavid du Colombier 
2007d9195a7SDavid du Colombier 	sg = open(sfile, OREAD);
2017d9195a7SDavid du Colombier 	if(sg < 0)
2027d9195a7SDavid du Colombier 		fatal(1, "open text %s", sfile);
2037d9195a7SDavid du Colombier 
2047d9195a7SDavid du Colombier 	n = read(sg, sfile, sizeof(sfile));
2057d9195a7SDavid du Colombier 	if(n >= sizeof(sfile))
2067d9195a7SDavid du Colombier 		fatal(0, "segment file buffer too small");
2077d9195a7SDavid du Colombier 	close(sg);
2087d9195a7SDavid du Colombier 
2097d9195a7SDavid du Colombier 	m = open(mfile, OREAD);
2107d9195a7SDavid du Colombier 	if(m < 0)
2117d9195a7SDavid du Colombier 		fatal(1, "open %s", mfile);
2127d9195a7SDavid du Colombier 
2137d9195a7SDavid du Colombier 	initmap();
2147d9195a7SDavid du Colombier 
2157d9195a7SDavid du Colombier 	p = strstr(sfile, "Data");
2167d9195a7SDavid du Colombier 	if(p == 0)
2177d9195a7SDavid du Colombier 		fatal(0, "no data");
2187d9195a7SDavid du Colombier 
2197d9195a7SDavid du Colombier 	vastart = strtoul(p+9, 0, 16);
2207d9195a7SDavid du Colombier 	vaend = strtoul(p+18, 0, 16);
2217d9195a7SDavid du Colombier 	s = &memory.seg[Data];
2227d9195a7SDavid du Colombier 	if(s->base != vastart || s->end != vaend) {
2237d9195a7SDavid du Colombier 		s->base = vastart;
2247d9195a7SDavid du Colombier 		s->end = vaend;
2257d9195a7SDavid du Colombier 		free(s->table);
2260ce5db6cSDavid du Colombier 		s->table = malloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
2277d9195a7SDavid du Colombier 	}
2287d9195a7SDavid du Colombier 	seginit(m, s, 0, vastart, vaend);
2297d9195a7SDavid du Colombier 
2307d9195a7SDavid du Colombier 	p = strstr(sfile, "Bss");
2317d9195a7SDavid du Colombier 	if(p == 0)
2327d9195a7SDavid du Colombier 		fatal(0, "no bss");
2337d9195a7SDavid du Colombier 
2347d9195a7SDavid du Colombier 	vastart = strtoul(p+9, 0, 16);
2357d9195a7SDavid du Colombier 	vaend = strtoul(p+18, 0, 16);
2367d9195a7SDavid du Colombier 	s = &memory.seg[Bss];
2377d9195a7SDavid du Colombier 	if(s->base != vastart || s->end != vaend) {
2387d9195a7SDavid du Colombier 		s->base = vastart;
2397d9195a7SDavid du Colombier 		s->end = vaend;
2407d9195a7SDavid du Colombier 		free(s->table);
2410ce5db6cSDavid du Colombier 		s->table = malloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
2427d9195a7SDavid du Colombier 	}
2437d9195a7SDavid du Colombier 	seginit(m, s, 0, vastart, vaend);
2447d9195a7SDavid du Colombier 
2457d9195a7SDavid du Colombier 	reg.pc = greg(m, REGOFF(pc));
2467d9195a7SDavid du Colombier 	reg.r[1] = greg(m, REGOFF(sp));
2477d9195a7SDavid du Colombier 	reg.r[2] = greg(m, REGOFF(r2));
2487d9195a7SDavid du Colombier 	reg.r[30] = greg(m, REGOFF(r30));
2497d9195a7SDavid du Colombier 	reg.r[31] = greg(m, REGOFF(r31));
2507d9195a7SDavid du Colombier 
2517d9195a7SDavid du Colombier 	for(i = 0; i < 32; i++)
2527d9195a7SDavid du Colombier 		reg.r[i] = greg(m, roff[i-1]);
2537d9195a7SDavid du Colombier 
2547d9195a7SDavid du Colombier 	s = &memory.seg[Stack];
2557d9195a7SDavid du Colombier 	vastart = reg.r[1] & ~(BY2PG-1);
2567d9195a7SDavid du Colombier 	seginit(m, s, (vastart-s->base)/BY2PG, vastart, STACKTOP);
2577d9195a7SDavid du Colombier 	close(m);
2587d9195a7SDavid du Colombier 	Bprint(bioout, "qi\n");
2597d9195a7SDavid du Colombier }
2607d9195a7SDavid du Colombier 
2617d9195a7SDavid du Colombier void
reset(void)2627d9195a7SDavid du Colombier reset(void)
2637d9195a7SDavid du Colombier {
2647d9195a7SDavid du Colombier 	int i, l, m;
2657d9195a7SDavid du Colombier 	Segment *s;
2667d9195a7SDavid du Colombier 	Breakpoint *b;
2677d9195a7SDavid du Colombier 
2687d9195a7SDavid du Colombier 	memset(&reg, 0, sizeof(Registers));
2696891d857SDavid du Colombier 	fpreginit();
2707d9195a7SDavid du Colombier 	for(i = 0; i > Nseg; i++) {
2717d9195a7SDavid du Colombier 		s = &memory.seg[i];
2720ce5db6cSDavid du Colombier 		l = ((s->end-s->base)/BY2PG)*sizeof(uchar*);
2737d9195a7SDavid du Colombier 		for(m = 0; m < l; m++)
2747d9195a7SDavid du Colombier 			if(s->table[m])
2757d9195a7SDavid du Colombier 				free(s->table[m]);
2767d9195a7SDavid du Colombier 		free(s->table);
2777d9195a7SDavid du Colombier 	}
2787d9195a7SDavid du Colombier 	free(iprof);
2797d9195a7SDavid du Colombier 	memset(&memory, 0, sizeof(memory));
2807d9195a7SDavid du Colombier 
2817d9195a7SDavid du Colombier 	for(b = bplist; b; b = b->next)
2827d9195a7SDavid du Colombier 		b->done = b->count;
2837d9195a7SDavid du Colombier }
2847d9195a7SDavid du Colombier 
2857d9195a7SDavid du Colombier void
initstk(int argc,char * argv[])2867d9195a7SDavid du Colombier initstk(int argc, char *argv[])
2877d9195a7SDavid du Colombier {
288*bb43afe4SDavid du Colombier 	ulong size, sp, ap, tos;
2897d9195a7SDavid du Colombier 	int i;
2907d9195a7SDavid du Colombier 	char *p;
2917d9195a7SDavid du Colombier 
2927d9195a7SDavid du Colombier 	initmap();
293*bb43afe4SDavid du Colombier 	tos = STACKTOP - sizeof(Tos)*2;	/* we'll assume twice the host's is big enough */
294*bb43afe4SDavid du Colombier 	sp = tos;
295*bb43afe4SDavid du Colombier 	for (i = 0; i < sizeof(Tos)*2; i++)
296*bb43afe4SDavid du Colombier 		putmem_b(tos + i, 0);
297*bb43afe4SDavid du Colombier 
298*bb43afe4SDavid du Colombier 	/*
299*bb43afe4SDavid du Colombier 	 * pid is second word from end of tos and needs to be set for nsec().
300*bb43afe4SDavid du Colombier 	 * we know power is a 32-bit cpu, so we'll assume knowledge of the Tos
301*bb43afe4SDavid du Colombier 	 * struct for now, and use our pid.
302*bb43afe4SDavid du Colombier 	 */
303*bb43afe4SDavid du Colombier 	putmem_w(tos + 4*4 + 2*sizeof(ulong) + 3*sizeof(uvlong), getpid());
3047d9195a7SDavid du Colombier 
3057d9195a7SDavid du Colombier 	/* Build exec stack */
3067d9195a7SDavid du Colombier 	size = strlen(file)+1+BY2WD+BY2WD+(BY2WD*2);
3077d9195a7SDavid du Colombier 	for(i = 0; i < argc; i++)
3087d9195a7SDavid du Colombier 		size += strlen(argv[i])+BY2WD+1;
3097d9195a7SDavid du Colombier 
3107d9195a7SDavid du Colombier 	sp -= size;
3117d9195a7SDavid du Colombier 	sp &= ~7;
3127d9195a7SDavid du Colombier 	reg.r[1] = sp;
313*bb43afe4SDavid du Colombier 	reg.r[3] = tos;		/* Plan 9 profiling clock, etc. */
3147d9195a7SDavid du Colombier 
3157d9195a7SDavid du Colombier 	/* Push argc */
3167d9195a7SDavid du Colombier 	putmem_w(sp, argc+1);
3177d9195a7SDavid du Colombier 	sp += BY2WD;
3187d9195a7SDavid du Colombier 
3197d9195a7SDavid du Colombier 	/* Compute sizeof(argv) and push argv[0] */
3207d9195a7SDavid du Colombier 	ap = sp+((argc+1)*BY2WD)+BY2WD;
3217d9195a7SDavid du Colombier 	putmem_w(sp, ap);
3227d9195a7SDavid du Colombier 	sp += BY2WD;
3237d9195a7SDavid du Colombier 
3247d9195a7SDavid du Colombier 	/* Build argv[0] string into stack */
3257d9195a7SDavid du Colombier 	for(p = file; *p; p++)
3267d9195a7SDavid du Colombier 		putmem_b(ap++, *p);
3277d9195a7SDavid du Colombier 
3287d9195a7SDavid du Colombier 	putmem_b(ap++, '\0');
3297d9195a7SDavid du Colombier 
3307d9195a7SDavid du Colombier 	/* Loop through pushing the arguments */
3317d9195a7SDavid du Colombier 	for(i = 0; i < argc; i++) {
3327d9195a7SDavid du Colombier 		putmem_w(sp, ap);
3337d9195a7SDavid du Colombier 		sp += BY2WD;
3347d9195a7SDavid du Colombier 		for(p = argv[i]; *p; p++)
3357d9195a7SDavid du Colombier 			putmem_b(ap++, *p);
3367d9195a7SDavid du Colombier 		putmem_b(ap++, '\0');
3377d9195a7SDavid du Colombier 	}
3387d9195a7SDavid du Colombier 	/* Null terminate argv */
3397d9195a7SDavid du Colombier 	putmem_w(sp, 0);
3407d9195a7SDavid du Colombier 
3417d9195a7SDavid du Colombier }
3427d9195a7SDavid du Colombier 
3437d9195a7SDavid du Colombier void
fatal(int syserr,char * fmt,...)3447d9195a7SDavid du Colombier fatal(int syserr, char *fmt, ...)
3457d9195a7SDavid du Colombier {
3467d9195a7SDavid du Colombier 	char buf[ERRMAX], *s;
3477d9195a7SDavid du Colombier 	va_list ap;
3487d9195a7SDavid du Colombier 
3497d9195a7SDavid du Colombier 	va_start(ap, fmt);
3507d9195a7SDavid du Colombier 	vseprint(buf, buf+sizeof(buf), fmt, ap);
3517d9195a7SDavid du Colombier 	va_end(ap);
3527d9195a7SDavid du Colombier 	s = "qi: %s\n";
3537d9195a7SDavid du Colombier 	if(syserr)
3547d9195a7SDavid du Colombier 		s = "qi: %s: %r\n";
3557d9195a7SDavid du Colombier 	fprint(2, s, buf);
3567d9195a7SDavid du Colombier 	exits(buf);
3577d9195a7SDavid du Colombier }
3587d9195a7SDavid du Colombier 
3597d9195a7SDavid du Colombier void
itrace(char * fmt,...)3607d9195a7SDavid du Colombier itrace(char *fmt, ...)
3617d9195a7SDavid du Colombier {
3627d9195a7SDavid du Colombier 	char buf[128];
3637d9195a7SDavid du Colombier 	va_list ap;
3647d9195a7SDavid du Colombier 
3657d9195a7SDavid du Colombier 	va_start(ap, fmt);
3667d9195a7SDavid du Colombier 	vseprint(buf, buf+sizeof(buf), fmt, ap);
3677d9195a7SDavid du Colombier 	va_end(ap);
3687d9195a7SDavid du Colombier 	Bprint(bioout, "%8lux %.8lux %s\n", reg.pc, reg.ir, buf);
3696891d857SDavid du Colombier Bflush(bioout);
3707d9195a7SDavid du Colombier }
3717d9195a7SDavid du Colombier 
3727d9195a7SDavid du Colombier void
dumpreg(void)3737d9195a7SDavid du Colombier dumpreg(void)
3747d9195a7SDavid du Colombier {
3757d9195a7SDavid du Colombier 	int i;
3767d9195a7SDavid du Colombier 
3777d9195a7SDavid du Colombier 	Bprint(bioout, "PC  #%-8lux SP  #%-8lux CR #%-8lux LR #%-8lux CTR #%-8lux XER #%-8lux\n",
3787d9195a7SDavid du Colombier 				reg.pc, reg.r[1], reg.cr, reg.lr, reg.ctr, reg.xer);
3797d9195a7SDavid du Colombier 
3807d9195a7SDavid du Colombier 	for(i = 0; i < 32; i++) {
3817d9195a7SDavid du Colombier 		if((i%4) == 0 && i != 0)
3827d9195a7SDavid du Colombier 			Bprint(bioout, "\n");
3837d9195a7SDavid du Colombier 		Bprint(bioout, "R%-2d #%-8lux ", i, reg.r[i]);
3847d9195a7SDavid du Colombier 	}
3857d9195a7SDavid du Colombier 	Bprint(bioout, "\n");
3867d9195a7SDavid du Colombier }
3877d9195a7SDavid du Colombier 
3887d9195a7SDavid du Colombier void
dumpfreg(void)3897d9195a7SDavid du Colombier dumpfreg(void)
3907d9195a7SDavid du Colombier {
3917d9195a7SDavid du Colombier 	dumpdreg();
3927d9195a7SDavid du Colombier }
3937d9195a7SDavid du Colombier 
3947d9195a7SDavid du Colombier void
dumpdreg(void)3957d9195a7SDavid du Colombier dumpdreg(void)
3967d9195a7SDavid du Colombier {
3977d9195a7SDavid du Colombier 	int i;
3987d9195a7SDavid du Colombier 	char buf[64];
3996891d857SDavid du Colombier 	FPdbleword d;
4007d9195a7SDavid du Colombier 
4017d9195a7SDavid du Colombier 	i = 0;
4027d9195a7SDavid du Colombier 	while(i < 32) {
4036891d857SDavid du Colombier 		d.x = reg.fd[i];
4046891d857SDavid du Colombier 		ieeedftos(buf, sizeof(buf), d.hi, d.lo);
4057d9195a7SDavid du Colombier 		Bprint(bioout, "F%-2d %s\t", i, buf);
4067d9195a7SDavid du Colombier 		i++;
4076891d857SDavid du Colombier 		d.x = reg.fd[i];
4086891d857SDavid du Colombier 		ieeedftos(buf, sizeof(buf), d.hi, d.lo);
4097d9195a7SDavid du Colombier 		Bprint(bioout, "\tF%-2d %s\n", i, buf);
4107d9195a7SDavid du Colombier 		i++;
4117d9195a7SDavid du Colombier 	}
4127d9195a7SDavid du Colombier }
4137d9195a7SDavid du Colombier 
4147d9195a7SDavid du Colombier void *
emalloc(ulong size)4157d9195a7SDavid du Colombier emalloc(ulong size)
4167d9195a7SDavid du Colombier {
4177d9195a7SDavid du Colombier 	void *a;
4187d9195a7SDavid du Colombier 
4197d9195a7SDavid du Colombier 	a = malloc(size);
4207d9195a7SDavid du Colombier 	if(a == 0)
4217d9195a7SDavid du Colombier 		fatal(0, "no memory");
4227d9195a7SDavid du Colombier 
4237d9195a7SDavid du Colombier 	memset(a, 0, size);
4247d9195a7SDavid du Colombier 	return a;
4257d9195a7SDavid du Colombier }
4267d9195a7SDavid du Colombier 
4277d9195a7SDavid du Colombier void *
erealloc(void * a,ulong oldsize,ulong size)4287d9195a7SDavid du Colombier erealloc(void *a, ulong oldsize, ulong size)
4297d9195a7SDavid du Colombier {
4307d9195a7SDavid du Colombier 	void *n;
4317d9195a7SDavid du Colombier 
4327d9195a7SDavid du Colombier 	n = malloc(size);
4337d9195a7SDavid du Colombier 	if(n == 0)
4347d9195a7SDavid du Colombier 		fatal(0, "no memory");
4357d9195a7SDavid du Colombier 	memset(n, 0, size);
4367d9195a7SDavid du Colombier 	if(size > oldsize)
4377d9195a7SDavid du Colombier 		size = oldsize;
4387d9195a7SDavid du Colombier 	memmove(n, a, size);
4397d9195a7SDavid du Colombier 	return n;
4407d9195a7SDavid du Colombier }
441