From 04b08da9af0c450d645ab7389d1467308cfc2db8 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Mon, 4 Mar 2013 21:27:36 +0100 Subject: Imported Upstream version 1.1~hg20130304 --- src/cmd/5l/span.c | 107 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 30 deletions(-) (limited to 'src/cmd/5l/span.c') diff --git a/src/cmd/5l/span.c b/src/cmd/5l/span.c index 13e1848e1..a5afa02e7 100644 --- a/src/cmd/5l/span.c +++ b/src/cmd/5l/span.c @@ -90,16 +90,36 @@ span(void) int32 c, otxt, out[6]; Section *sect; uchar *bp; + Sym *sub; if(debug['v']) Bprint(&bso, "%5.2f span\n", cputime()); Bflush(&bso); + sect = addsection(&segtext, ".text", 05); + lookup("text", 0)->sect = sect; + lookup("etext", 0)->sect = sect; + bflag = 0; c = INITTEXT; otxt = c; for(cursym = textp; cursym != nil; cursym = cursym->next) { + cursym->sect = sect; p = cursym->text; + if(p == P || p->link == P) { // handle external functions and ELF section symbols + if(cursym->type & SSUB) + continue; + if(cursym->align != 0) + c = rnd(c, cursym->align); + cursym->value = 0; + for(sub = cursym; sub != S; sub = sub->sub) { + sub->value += c; + for(p = sub->text; p != P; p = p->link) + p->pc += sub->value; + } + c += cursym->size; + continue; + } p->pc = c; cursym->value = c; @@ -160,6 +180,8 @@ span(void) bflag = 0; c = INITTEXT; for(cursym = textp; cursym != nil; cursym = cursym->next) { + if(!cursym->text || !cursym->text->link) + continue; cursym->value = c; for(p = cursym->text; p != P; p = p->link) { curp = p; @@ -217,6 +239,8 @@ span(void) */ for(cursym = textp; cursym != nil; cursym = cursym->next) { p = cursym->text; + if(p == P || p->link == P) + continue; autosize = p->to.offset + 4; symgrow(cursym, cursym->size); @@ -235,7 +259,6 @@ span(void) } } } - sect = addsection(&segtext, ".text", 05); sect->vaddr = INITTEXT; sect->len = c - INITTEXT; } @@ -269,12 +292,20 @@ flushpool(Prog *p, int skip, int force) q->to.type = D_BRANCH; q->cond = p->link; q->link = blitrl; + q->line = p->line; blitrl = q; } else if(!force && (p->pc+pool.size-pool.start < 2048)) return 0; elitrl->link = p->link; p->link = blitrl; + // BUG(minux): how to correctly handle line number for constant pool entries? + // for now, we set line number to the last instruction preceding them at least + // this won't bloat the .debug_line tables + while(blitrl) { + blitrl->line = p->line; + blitrl = blitrl->link; + } blitrl = 0; /* BUG: should refer back to values until out-of-range */ elitrl = 0; pool.size = 0; @@ -299,9 +330,11 @@ addpool(Prog *p, Adr *a) switch(c) { default: t.to = *a; + if(flag_shared && t.to.sym != S) + t.pcrel = p; break; - case C_SROREG: + case C_SROREG: case C_LOREG: case C_ROREG: case C_FOREG: @@ -316,11 +349,13 @@ addpool(Prog *p, Adr *a) break; } - for(q = blitrl; q != P; q = q->link) /* could hash on t.t0.offset */ - if(memcmp(&q->to, &t.to, sizeof(t.to)) == 0) { - p->cond = q; - return; - } + if(t.pcrel == P) { + for(q = blitrl; q != P; q = q->link) /* could hash on t.t0.offset */ + if(q->pcrel == P && memcmp(&q->to, &t.to, sizeof(t.to)) == 0) { + p->cond = q; + return; + } + } q = prg(); *q = t; @@ -407,25 +442,9 @@ immhalf(int32 v) int32 symaddr(Sym *s) { - int32 v; - - v = s->value; - switch(s->type) { - default: - diag("unexpected type %d in symaddr(%s)", s->type, s->name); - return 0; - - case STEXT: - case SELFROSECT: - case SRODATA: - case SDATA: - case SBSS: - case SCONST: - case SNOPTRDATA: - case SNOPTRBSS: - break; - } - return v; + if(!s->reachable) + diag("unreachable symbol in symaddr - %s", s->name); + return s->value; } int @@ -444,6 +463,9 @@ aclass(Adr *a) case D_REGREG: return C_REGREG; + case D_REGREG2: + return C_REGREG2; + case D_SHIFT: return C_SHIFT; @@ -552,7 +574,10 @@ aclass(Adr *a) if(s == S) break; instoffset = 0; // s.b. unused but just in case - return C_LCON; + if(flag_shared) + return C_LCONADDR; + else + return C_LCON; case D_AUTO: instoffset = autosize + a->offset; @@ -718,8 +743,14 @@ buildop(void) for(i=0; i