void span(void) { Prog *p, *q; int32 v, c, idat; int m, n, again; xdefine("etext", STEXT, 0L); idat = INITDAT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) curtext = p; n = 0; if(p->to.type == D_BRANCH) if(p->pcond == P) p->pcond = p; if((q = p->pcond) != P) if(q->back != 2) n = 1; p->back = n; if(p->as == AADJSP) { p->to.type = D_SP; v = -p->from.offset; p->from.offset = v; p->as = AADDL; if(v < 0) { p->as = ASUBL; v = -v; p->from.offset = v; } if(v == 0) p->as = ANOP; } } n = 0; start: do{ again = 0; if(debug['v']) Bprint(&bso, "%5.2f span %d\n", cputime(), n); Bflush(&bso); if(n > 500) { // TODO(rsc): figure out why nacl takes so long to converge. print("span must be looping - %d\n", textsize); errorexit(); } c = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) { curtext = p; if(HEADTYPE == 8) c = (c+31)&~31; } if(p->to.type == D_BRANCH) if(p->back) p->pc = c; if(n == 0 || HEADTYPE == 8 || p->to.type == D_BRANCH) { if(HEADTYPE == 8) p->pc = c; asmins(p); m = andptr-and; if(p->mark != m) again = 1; p->mark = m; } if(HEADTYPE == 8) { c = p->pc + p->mark; } else { p->pc = c; c += p->mark; } } textsize = c; n++; }while(again); if(INITRND) { INITDAT = rnd(c, INITRND); if(INITDAT != idat) { idat = INITDAT; goto start; } } xdefine("etext", STEXT, c); if(debug['v']) Bprint(&bso, "etext = %lux\n", c); Bflush(&bso); for(p = textp; p != P; p = p->pcond) p->from.sym->value = p->pc; textsize = c - INITTEXT; }
void asmb(void) { Prog *p; long v; int a; short *op1; if(debug['v']) Bprint(&bso, "%5.2f asmb\n", cputime()); Bflush(&bso); seek(cout, HEADR, 0); pc = INITTEXT; curp = firstp; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) curtext = p; if(p->pc != pc) { if(!debug['a']) print("%P\n", curp); diag("phase error %.4lux sb %.4lux in %s", p->pc, pc, TNAME); pc = p->pc; } curp = p; if(debug['a']) Bprint(&bso, "%lux:%P\n", pc, curp); asmins(p); if(cbc < sizeof(opa)) cflush(); for(op1 = opa; op1 < op; op1++) { a = *op1; *cbp++ = a >> 8; *cbp++ = a; } a = 2*(op - opa); pc += a; cbc -= a; if(debug['a']) { for(op1 = opa; op1 < op; op1++) if(op1 == opa) Bprint(&bso, "\t\t%4ux", *op1 & 0xffff); else Bprint(&bso, " %4ux", *op1 & 0xffff); if(op != opa) Bprint(&bso, "\n"); } } cflush(); switch(HEADTYPE) { case 0: /* this is garbage */ seek(cout, rnd(HEADR+textsize, 8192), 0); break; case 1: /* plan9 boot data goes into text */ seek(cout, rnd(HEADR+textsize, INITRND), 0); break; case 2: /* plan 9 */ seek(cout, HEADR+textsize, 0); break; case 3: /* next boot */ seek(cout, HEADR+rnd(textsize, INITRND), 0); break; case 4: /* preprocess pilot */ seek(cout, HEADR+textsize, 0); break; } if(debug['v']) Bprint(&bso, "%5.2f datblk\n", cputime()); Bflush(&bso); for(v = 0; v < datsize; v += sizeof(buf)-100) { if(datsize-v > sizeof(buf)-100) datblk(v, sizeof(buf)-100); else datblk(v, datsize-v); } symsize = 0; spsize = 0; lcsize = 0; relocsize = 0; Bflush(&bso); switch(HEADTYPE) { default: seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0); break; case 1: /* plan9 boot data goes into text */ seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0); break; case 2: /* plan 9 */ seek(cout, HEADR+textsize+datsize, 0); break; case 3: /* next boot */ seek(cout, HEADR+rnd(textsize, INITRND)+datsize, 0); break; case 4: /* preprocess pilot */ seek(cout, HEADR+textsize+datsize, 0); break; } if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sym\n", cputime()); asmsym(); } Bflush(&bso); if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f sp\n", cputime()); asmsp(); } Bflush(&bso); if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f pc\n", cputime()); asmlc(); } Bflush(&bso); if(!debug['s']) { if(debug['v']) Bprint(&bso, "%5.2f reloc\n", cputime()); asmreloc(); } cflush(); if(debug['v']) Bprint(&bso, "%5.2f headr\n", cputime()); Bflush(&bso); seek(cout, 0L, 0); switch(HEADTYPE) { default: lput(0x160L<<16); /* magic and sections */ lput(0L); /* time and date */ lput(rnd(HEADR+textsize, 4096)+datsize); lput(symsize); /* nsyms */ lput((0x38L<<16)|7L); /* size of optional hdr and flags */ lput((0413<<16)|0437L); /* magic and version */ lput(rnd(HEADR+textsize, 4096)); /* sizes */ lput(datsize); lput(bsssize); lput(entryvalue()); /* va of entry */ lput(INITTEXT-HEADR); /* va of base of text */ lput(INITDAT); /* va of base of data */ lput(INITDAT+datsize); /* va of base of bss */ lput(~0L); /* gp reg mask */ lput(0L); lput(0L); lput(0L); lput(0L); lput(~0L); /* gp value ?? */ break; case 1: /* plan9 boot data goes into text */ lput(0407); /* magic */ lput(rnd(HEADR+textsize, INITRND)-HEADR+datsize); /* sizes */ lput(0); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(spsize); /* sp offsets */ lput(lcsize); /* line offsets */ break; case 2: /* plan 9 */ lput(0407); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(spsize); /* sp offsets */ lput(lcsize); /* line offsets */ break; case 3: /* next boot */ /* header */ lput(0xfeedfaceL); /* magic */ lput(6); /* 68040 */ lput(1); /* more 68040 */ lput(5); /* file type 'boot' */ lput(HEADTYPE); /* number commands */ lput(HEADR-7*4); /* sizeof commands */ lput(1); /* no undefineds */ /* command 1 text */ lput(1); /* command = 'segment' */ lput(124); /* command size */ s16put("__TEXT"); /* botch?? entryvalue() */ lput(INITTEXT); /* va of start */ lput(rnd(textsize, 8192)); /* va size */ lput(HEADR); /* file offset */ lput(rnd(textsize, 8192)); /* file size */ lput(7); /* max prot */ lput(7); /* init prot */ lput(1); /* number of sections */ lput(0); /* flags */ /* text section */ s16put("__text"); s16put("__TEXT"); /* botch?? entryvalue() */ lput(INITTEXT); /* va of start */ lput(textsize); /* va size */ lput(HEADR); /* file offset */ lput(2); /* align */ lput(0); /* reloff */ lput(0); /* nreloc */ lput(0); /* flags */ lput(0); /* reserved1 */ lput(0); /* reserved2 */ /* command 1 data */ lput(1); /* command = 'segment' */ lput(192); /* command size */ s16put("__DATA"); lput(INITDAT); /* va of start */ lput(rnd(datsize, 8192)); /* va size */ lput(HEADR+rnd(textsize, 8192)); /* file offset */ lput(rnd(datsize, 8192)); /* file size */ lput(7); /* max prot */ lput(7); /* init prot */ lput(2); /* number of sections */ lput(0); /* flags */ /* data section */ s16put("__data"); s16put("__DATA"); lput(INITDAT); /* va of start */ lput(datsize); /* va size */ lput(HEADR+rnd(textsize, 8192)); /* file offset */ lput(2); /* align */ lput(0); /* reloff */ lput(0); /* nreloc */ lput(0); /* flags */ lput(0); /* reserved1 */ lput(0); /* reserved2 */ /* bss section */ s16put("__bss"); s16put("__DATA"); lput(INITDAT+datsize); /* va of start */ lput(bsssize); /* va size */ lput(0); /* file offset */ lput(2); /* align */ lput(0); /* reloff */ lput(0); /* nreloc */ lput(1); /* flags = zero fill */ lput(0); /* reserved1 */ lput(0); /* reserved2 */ /* command 2 symbol */ lput(2); /* command = 'symbol' */ lput(24); /* command size */ lput(HEADR+rnd(textsize, INITRND) +datsize); /* symoff */ lput(symsize); /* nsyms */ lput(spsize); /* sp offsets */ lput(lcsize); /* line offsets */ break; case 4: /* preprocess pilot */ lput(0407); /* magic */ lput(textsize); /* sizes */ lput(datsize); lput(bsssize); lput(symsize); /* nsyms */ lput(entryvalue()); /* va of entry */ lput(spsize); /* sp offsets */ lput(lcsize); /* line offsets */ lput(relocsize); /* relocation */ break; } cflush(); }
void span1(Sym *s) { Prog *p, *q; int32 c, v, loop; uchar *bp; int n, m, i; cursym = s; if(s->p != nil) return; for(p = s->text; p != P; p = p->link) { p->back = 2; // use short branches first time through if((q = p->pcond) != P && (q->back & 2)) p->back |= 1; // backward jump if(p->as == AADJSP) { p->to.type = D_SP; v = -p->from.offset; p->from.offset = v; p->as = p->mode != 64? AADDL: AADDQ; if(v < 0) { p->as = p->mode != 64? ASUBL: ASUBQ; v = -v; p->from.offset = v; } if(v == 0) p->as = ANOP; } } n = 0; do { loop = 0; memset(s->r, 0, s->nr*sizeof s->r[0]); s->nr = 0; s->np = 0; c = 0; for(p = s->text; p != P; p = p->link) { p->pc = c; // process forward jumps to p for(q = p->comefrom; q != P; q = q->forwd) { v = p->pc - (q->pc + q->mark); if(q->back & 2) { // short if(v > 127) { loop++; q->back ^= 2; } if(q->as == AJCXZL) s->p[q->pc+2] = v; else s->p[q->pc+1] = v; } else { bp = s->p + q->pc + q->mark - 4; *bp++ = v; *bp++ = v>>8; *bp++ = v>>16; *bp = v>>24; } } p->comefrom = P; asmins(p); p->pc = c; m = andptr-and; symgrow(s, p->pc+m); memmove(s->p+p->pc, and, m); p->mark = m; c += m; } if(++n > 20) { diag("span must be looping"); errorexit(); } } while(loop); s->size = c; if(debug['a'] > 1) { print("span1 %s %lld (%d tries)\n %.6ux", s->name, s->size, n, 0); for(i=0; i<s->np; i++) { print(" %.2ux", s->p[i]); if(i%16 == 15) print("\n %.6ux", i+1); } if(i%16) print("\n"); for(i=0; i<s->nr; i++) { Reloc *r; r = &s->r[i]; print(" rel %#.4ux/%d %s%+lld\n", r->off, r->siz, r->sym->name, r->add); } } }
void span(void) { Prog *p, *q; long v; vlong c, idat; int m, n, again; xdefine("etext", STEXT, 0L); idat = INITDAT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) curtext = p; n = 0; if(p->to.type == D_BRANCH) if(p->pcond == P) p->pcond = p; if((q = p->pcond) != P) if(q->back != 2) n = 1; p->back = n; if(p->as == AADJSP) { p->to.type = D_SP; v = -p->from.offset; p->from.offset = v; p->as = p->mode != 64? AADDL: AADDQ; if(v < 0) { p->as = p->mode != 64? ASUBL: ASUBQ; v = -v; p->from.offset = v; } if(v == 0) p->as = ANOP; } } n = 0; start: if(debug['v']) Bprint(&bso, "%5.2f span\n", cputime()); Bflush(&bso); c = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) curtext = p; if(p->to.type == D_BRANCH) if(p->back) p->pc = c; asmins(p); p->pc = c; m = andptr-and; p->mark = m; c += m; } loop: n++; if(debug['v']) Bprint(&bso, "%5.2f span %d\n", cputime(), n); Bflush(&bso); if(n > 50) { print("span must be looping\n"); errorexit(); } again = 0; c = INITTEXT; for(p = firstp; p != P; p = p->link) { if(p->as == ATEXT) curtext = p; if(p->to.type == D_BRANCH || p->back & 0100) { if(p->back) p->pc = c; asmins(p); m = andptr-and; if(m != p->mark) { p->mark = m; again++; } } p->pc = c; c += p->mark; } if(again) { textsize = c; goto loop; } if(INITRND) { INITDAT = rnd(c, INITRND); if(INITDAT != idat) { idat = INITDAT; goto start; } } xdefine("etext", STEXT, c); if(debug['v']) Bprint(&bso, "etext = %llux\n", c); Bflush(&bso); for(p = textp; p != P; p = p->pcond) p->from.sym->value = p->pc; textsize = c - INITTEXT; }