#include #define EXTERN #include "a.h" #include "y.tab.h" void main(int argc, char *argv[]) { char *p; int nout, nproc, status, i, c; thechar = '8'; thestring = "386"; memset(debug, 0, sizeof(debug)); cinit(); outfile = 0; include[ninclude++] = "."; ARGBEGIN { default: c = ARGC(); if(c >= 0 || c < sizeof(debug)) debug[c] = 1; break; case 'o': outfile = ARGF(); break; case 'D': p = ARGF(); if(p) Dlist[nDlist++] = p; break; case 'I': p = ARGF(); setinclude(p); break; } ARGEND if(*argv == 0) { print("usage: %ca [-options] file.s\n", thechar); errorexit(); } if(argc > 1 && systemtype(Windows)){ print("can't assemble multiple files on windows\n"); errorexit(); } if(argc > 1 && !systemtype(Windows)) { nproc = 1; if(p = getenv("NPROC")) nproc = atol(p); /* */ c = 0; nout = 0; for(;;) { while(nout < nproc && argc > 0) { i = myfork(); if(i < 0) { i = mywait(&status); if(i < 0) errorexit(); if(status) c++; nout--; continue; } if(i == 0) { print("%s:\n", *argv); if(assemble(*argv)) errorexit(); exits(0); } nout++; argc--; argv++; } i = mywait(&status); if(i < 0) { if(c) errorexit(); exits(0); } if(status) c++; nout--; } } if(assemble(argv[0])) errorexit(); exits(0); } int assemble(char *file) { char ofile[100], incfile[20], *p; int i, of; strcpy(ofile, file); p = utfrrune(ofile, pathchar()); if(p) { include[0] = ofile; *p++ = 0; } else p = ofile; if(outfile == 0) { outfile = p; if(outfile){ p = utfrrune(outfile, '.'); if(p) if(p[1] == 's' && p[2] == 0) p[0] = 0; p = utfrune(outfile, 0); p[0] = '.'; p[1] = thechar; p[2] = 0; } else outfile = "/dev/null"; } p = getenv("INCLUDE"); if(p) { setinclude(p); } else { if(systemtype(Plan9)) { sprint(incfile,"/%s/include", thestring); setinclude(strdup(incfile)); } } of = mycreat(outfile, 0664); if(of < 0) { yyerror("%ca: cannot create %s", thechar, outfile); errorexit(); } Binit(&obuf, of, OWRITE); pass = 1; pinit(file); for(i=0; itype != LNAME) yyerror("double initialization %s", itab[i].name); s->type = itab[i].type; s->value = itab[i].value; } pathname = allocn(pathname, 0, 100); if(mygetwd(pathname, 99) == 0) { pathname = allocn(pathname, 100, 900); if(mygetwd(pathname, 999) == 0) strcpy(pathname, "/???"); } } void checkscale(int scale) { switch(scale) { case 1: case 2: case 4: case 8: return; } yyerror("scale must be 1248: %d", scale); } void syminit(Sym *s) { s->type = LNAME; s->value = 0; } void cclean(void) { Gen2 g2; g2.from = nullgen; g2.to = nullgen; outcode(AEND, &g2); Bflush(&obuf); } void zname(char *n, int t, int s) { Bputc(&obuf, ANAME); /* as(2) */ Bputc(&obuf, ANAME>>8); Bputc(&obuf, t); /* type */ Bputc(&obuf, s); /* sym */ while(*n) { Bputc(&obuf, *n); n++; } Bputc(&obuf, 0); } void zaddr(Gen *a, int s) { long l; int i, t; char *n; Ieee e; t = 0; if(a->index != D_NONE || a->scale != 0) t |= T_INDEX; if(a->offset != 0) t |= T_OFFSET; if(s != 0) t |= T_SYM; switch(a->type) { default: t |= T_TYPE; break; case D_FCONST: t |= T_FCONST; break; case D_CONST2: t |= T_OFFSET|T_OFFSET2; break; case D_SCONST: t |= T_SCONST; break; case D_NONE: break; } Bputc(&obuf, t); if(t & T_INDEX) { /* implies index, scale */ Bputc(&obuf, a->index); Bputc(&obuf, a->scale); } if(t & T_OFFSET) { /* implies offset */ l = a->offset; Bputc(&obuf, l); Bputc(&obuf, l>>8); Bputc(&obuf, l>>16); Bputc(&obuf, l>>24); } if(t & T_OFFSET2) { l = a->offset2; Bputc(&obuf, l); Bputc(&obuf, l>>8); Bputc(&obuf, l>>16); Bputc(&obuf, l>>24); } if(t & T_SYM) /* implies sym */ Bputc(&obuf, s); if(t & T_FCONST) { ieeedtod(&e, a->dval); l = e.l; Bputc(&obuf, l); Bputc(&obuf, l>>8); Bputc(&obuf, l>>16); Bputc(&obuf, l>>24); l = e.h; Bputc(&obuf, l); Bputc(&obuf, l>>8); Bputc(&obuf, l>>16); Bputc(&obuf, l>>24); return; } if(t & T_SCONST) { n = a->sval; for(i=0; itype); } void outcode(int a, Gen2 *g2) { int sf, st, t; Sym *s; if(pass == 1) goto out; jackpot: sf = 0; s = g2->from.sym; while(s != S) { sf = s->sym; if(sf < 0 || sf >= NSYM) sf = 0; t = g2->from.type; if(t == D_ADDR) t = g2->from.index; if(h[sf].type == t) if(h[sf].sym == s) break; zname(s->name, t, sym); s->sym = sym; h[sym].sym = s; h[sym].type = t; sf = sym; sym++; if(sym >= NSYM) sym = 1; break; } st = 0; s = g2->to.sym; while(s != S) { st = s->sym; if(st < 0 || st >= NSYM) st = 0; t = g2->to.type; if(t == D_ADDR) t = g2->to.index; if(h[st].type == t) if(h[st].sym == s) break; zname(s->name, t, sym); s->sym = sym; h[sym].sym = s; h[sym].type = t; st = sym; sym++; if(sym >= NSYM) sym = 1; if(st == sf) goto jackpot; break; } Bputc(&obuf, a); Bputc(&obuf, a>>8); Bputc(&obuf, lineno); Bputc(&obuf, lineno>>8); Bputc(&obuf, lineno>>16); Bputc(&obuf, lineno>>24); zaddr(&g2->from, sf); zaddr(&g2->to, st); out: if(a != AGLOBL && a != ADATA) pc++; } void outhist(void) { Gen g; Hist *h; char *p, *q, *op, c; int n; g = nullgen; c = pathchar(); for(h = hist; h != H; h = h->link) { p = h->name; op = 0; /* on windows skip drive specifier in pathname */ if(systemtype(Windows) && p && p[1] == ':'){ p += 2; c = *p; } if(p && p[0] != c && h->offset == 0 && pathname){ /* on windows skip drive specifier in pathname */ if(systemtype(Windows) && pathname[1] == ':') { op = p; p = pathname+2; c = *p; } else if(pathname[0] == c){ op = p; p = pathname; } } while(p) { q = strchr(p, c); if(q) { n = q-p; if(n == 0){ n = 1; /* leading "/" */ *p = '/'; /* don't emit "\" on windows */ } q++; } else { n = strlen(p); q = 0; } if(n) { Bputc(&obuf, ANAME); Bputc(&obuf, ANAME>>8); Bputc(&obuf, D_FILE); /* type */ Bputc(&obuf, 1); /* sym */ Bputc(&obuf, '<'); Bwrite(&obuf, p, n); Bputc(&obuf, 0); } p = q; if(p == 0 && op) { p = op; op = 0; } } g.offset = h->offset; Bputc(&obuf, AHISTORY); Bputc(&obuf, AHISTORY>>8); Bputc(&obuf, h->line); Bputc(&obuf, h->line>>8); Bputc(&obuf, h->line>>16); Bputc(&obuf, h->line>>24); zaddr(&nullgen, 0); zaddr(&g, 0); } } #include "../cc/lexbody" #include "../cc/macbody" #include "../cc/compat"