else
doprof2();
span();
+ textaddress();
pclntab();
symtab();
dodata();
if(s->type == 0) {
s->type = SDATA;
adduint32(s, ieeedtof(&p->from.ieee));
- s->reachable = 1;
+ s->reachable = 0;
}
p->from.type = D_EXTERN;
p->from.sym = s;
s->type = SDATA;
adduint32(s, p->from.ieee.l);
adduint32(s, p->from.ieee.h);
- s->reachable = 1;
+ s->reachable = 0;
}
p->from.type = D_EXTERN;
p->from.sym = s;
if(s) {
if(debug['c'])
Bprint(&bso, "%s calls %s\n", TNAME, s->name);
- switch(s->type) {
- default:
+ if((s->type&~SSUB) != STEXT) {
/* diag prints TNAME first */
diag("undefined: %s", s->name);
s->type = STEXT;
s->value = vexit;
continue; // avoid more error messages
- case STEXT:
- p->to.offset = s->value;
- break;
}
+ if(s->text == nil)
+ continue;
p->to.type = D_BRANCH;
+ p->to.offset = s->text->pc;
+ p->pcond = s->text;
+ continue;
}
}
if(p->to.type != D_BRANCH)
continue;
c = p->to.offset;
- for(q = textp->text; q != P;) {
+ for(q = cursym->text; q != P;) {
if(c == q->pc)
break;
if(q->forwd != P && c >= q->forwd->pc)
q = q->link;
}
if(q == P) {
- diag("branch out of range in %s\n%P [%s]",
- TNAME, p, p->to.sym ? p->to.sym->name : "<nil>");
+ diag("branch out of range in %s (%#ux)\n%P [%s]",
+ TNAME, c, p, p->to.sym ? p->to.sym->name : "<nil>");
p->to.type = D_NONE;
}
p->pcond = q;
autoffset = 0;
deltasp = 0;
for(cursym = textp; cursym != nil; cursym = cursym->next) {
+ if(cursym->text == nil || cursym->text->link == nil)
+ continue;
+
p = cursym->text;
parsetextconst(p->to.offset);
autoffset = textstksiz;
{
Prog *p, *q;
int32 v;
- vlong c;
int n;
- Section *sect;
if(debug['v'])
Bprint(&bso, "%5.2f span\n", cputime());
}
span1(cursym);
}
-
- // Next, loop over symbols to assign actual PCs.
- // Could parallelize here too, by assigning to text
- // and then letting threads copy down, but probably not worth it.
- c = INITTEXT;
- sect = addsection(&segtext, ".text", 05);
- sect->vaddr = c;
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- cursym->value = c;
- for(p = cursym->text; p != P; p = p->link)
- p->pc += c;
- c += cursym->size;
- }
- sect->len = c - sect->vaddr;
}
void
// Could handle this case by making D_PCREL
// record the Prog* instead of the Sym*, but let's
// wait until the need arises.
- diag("call of non-TEXT");
+ diag("call of non-TEXT %P", q);
errorexit();
}
*andptr++ = op;
else
doprof2();
span();
+ textaddress();
pclntab();
symtab();
dodata();
if(s) {
if(debug['c'])
Bprint(&bso, "%s calls %s\n", TNAME, s->name);
- switch(s->type) {
- default:
+ if((s->type&~SSUB) != STEXT) {
/* diag prints TNAME first */
diag("undefined: %s", s->name);
s->type = STEXT;
s->value = vexit;
continue; // avoid more error messages
- case STEXT:
- p->to.offset = s->value;
- break;
}
+ if(s->text == nil)
+ continue;
p->to.type = D_BRANCH;
+ p->to.offset = s->text->pc;
+ p->pcond = s->text;
+ continue;
}
}
if(p->to.type != D_BRANCH)
continue;
c = p->to.offset;
- for(q = textp->text; q != P;) {
+ for(q = cursym->text; q != P;) {
if(c == q->pc)
break;
if(q->forwd != P && c >= q->forwd->pc)
q = q->link;
}
if(q == P) {
- diag("branch out of range in %s\n%P", TNAME, p);
+ diag("branch out of range in %s (%#ux)\n%P [%s]",
+ TNAME, c, p, p->to.sym ? p->to.sym->name : "<nil>");
p->to.type = D_NONE;
}
p->pcond = q;
}
for(cursym = textp; cursym != nil; cursym = cursym->next) {
+ if(cursym->text == nil || cursym->p != nil)
+ continue;
+
for(p = cursym->text; p != P; p = p->link) {
p->mark = 0; /* initialization for follow */
if(p->pcond != P) {
}
for(cursym = textp; cursym != nil; cursym = cursym->next) {
- p = cursym->text;
+ if(cursym->text == nil || cursym->text->link == nil)
+ continue;
+ p = cursym->text;
autoffset = p->to.offset;
if(autoffset < 0)
autoffset = 0;
for(i=0; i<NHASH; i++)
for(s = hash[i]; s != S; s = s->hash)
if(s->type == SXREF)
- diag("%s: not defined", s->name);
+ diag("%s(%d): not defined", s->name, s->version);
}
span(void)
{
Prog *p, *q;
- int32 v, c;
+ int32 v;
int n;
- Section *sect;
if(debug['v'])
Bprint(&bso, "%5.2f span\n", cputime());
// NOTE(rsc): If we get rid of the globals we should
// be able to parallelize these iterations.
for(cursym = textp; cursym != nil; cursym = cursym->next) {
+ if(cursym->text == nil || cursym->text->link == nil)
+ continue;
+
// TODO: move into span1
for(p = cursym->text; p != P; p = p->link) {
n = 0;
}
span1(cursym);
}
-
- // Next, loop over symbols to assign actual PCs.
- // Could parallelize here too, by assigning to text
- // and then letting threads copy down, but probably not worth it.
- c = INITTEXT;
- sect = addsection(&segtext, ".text", 05);
- sect->vaddr = c;
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- cursym->value = c;
- for(p = cursym->text; p != P; p = p->link)
- p->pc += c;
- c += cursym->size;
- }
- sect->len = c - sect->vaddr;
}
void
// Could handle this case by making D_PCREL
// record the Prog* instead of the Sym*, but let's
// wait until the need arises.
- diag("call of non-TEXT");
+ diag("call of non-TEXT %P", q);
errorexit();
}
*andptr++ = op;
cput(DW_LNE_set_address);
addrput(pc);
}
- if (!s->reachable)
+ if(s->text == nil)
continue;
if (unitstart < 0) {
if (s->version == 0)
newattr(dwfunc, DW_AT_external, DW_CLS_FLAG, 1, 0);
+ if(s->text->link == nil)
+ continue;
+
for(q = s->text; q != P; q = q->link) {
lh = searchhist(q->line);
if (lh == nil) {
for(cursym = textp; cursym != nil; cursym = cursym->next) {
s = cursym;
- if (!s->reachable)
+ if(s->text == nil)
continue;
fdeo = cpos();
extern int iself;
int elfwriteinterp(void);
void elfinterp(ElfShdr*, uint64, char*);
-void elfdynhash(int);
+void elfdynhash(void);
ElfPhdr* elfphload(Segment*);
ElfShdr* elfshbits(Section*);
void elfsetstring(char*, int);