xref: /plan9-contrib/sys/src/cmd/5i/5i.c (revision bb43afe423a7a925fe6bf0f50e9f0e6b24a63d80)
17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <bio.h>
47dd7cddfSDavid du Colombier #include <mach.h>
57dd7cddfSDavid du Colombier #include "arm.h"
67dd7cddfSDavid du Colombier 
751480713SDavid du Colombier #include <tos.h>
851480713SDavid du Colombier 
97dd7cddfSDavid du Colombier char*	file = "5.out";
107dd7cddfSDavid du Colombier int	datasize;
11061a3f44SDavid du Colombier ulong	textbase;
127dd7cddfSDavid du Colombier Biobuf	bp, bi;
137dd7cddfSDavid du Colombier Fhdr	fhdr;
147dd7cddfSDavid du Colombier 
157dd7cddfSDavid du Colombier void
main(int argc,char ** argv)167dd7cddfSDavid du Colombier main(int argc, char **argv)
177dd7cddfSDavid du Colombier {
187dd7cddfSDavid du Colombier 
197dd7cddfSDavid du Colombier 	argc--;
207dd7cddfSDavid du Colombier 	argv++;
217dd7cddfSDavid du Colombier 
227dd7cddfSDavid du Colombier 	bioout = &bp;
237dd7cddfSDavid du Colombier 	bin = &bi;
247dd7cddfSDavid du Colombier 	Binit(bioout, 1, OWRITE);
257dd7cddfSDavid du Colombier 	Binit(bin, 0, OREAD);
267dd7cddfSDavid du Colombier 
277dd7cddfSDavid du Colombier 	tlb.on = 1;
287dd7cddfSDavid du Colombier 	tlb.tlbsize = 24;
297dd7cddfSDavid du Colombier 
307dd7cddfSDavid du Colombier 	if(argc)
317dd7cddfSDavid du Colombier 		file = argv[0];
327dd7cddfSDavid du Colombier 	argc--;
337dd7cddfSDavid du Colombier 	argv++;
347dd7cddfSDavid du Colombier 
357dd7cddfSDavid du Colombier 	text = open(file, OREAD);
367dd7cddfSDavid du Colombier 	if(text < 0)
377dd7cddfSDavid du Colombier 		fatal(1, "open text '%s'", file);
387dd7cddfSDavid du Colombier 
397dd7cddfSDavid du Colombier 	Bprint(bioout, "5i\n");
407dd7cddfSDavid du Colombier 	inithdr(text);
417dd7cddfSDavid du Colombier 	initstk(argc, argv);
427dd7cddfSDavid du Colombier 
437dd7cddfSDavid du Colombier 	cmd();
447dd7cddfSDavid du Colombier }
457dd7cddfSDavid du Colombier 
467dd7cddfSDavid du Colombier void
initmap()477dd7cddfSDavid du Colombier initmap()
487dd7cddfSDavid du Colombier {
497dd7cddfSDavid du Colombier 	ulong t, d, b, bssend;
507dd7cddfSDavid du Colombier 	Segment *s;
517dd7cddfSDavid du Colombier 
527dd7cddfSDavid du Colombier 	t = (fhdr.txtaddr+fhdr.txtsz+(BY2PG-1)) & ~(BY2PG-1);
537dd7cddfSDavid du Colombier 	d = (t + fhdr.datsz + (BY2PG-1)) & ~(BY2PG-1);
547dd7cddfSDavid du Colombier 	bssend = t + fhdr.datsz + fhdr.bsssz;
557dd7cddfSDavid du Colombier 	b = (bssend + (BY2PG-1)) & ~(BY2PG-1);
567dd7cddfSDavid du Colombier 
577dd7cddfSDavid du Colombier 	s = &memory.seg[Text];
587dd7cddfSDavid du Colombier 	s->type = Text;
597dd7cddfSDavid du Colombier 	s->base = fhdr.txtaddr - fhdr.hdrsz;
607dd7cddfSDavid du Colombier 	s->end = t;
617dd7cddfSDavid du Colombier 	s->fileoff = fhdr.txtoff - fhdr.hdrsz;
627dd7cddfSDavid du Colombier 	s->fileend = s->fileoff + fhdr.txtsz;
630ce5db6cSDavid du Colombier 	s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
647dd7cddfSDavid du Colombier 
657dd7cddfSDavid du Colombier 	iprof = emalloc(((s->end-s->base)/PROFGRAN)*sizeof(long));
667dd7cddfSDavid du Colombier 	textbase = s->base;
677dd7cddfSDavid du Colombier 
687dd7cddfSDavid du Colombier 	s = &memory.seg[Data];
697dd7cddfSDavid du Colombier 	s->type = Data;
707dd7cddfSDavid du Colombier 	s->base = t;
717dd7cddfSDavid du Colombier 	s->end = t+(d-t);
727dd7cddfSDavid du Colombier 	s->fileoff = fhdr.datoff;
737dd7cddfSDavid du Colombier 	s->fileend = s->fileoff + fhdr.datsz;
747dd7cddfSDavid du Colombier 	datasize = fhdr.datsz;
750ce5db6cSDavid du Colombier 	s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
767dd7cddfSDavid du Colombier 
777dd7cddfSDavid du Colombier 	s = &memory.seg[Bss];
787dd7cddfSDavid du Colombier 	s->type = Bss;
797dd7cddfSDavid du Colombier 	s->base = d;
807dd7cddfSDavid du Colombier 	s->end = d+(b-d);
810ce5db6cSDavid du Colombier 	s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
827dd7cddfSDavid du Colombier 
837dd7cddfSDavid du Colombier 	s = &memory.seg[Stack];
847dd7cddfSDavid du Colombier 	s->type = Stack;
857dd7cddfSDavid du Colombier 	s->base = STACKTOP-STACKSIZE;
867dd7cddfSDavid du Colombier 	s->end = STACKTOP;
870ce5db6cSDavid du Colombier 	s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
887dd7cddfSDavid du Colombier 
897dd7cddfSDavid du Colombier 	reg.r[REGPC] = fhdr.entry;
907dd7cddfSDavid du Colombier }
917dd7cddfSDavid du Colombier 
927dd7cddfSDavid du Colombier void
inithdr(int fd)937dd7cddfSDavid du Colombier inithdr(int fd)
947dd7cddfSDavid du Colombier {
957dd7cddfSDavid du Colombier 	Symbol s;
967dd7cddfSDavid du Colombier 
977dd7cddfSDavid du Colombier 	extern Machdata armmach;
987dd7cddfSDavid du Colombier 
997dd7cddfSDavid du Colombier 	seek(fd, 0, 0);
1007dd7cddfSDavid du Colombier 	if (!crackhdr(fd, &fhdr))
1017dd7cddfSDavid du Colombier 		fatal(0, "read text header");
1027dd7cddfSDavid du Colombier 
1037dd7cddfSDavid du Colombier 	if(fhdr.type != FARM )
1047dd7cddfSDavid du Colombier 		fatal(0, "bad magic number: %d %d", fhdr.type, FARM);
1057dd7cddfSDavid du Colombier 
1067dd7cddfSDavid du Colombier 	if (syminit(fd, &fhdr) < 0)
1077dd7cddfSDavid du Colombier 		fatal(0, "%r\n");
1087dd7cddfSDavid du Colombier 
1097dd7cddfSDavid du Colombier 	symmap = loadmap(symmap, fd, &fhdr);
1107dd7cddfSDavid du Colombier 	if (mach->sbreg && lookup(0, mach->sbreg, &s))
1117dd7cddfSDavid du Colombier 		mach->sb = s.value;
1127dd7cddfSDavid du Colombier 	machdata = &armmach;
1137dd7cddfSDavid du Colombier }
1147dd7cddfSDavid du Colombier 
1157dd7cddfSDavid du Colombier void
reset(void)1167dd7cddfSDavid du Colombier reset(void)
1177dd7cddfSDavid du Colombier {
1187dd7cddfSDavid du Colombier 	int i, l, m;
1197dd7cddfSDavid du Colombier 	Segment *s;
1207dd7cddfSDavid du Colombier 	Breakpoint *b;
1217dd7cddfSDavid du Colombier 
1227dd7cddfSDavid du Colombier 	memset(&reg, 0, sizeof(Registers));
1237dd7cddfSDavid du Colombier 
1247dd7cddfSDavid du Colombier 	for(i = 0; i > Nseg; i++) {
1257dd7cddfSDavid du Colombier 		s = &memory.seg[i];
1260ce5db6cSDavid du Colombier 		l = ((s->end-s->base)/BY2PG)*sizeof(uchar*);
1277dd7cddfSDavid du Colombier 		for(m = 0; m < l; m++)
1287dd7cddfSDavid du Colombier 			if(s->table[m])
1297dd7cddfSDavid du Colombier 				free(s->table[m]);
1307dd7cddfSDavid du Colombier 		free(s->table);
1317dd7cddfSDavid du Colombier 	}
1327dd7cddfSDavid du Colombier 	free(iprof);
1337dd7cddfSDavid du Colombier 	memset(&memory, 0, sizeof(memory));
1347dd7cddfSDavid du Colombier 
1357dd7cddfSDavid du Colombier 	for(b = bplist; b; b = b->next)
1367dd7cddfSDavid du Colombier 		b->done = b->count;
1377dd7cddfSDavid du Colombier }
1387dd7cddfSDavid du Colombier 
1397dd7cddfSDavid du Colombier void
initstk(int argc,char * argv[])1407dd7cddfSDavid du Colombier initstk(int argc, char *argv[])
1417dd7cddfSDavid du Colombier {
1427dd7cddfSDavid du Colombier 	ulong size;
14351480713SDavid du Colombier 	ulong sp, ap, tos;
1447dd7cddfSDavid du Colombier 	int i;
1457dd7cddfSDavid du Colombier 	char *p;
1467dd7cddfSDavid du Colombier 
1477dd7cddfSDavid du Colombier 	initmap();
14851480713SDavid du Colombier 	tos = STACKTOP - sizeof(Tos)*2;	/* we'll assume twice the host's is big enough */
14951480713SDavid du Colombier 	sp = tos;
150*bb43afe4SDavid du Colombier 	for (i = 0; i < sizeof(Tos)*2; i++)
151*bb43afe4SDavid du Colombier 		putmem_b(tos + i, 0);
152*bb43afe4SDavid du Colombier 
153*bb43afe4SDavid du Colombier 	/*
154*bb43afe4SDavid du Colombier 	 * pid is second word from end of tos and needs to be set for nsec().
155*bb43afe4SDavid du Colombier 	 * we know arm is a 32-bit cpu, so we'll assume knowledge of the Tos
156*bb43afe4SDavid du Colombier 	 * struct for now, and use our pid.
157*bb43afe4SDavid du Colombier 	 */
158*bb43afe4SDavid du Colombier 	putmem_w(tos + 4*4 + 2*sizeof(ulong) + 3*sizeof(uvlong), getpid());
1597dd7cddfSDavid du Colombier 
1607dd7cddfSDavid du Colombier 	/* Build exec stack */
1617dd7cddfSDavid du Colombier 	size = strlen(file)+1+BY2WD+BY2WD+BY2WD;
1627dd7cddfSDavid du Colombier 	for(i = 0; i < argc; i++)
1637dd7cddfSDavid du Colombier 		size += strlen(argv[i])+BY2WD+1;
1647dd7cddfSDavid du Colombier 
1657dd7cddfSDavid du Colombier 	sp -= size;
16651480713SDavid du Colombier 	sp &= ~7;
16751480713SDavid du Colombier 	reg.r[0] = tos;
1687dd7cddfSDavid du Colombier 	reg.r[13] = sp;
169*bb43afe4SDavid du Colombier 	reg.r[1] = STACKTOP-4;	/* Plan 9 profiling clock (why & why in R1?) */
1707dd7cddfSDavid du Colombier 
1717dd7cddfSDavid du Colombier 	/* Push argc */
1727dd7cddfSDavid du Colombier 	putmem_w(sp, argc+1);
1737dd7cddfSDavid du Colombier 	sp += BY2WD;
1747dd7cddfSDavid du Colombier 
1757dd7cddfSDavid du Colombier 	/* Compute sizeof(argv) and push argv[0] */
1767dd7cddfSDavid du Colombier 	ap = sp+((argc+1)*BY2WD)+BY2WD;
1777dd7cddfSDavid du Colombier 	putmem_w(sp, ap);
1787dd7cddfSDavid du Colombier 	sp += BY2WD;
1797dd7cddfSDavid du Colombier 
1807dd7cddfSDavid du Colombier 	/* Build argv[0] string into stack */
1817dd7cddfSDavid du Colombier 	for(p = file; *p; p++)
1827dd7cddfSDavid du Colombier 		putmem_b(ap++, *p);
1837dd7cddfSDavid du Colombier 
1847dd7cddfSDavid du Colombier 	putmem_b(ap++, '\0');
1857dd7cddfSDavid du Colombier 
1867dd7cddfSDavid du Colombier 	/* Loop through pushing the arguments */
1877dd7cddfSDavid du Colombier 	for(i = 0; i < argc; i++) {
1887dd7cddfSDavid du Colombier 		putmem_w(sp, ap);
1897dd7cddfSDavid du Colombier 		sp += BY2WD;
1907dd7cddfSDavid du Colombier 		for(p = argv[i]; *p; p++)
1917dd7cddfSDavid du Colombier 			putmem_b(ap++, *p);
1927dd7cddfSDavid du Colombier 		putmem_b(ap++, '\0');
1937dd7cddfSDavid du Colombier 	}
1947dd7cddfSDavid du Colombier 	/* Null terminate argv */
1957dd7cddfSDavid du Colombier 	putmem_w(sp, 0);
1967dd7cddfSDavid du Colombier 
1977dd7cddfSDavid du Colombier }
1987dd7cddfSDavid du Colombier 
1997dd7cddfSDavid du Colombier void
fatal(int syserr,char * fmt,...)2007dd7cddfSDavid du Colombier fatal(int syserr, char *fmt, ...)
2017dd7cddfSDavid du Colombier {
2029a747e4fSDavid du Colombier 	char buf[ERRMAX], *s;
2037dd7cddfSDavid du Colombier 	va_list arg;
2047dd7cddfSDavid du Colombier 
2057dd7cddfSDavid du Colombier 	va_start(arg, fmt);
2069a747e4fSDavid du Colombier 	vseprint(buf, buf+sizeof(buf), fmt, arg);
2077dd7cddfSDavid du Colombier 	va_end(arg);
2087dd7cddfSDavid du Colombier 	s = "5i: %s\n";
2097dd7cddfSDavid du Colombier 	if(syserr)
2107dd7cddfSDavid du Colombier 		s = "5i: %s: %r\n";
2117dd7cddfSDavid du Colombier 	fprint(2, s, buf);
2127dd7cddfSDavid du Colombier 	exits(buf);
2137dd7cddfSDavid du Colombier }
2147dd7cddfSDavid du Colombier 
2157dd7cddfSDavid du Colombier void
itrace(char * fmt,...)2167dd7cddfSDavid du Colombier itrace(char *fmt, ...)
2177dd7cddfSDavid du Colombier {
2187dd7cddfSDavid du Colombier 	char buf[128];
2197dd7cddfSDavid du Colombier 	va_list arg;
2207dd7cddfSDavid du Colombier 
2217dd7cddfSDavid du Colombier 	va_start(arg, fmt);
2229a747e4fSDavid du Colombier 	vseprint(buf, buf+sizeof(buf), fmt, arg);
2237dd7cddfSDavid du Colombier 	va_end(arg);
22459cc4ca5SDavid du Colombier 	Bprint(bioout, "%8lux %.8lux %2d %s\n", reg.ar, reg.ir, reg.class, buf);
2257dd7cddfSDavid du Colombier }
2267dd7cddfSDavid du Colombier 
2277dd7cddfSDavid du Colombier void
dumpreg(void)2287dd7cddfSDavid du Colombier dumpreg(void)
2297dd7cddfSDavid du Colombier {
2307dd7cddfSDavid du Colombier 	int i;
2317dd7cddfSDavid du Colombier 
2327dd7cddfSDavid du Colombier 	Bprint(bioout, "PC  #%-8lux SP  #%-8lux \n",
2337dd7cddfSDavid du Colombier 				reg.r[REGPC], reg.r[REGSP]);
2347dd7cddfSDavid du Colombier 
2357dd7cddfSDavid du Colombier 	for(i = 0; i < 16; i++) {
2367dd7cddfSDavid du Colombier 		if((i%4) == 0 && i != 0)
2377dd7cddfSDavid du Colombier 			Bprint(bioout, "\n");
2387dd7cddfSDavid du Colombier 		Bprint(bioout, "R%-2d #%-8lux ", i, reg.r[i]);
2397dd7cddfSDavid du Colombier 	}
2407dd7cddfSDavid du Colombier 	Bprint(bioout, "\n");
2417dd7cddfSDavid du Colombier }
2427dd7cddfSDavid du Colombier 
2437dd7cddfSDavid du Colombier void
dumpfreg(void)2447dd7cddfSDavid du Colombier dumpfreg(void)
2457dd7cddfSDavid du Colombier {
2467dd7cddfSDavid du Colombier }
2477dd7cddfSDavid du Colombier 
2487dd7cddfSDavid du Colombier void
dumpdreg(void)2497dd7cddfSDavid du Colombier dumpdreg(void)
2507dd7cddfSDavid du Colombier {
2517dd7cddfSDavid du Colombier }
2527dd7cddfSDavid du Colombier 
2537dd7cddfSDavid du Colombier void *
emalloc(ulong size)2547dd7cddfSDavid du Colombier emalloc(ulong size)
2557dd7cddfSDavid du Colombier {
2567dd7cddfSDavid du Colombier 	void *a;
2577dd7cddfSDavid du Colombier 
2587dd7cddfSDavid du Colombier 	a = malloc(size);
2597dd7cddfSDavid du Colombier 	if(a == 0)
2607dd7cddfSDavid du Colombier 		fatal(0, "no memory");
2617dd7cddfSDavid du Colombier 
2627dd7cddfSDavid du Colombier 	memset(a, 0, size);
2637dd7cddfSDavid du Colombier 	return a;
2647dd7cddfSDavid du Colombier }
2657dd7cddfSDavid du Colombier 
2667dd7cddfSDavid du Colombier void *
erealloc(void * a,ulong oldsize,ulong size)2677dd7cddfSDavid du Colombier erealloc(void *a, ulong oldsize, ulong size)
2687dd7cddfSDavid du Colombier {
2697dd7cddfSDavid du Colombier 	void *n;
2707dd7cddfSDavid du Colombier 
2717dd7cddfSDavid du Colombier 	n = malloc(size);
2727dd7cddfSDavid du Colombier 	if(n == 0)
2737dd7cddfSDavid du Colombier 		fatal(0, "no memory");
2747dd7cddfSDavid du Colombier 	memset(n, 0, size);
2757dd7cddfSDavid du Colombier 	if(size > oldsize)
2767dd7cddfSDavid du Colombier 		size = oldsize;
2777dd7cddfSDavid du Colombier 	memmove(n, a, size);
2787dd7cddfSDavid du Colombier 	return n;
2797dd7cddfSDavid du Colombier }
280