123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #include "l.h"
- #define Dbufslop 100
- #define PADDR(a) ((a) & ~0xfffffffff0000000ull)
- int64_t
- 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;
- switch(s->type) {
- case STEXT:
- break;
- case SDATA:
- if(dlm)
- return s->value+INITDAT;
- default:
- diag("entry not text: %s", s->name);
- }
- return s->value;
- }
- /* these need to take long arguments to be compatible with elf.c */void
- wputl(int32_t w)
- {
- cput(w);
- cput(w>>8);
- }
- void
- wput(int32_t w)
- {
- cput(w>>8);
- cput(w);
- }
- void
- lput(int32_t l)
- {
- cput(l>>24);
- cput(l>>16);
- cput(l>>8);
- cput(l);
- }
- void
- llput(int64_t v)
- {
- lput(v>>32);
- lput(v);
- }
- void
- lputl(int32_t l)
- {
- cput(l);
- cput(l>>8);
- cput(l>>16);
- cput(l>>24);
- }
- void
- llputl(int64_t v)
- {
- lputl(v);
- lputl(v>>32);
- }
- void
- strnput(char *s, int n)
- {
- for(; *s && n > 0; s++){
- cput(*s);
- n--;
- }
- while(n > 0){
- cput(0);
- n--;
- }
- }
- void
- asmb(void)
- {
- Prog *p;
- int32_t v, magic;
- int a;
- uint8_t *op1;
- int64_t vl;
- 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 %llux sb %llux in %s", p->pc, pc, TNAME);
- pc = p->pc;
- }
- curp = p;
- asmins(p);
- a = (andptr - and);
- if(cbc < a)
- cflush();
- if(debug['a']) {
- Bprint(&bso, pcstr, pc);
- for(op1 = and; op1 < andptr; op1++)
- Bprint(&bso, "%.2ux", *op1 & 0xff);
- Bprint(&bso, "\t%P\n", curp);
- }
- if(dlm) {
- if(p->as == ATEXT)
- reloca = nil;
- else if(reloca != nil)
- diag("reloc failure: %P", curp);
- }
- memmove(cbp, and, a);
- cbp += a;
- pc += a;
- cbc -= a;
- }
- cflush();
- switch(HEADTYPE) {
- default:
- diag("unknown header type %ld", HEADTYPE);
- case 2:
- case 5:
- case 6:
- seek(cout, HEADR+textsize, 0);
- break;
- }
- if(debug['v'])
- Bprint(&bso, "%5.2f datblk\n", cputime());
- Bflush(&bso);
- if(dlm){
- char buf[8];
- write(cout, buf, INITDAT-textsize);
- textsize = INITDAT;
- }
- 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;
- spsize = 0;
- lcsize = 0;
- if(!debug['s']) {
- if(debug['v'])
- Bprint(&bso, "%5.2f sym\n", cputime());
- Bflush(&bso);
- switch(HEADTYPE) {
- default:
- case 2:
- case 5:
- case 6:
- seek(cout, HEADR+textsize+datsize, 0);
- break;
- }
- if(!debug['s'])
- asmsym();
- if(debug['v'])
- Bprint(&bso, "%5.2f sp\n", cputime());
- Bflush(&bso);
- if(debug['v'])
- Bprint(&bso, "%5.2f pc\n", cputime());
- Bflush(&bso);
- if(!debug['s'])
- asmlc();
- if(dlm)
- asmdyn();
- cflush();
- }
- else if(dlm){
- seek(cout, HEADR+textsize+datsize, 0);
- asmdyn();
- cflush();
- }
- if(debug['v'])
- Bprint(&bso, "%5.2f headr\n", cputime());
- Bflush(&bso);
- seek(cout, 0L, 0);
- switch(HEADTYPE) {
- default:
- case 2: /* plan9 */
- magic = 4*26*26+7;
- magic |= 0x00008000; /* fat header */
- if(dlm)
- magic |= 0x80000000; /* dlm */
- lput(magic); /* magic */
- lput(textsize); /* sizes */
- lput(datsize);
- lput(bsssize);
- lput(symsize); /* nsyms */
- vl = entryvalue();
- lput(PADDR(vl)); /* va of entry */
- lput(spsize); /* sp offsets */
- lput(lcsize); /* line offsets */
- llput(vl); /* va of entry */
- break;
- case 5:
- elf32(debug['8']? I386: AMD64, ELFDATA2LSB, 0, nil);
- break;
- case 6:
- elf64(AMD64, ELFDATA2LSB, 0, nil);
- break;
- }
- cflush();
- }
- 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(int32_t s, int32_t n)
- {
- Prog *p;
- uint8_t *cast;
- int32_t l, fl, j;
- int64_t o;
- 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;
- if(p->as != AINIT && p->as != ADYNT) {
- 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 = (uint8_t*)&fl;
- if(debug['a'] && i == 0) {
- Bprint(&bso, pcstr, l+s+INITDAT);
- for(j=0; j<c; j++)
- Bprint(&bso, "%.2ux", cast[fnuxi4[j]]);
- Bprint(&bso, "\t%P\n", curp);
- }
- for(; i<c; i++) {
- buf.dbuf[l] = cast[fnuxi4[i]];
- l++;
- }
- break;
- case 8:
- cast = (uint8_t*)&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]]);
- 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:
- o = 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) {
- if(p->to.sym->type == SUNDEF)
- ckoff(p->to.sym, o);
- o += p->to.sym->value;
- if(p->to.sym->type != STEXT && p->to.sym->type != SUNDEF)
- o += INITDAT;
- if(dlm)
- dynreloc(p->to.sym, l+s+INITDAT, 1);
- }
- }
- fl = o;
- cast = (uint8_t*)&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]]);
- 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]]);
- 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]]);
- Bprint(&bso, "\t%P\n", curp);
- }
- for(; i<c; i++) {
- buf.dbuf[l] = cast[inuxi4[i]];
- l++;
- }
- break;
- case 8:
- cast = (uint8_t*)&o;
- if(debug['a'] && i == 0) {
- Bprint(&bso, pcstr, l+s+INITDAT);
- for(j=0; j<c; j++)
- Bprint(&bso, "%.2ux", cast[inuxi8[j]]);
- Bprint(&bso, "\t%P\n", curp);
- }
- for(; i<c; i++) {
- buf.dbuf[l] = cast[inuxi8[i]];
- l++;
- }
- break;
- }
- break;
- }
- }
- write(cout, buf.dbuf, n);
- }
- int64_t
- rnd(int64_t v, int64_t r)
- {
- int64_t c;
- if(r <= 0)
- return v;
- v += r - 1;
- c = v % r;
- if(c < 0)
- c += r;
- v -= c;
- return v;
- }
|