diff --git a/src/cmd/5l/asm.c b/src/cmd/5l/asm.c index 4d9264c9140..0b38e0b29b5 100644 --- a/src/cmd/5l/asm.c +++ b/src/cmd/5l/asm.c @@ -291,13 +291,11 @@ phsh(Elf64_Phdr *ph, Elf64_Shdr *sh) void asmb(void) { - Prog *p; int32 t; int a, dynsym; uint32 va, fo, w, symo, startva; uint32 symdatva = SYMDATVA; int strtabsize; - Optab *o; ElfEhdr *eh; ElfPhdr *ph, *pph; ElfShdr *sh; @@ -312,28 +310,8 @@ asmb(void) OFFSET = HEADR; seek(cout, OFFSET, 0); pc = INITTEXT; - for(cursym = textp; cursym != nil; cursym = cursym->next) { - for(p = cursym->text; p != P; p = p->link) { - setarch(p); - if(p->as == ATEXT) - autosize = p->to.offset + 4; - if(p->pc != pc) { - diag("phase error %ux sb %ux", - p->pc, pc); - if(!debug['a']) - prasm(curp); - pc = p->pc; - } - curp = p; - o = oplook(p); /* could probably avoid this call */ - if(thumb) - thumbasmout(p, o); - else - asmout(p, o); - pc += o->size; - } - } - cflush(); + codeblk(pc, segtext.sect->len); + pc += segtext.sect->len; if(seek(cout, 0, 1) != pc - segtext.vaddr + segtext.fileoff) diag("text phase error"); @@ -846,10 +824,11 @@ asmthumbmap(void) } void -asmout(Prog *p, Optab *o) +asmout(Prog *p, Optab *o, int32 *out) { int32 o1, o2, o3, o4, o5, o6, v; int r, rf, rt, rt2; + Reloc *rel; PP = p; o1 = 0; @@ -991,6 +970,15 @@ if(debug['G']) print("%ux: %s: arm %d %d %d %d\n", (uint32)(p->pc), p->from.sym- case 11: /* word */ aclass(&p->to); o1 = instoffset; + if(p->to.sym != S) { + rel = addrel(cursym); + rel->off = pc - cursym->value; + rel->siz = 4; + rel->type = D_ADDR; + rel->sym = p->to.sym; + rel->add = p->to.offset; + o1 = 0; + } break; case 12: /* movw $lcon, reg */ @@ -1588,6 +1576,14 @@ if(debug['G']) print("%ux: %s: arm %d %d %d %d\n", (uint32)(p->pc), p->from.sym- o1 |= (p->scond & C_SCOND) << 28; break; } + + out[0] = o1; + out[1] = o2; + out[2] = o3; + out[3] = o4; + out[4] = o5; + out[5] = o6; + return; v = p->pc; switch(o->size) { diff --git a/src/cmd/5l/l.h b/src/cmd/5l/l.h index 1e720f3bea5..4f7ec522356 100644 --- a/src/cmd/5l/l.h +++ b/src/cmd/5l/l.h @@ -379,7 +379,7 @@ void addhist(int32, int); Prog* appendp(Prog*); void asmb(void); void asmthumbmap(void); -void asmout(Prog*, Optab*); +void asmout(Prog*, Optab*, int32*); void thumbasmout(Prog*, Optab*); void asmsym(void); int32 atolwhex(char*); diff --git a/src/cmd/5l/obj.c b/src/cmd/5l/obj.c index 6392d93ca81..5a508b4f4aa 100644 --- a/src/cmd/5l/obj.c +++ b/src/cmd/5l/obj.c @@ -70,7 +70,7 @@ main(int argc, char *argv[]) { int c, i; -debug['s'] = 1; +//debug['s'] = 1; // qemu cannot handle symdat load Binit(&bso, 1, OWRITE); cout = -1; listinit(); diff --git a/src/cmd/5l/span.c b/src/cmd/5l/span.c index 3a1c35b62d8..048a4768b63 100644 --- a/src/cmd/5l/span.c +++ b/src/cmd/5l/span.c @@ -166,11 +166,12 @@ span(void) { Prog *p, *op; Optab *o; - int m, bflag; - int32 c, otxt; + int m, bflag, i, v; + int32 c, otxt, out[6]; int lastthumb = -1; Section *rosect, *sect; Sym *sym; + uchar *bp; if(debug['v']) Bprint(&bso, "%5.2f span\n", cputime()); @@ -187,11 +188,8 @@ span(void) p = cursym->text; setarch(p); p->pc = c; + cursym->value = c; - if(blitrl && lastthumb != -1 && lastthumb != thumb){ // flush literal pool - if(flushpool(op, 0, 1)) - c = p->pc = scan(op, p, c); - } lastthumb = thumb; autosize = p->to.offset + 4; if(p->from.sym != S) @@ -216,8 +214,6 @@ span(void) c = p->pc = scan(op, p, c); } if(m == 0) { - if(p->as == ATEXT) { - } diag("zero-width instruction\n%P", p); continue; } @@ -237,12 +233,13 @@ span(void) flushpool(p, 0, 0); c += m; } - if(blitrl && cursym->next == nil){ + if(blitrl){ if(thumb && isbranch(op)) pool.extra += brextra(op); if(checkpool(op, 0)) c = scan(op, P, c); } + cursym->size = c - cursym->value; } /* @@ -257,6 +254,7 @@ span(void) bflag = 0; c = INITTEXT; for(cursym = textp; cursym != nil; cursym = cursym->next) { + cursym->value = c; for(p = cursym->text; p != P; p = p->link) { setarch(p); p->pc = c; @@ -299,6 +297,7 @@ span(void) } c += m; } + cursym->size = c - cursym->value; } } @@ -318,6 +317,7 @@ span(void) oop = op = nil; again = 0; for(cursym = textp; cursym != nil; cursym = cursym->next) { + cursym->value = c; for(p = cursym->text; p != P; oop = op, op = p, p = p->link) { setarch(p); if(p->pc != c) @@ -361,6 +361,7 @@ span(void) } c += m; } + cursym->size = c - cursym->value; } if(c != lastc || again){ lastc = c; @@ -368,12 +369,39 @@ span(void) } } c = rnd(c, 8); - xdefine("etext", STEXT, c); - for(cursym = textp; cursym != nil; cursym = cursym->next) - cursym->value = cursym->text->pc; textsize = c - INITTEXT; + /* + * lay out the code. all the pc-relative code references, + * even cross-function, are resolved now; + * only data references need to be relocated. + * with more work we could leave cross-function + * code references to be relocated too, and then + * perhaps we'd be able to parallelize the span loop above. + */ + for(cursym = textp; cursym != nil; cursym = cursym->next) { + p = cursym->text; + setarch(p); + autosize = p->to.offset + 4; + symgrow(cursym, cursym->size); + + bp = cursym->p; + for(p = p->link; p != P; p = p->link) { + pc = p->pc; + curp = p; + o = oplook(p); + asmout(p, o, out); + for(i=0; isize/4; i++) { + v = out[i]; + *bp++ = v; + *bp++ = v>>8; + *bp++ = v>>16; + *bp++ = v>>24; + } + } + } + rosect = segtext.sect->next; if(rosect) { if(INITRND)