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(®, 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