123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421 |
- #include "l.h"
- #define Dbufslop 100
- long
- entryvalue(void)
- {
- char *a;
- Sym *s;
- a = INITENTRY;
- if(*a >= '0' && *a <= '9')
- return atolwhex(a);
- s = lookup(a, 0);
- if(s->type == 0)
- return INITTEXT;
- if(s->type != STEXT && s->type != SLEAF)
- diag("entry not text: %s %d", s->name, s->type);
- return s->value;
- }
- void
- asmb(void)
- {
- Prog *p;
- long v;
- ulong *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;
- autosize = p->to.offset + 4;
- }
- if(p->pc != pc) {
- if(!debug['a'])
- print("%P\n", curp);
- diag("phase error %lux sb %lux in %s", p->pc, pc, TNAME);
- pc = p->pc;
- }
- curp = p;
- asmins(p);
- if(cbc < sizeof(and))
- cflush();
- if(debug['a']) {
- Bprint(&bso, pcstr, pc);
- for(op1 = and; op1 < andptr; op1++)
- Bprint(&bso, " %.8lux", *op1);
- Bprint(&bso, "\t%P\n", curp);
- }
- for(op1 = and; op1 < andptr; op1++) {
- v = *op1;
- cbp[0] = v;
- cbp[1] = v>>8;
- cbp[2] = v>>16;
- cbp[3] = v>>24;
- cbp += 4;
- pc += 4;
- cbc -= 4;
- }
- }
- cflush();
- switch(HEADTYPE) {
- default:
- diag("unknown header type %d", HEADTYPE);
- case 0:
- seek(cout, rnd(HEADR+textsize, 8192), 0);
- break;
- case 1:
- textsize = rnd(HEADR+textsize, 4096)-HEADR;
- seek(cout, textsize+HEADR, 0);
- break;
- case 2:
- seek(cout, HEADR+textsize, 0);
- break;
- case 3:
- seek(cout, HEADR+rnd(textsize, INITRND), 0);
- break;
- case 4:
- textsize = rnd(textsize, 4);
- seek(cout, textsize+HEADR, 0);
- break;
- }
- if(debug['v'])
- Bprint(&bso, "%5.2f datblk\n", cputime());
- Bflush(&bso);
- for(v = 0; v < datsize; v += sizeof(buf)-Dbufslop) {
- if(datsize-v > sizeof(buf)-Dbufslop)
- datblk(v, sizeof(buf)-Dbufslop);
- else
- datblk(v, datsize-v);
- }
- symsize = 0;
- lcsize = 0;
- if(!debug['s']) {
- if(debug['v'])
- Bprint(&bso, "%5.2f sym\n", cputime());
- Bflush(&bso);
- switch(HEADTYPE) {
- default:
- case 0:
- seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0);
- break;
- case 1:
- seek(cout, rnd(HEADR+textsize, INITRND)+datsize, 0);
- break;
- case 2:
- seek(cout, HEADR+textsize+datsize, 0);
- break;
- case 3:
- debug['s'] = 1;
- break;
- case 4:
- debug['s'] = 1;
- break;
- }
- if(!debug['s'])
- asmsym();
- if(debug['v'])
- Bprint(&bso, "%5.2f sp\n", cputime());
- Bflush(&bso);
- if(!debug['s'])
- asmlc();
- cflush();
- }
- if(debug['v'])
- Bprint(&bso, "%5.2f headr\n", cputime());
- Bflush(&bso);
- seek(cout, 0L, 0);
- switch(HEADTYPE) {
- default:
- case 0: /* garbage */
- 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: /* unix coff */
- case 4:
- /*
- * file header
- */
- if(HEADTYPE == 4)
- lputl(0x00020161); /* 2 sections, magic */
- else
- lputl(0x0002014c); /* 2 sections, magic */
- lputl(0); /* unix time stamp */
- lputl(0); /* symbol table */
- lputl(0); /* nsyms */
- lputl(0x00030020); /* flags, sizeof a.out header */
- /*
- * a.out header
- */
- lputl(0x10b); /* magic, version stamp */
- lputl(rnd(textsize, INITRND)); /* text sizes */
- lputl(datsize); /* data sizes */
- lputl(bsssize); /* bss sizes */
- lput(entryvalue()); /* va of entry */
- lputl(INITTEXT); /* text start */
- lputl(INITDAT); /* data start */
- lputl(0); /* tag entries */
- /*
- * text section header
- */
- s8put(".text");
- lputl(INITTEXT); /* pa */
- lputl(INITTEXT); /* va */
- lputl(textsize); /* text size */
- lputl(HEADR); /* file offset */
- lputl(0); /* relocation */
- lputl(0); /* line numbers */
- lputl(0); /* relocation, line numbers */
- lputl(0x20); /* flags text only */
- lputl(0); /* alignment */
- /*
- * data section header
- */
- s8put(".data");
- lputl(INITDAT); /* pa */
- lputl(INITDAT); /* va */
- lputl(datsize); /* data size */
- lputl(HEADR+textsize); /* file offset */
- lputl(0); /* relocation */
- lputl(0); /* line numbers */
- lputl(0); /* relocation, line numbers */
- lputl(0x40); /* flags data only */
- lputl(0); /* alignment */
- break;
- case 2: /* plan9 */
- lput(4*12*12+7); /* magic */
- lput(textsize); /* sizes */
- lput(datsize);
- lput(bsssize);
- lput(symsize); /* nsyms */
- lput(entryvalue()); /* va of entry */
- lput(0); /* sp offsets */
- lput(lcsize); /* line offsets */
- break;
- case 3:
- /* msdos boot */
- break;
- }
- cflush();
- }
- void
- lput(long l)
- {
- CPUT(l>>24)
- CPUT(l>>16)
- CPUT(l>>8)
- CPUT(l)
- }
- void
- lputl(long l)
- {
- CPUT(l)
- CPUT(l>>8)
- CPUT(l>>16)
- CPUT(l>>24)
- }
- void
- s8put(char *n)
- {
- char name[8];
- int i;
- strncpy(name, n, sizeof(name));
- for(i=0; i<sizeof(name); i++)
- CPUT(name[i])
- }
- void
- cflush(void)
- {
- int n;
- n = sizeof(buf.cbuf) - cbc;
- if(n)
- write(cout, buf.cbuf, n);
- cbp = buf.cbuf;
- cbc = sizeof(buf.cbuf);
- }
- void
- datblk(long s, long n)
- {
- Prog *p;
- char *cast;
- long l, fl, j;
- int i, c;
- memset(buf.dbuf, 0, n+Dbufslop);
- for(p = datap; p != P; p = p->link) {
- curp = p;
- l = p->from.sym->value + p->from.offset - s;
- c = p->from.scale;
- i = 0;
- if(l < 0) {
- if(l+c <= 0)
- continue;
- while(l < 0) {
- l++;
- i++;
- }
- }
- if(l >= n)
- continue;
- for(j=l+(c-i)-1; j>=l; j--)
- if(buf.dbuf[j]) {
- print("%P\n", p);
- diag("multiple initialization");
- break;
- }
- switch(p->to.type) {
- case D_FCONST:
- switch(c) {
- default:
- case 4:
- fl = ieeedtof(&p->to.ieee);
- cast = (char*)&fl;
- if(debug['a'] && i == 0) {
- Bprint(&bso, pcstr, l+s+INITDAT);
- for(j=0; j<c; j++)
- Bprint(&bso, "%.2ux", cast[fnuxi4[j]] & 0xff);
- Bprint(&bso, "\t%P\n", curp);
- }
- for(; i<c; i++) {
- buf.dbuf[l] = cast[fnuxi4[i]];
- l++;
- }
- break;
- case 8:
- cast = (char*)&p->to.ieee;
- if(debug['a'] && i == 0) {
- Bprint(&bso, pcstr, l+s+INITDAT);
- for(j=0; j<c; j++)
- Bprint(&bso, "%.2ux", cast[fnuxi8[j]] & 0xff);
- Bprint(&bso, "\t%P\n", curp);
- }
- for(; i<c; i++) {
- buf.dbuf[l] = cast[fnuxi8[i]];
- l++;
- }
- break;
- }
- break;
- case D_SCONST:
- if(debug['a'] && i == 0) {
- Bprint(&bso, pcstr, l+s+INITDAT);
- for(j=0; j<c; j++)
- Bprint(&bso, "%.2ux", p->to.scon[j] & 0xff);
- Bprint(&bso, "\t%P\n", curp);
- }
- for(; i<c; i++) {
- buf.dbuf[l] = p->to.scon[i];
- l++;
- }
- break;
- default:
- fl = p->to.offset;
- if(p->to.type == D_ADDR) {
- if(p->to.index != D_STATIC && p->to.index != D_EXTERN)
- diag("DADDR type%P", p);
- if(p->to.sym) {
- fl += p->to.sym->value;
- if(p->to.sym->type != STEXT && p->to.sym->type != SLEAF)
- fl += INITDAT;
- }
- }
- cast = (char*)&fl;
- switch(c) {
- default:
- diag("bad nuxi %d %d\n%P", c, i, curp);
- break;
- case 1:
- if(debug['a'] && i == 0) {
- Bprint(&bso, pcstr, l+s+INITDAT);
- for(j=0; j<c; j++)
- Bprint(&bso, "%.2ux", cast[inuxi1[j]] & 0xff);
- Bprint(&bso, "\t%P\n", curp);
- }
- for(; i<c; i++) {
- buf.dbuf[l] = cast[inuxi1[i]];
- l++;
- }
- break;
- case 2:
- if(debug['a'] && i == 0) {
- Bprint(&bso, pcstr, l+s+INITDAT);
- for(j=0; j<c; j++)
- Bprint(&bso, "%.2ux", cast[inuxi2[j]] & 0xff);
- Bprint(&bso, "\t%P\n", curp);
- }
- for(; i<c; i++) {
- buf.dbuf[l] = cast[inuxi2[i]];
- l++;
- }
- break;
- case 4:
- if(debug['a'] && i == 0) {
- Bprint(&bso, pcstr, l+s+INITDAT);
- for(j=0; j<c; j++)
- Bprint(&bso, "%.2ux", cast[inuxi4[j]] & 0xff);
- Bprint(&bso, "\t%P\n", curp);
- }
- for(; i<c; i++) {
- buf.dbuf[l] = cast[inuxi4[i]];
- l++;
- }
- break;
- }
- break;
- }
- }
- write(cout, buf.dbuf, n);
- }
- long
- rnd(long v, long r)
- {
- long c;
- if(r <= 0)
- return v;
- v += r - 1;
- c = v % r;
- if(c < 0)
- c += r;
- v -= c;
- return v;
- }
|