Commit a3c4faf8 authored by Russ Cox's avatar Russ Cox

6l: do not link in objects from an archive just for init functions.

   (makes go libraries behave more like c libraries.)

R=r
DELTA=85  (67 added, 12 deleted, 6 changed)
OCL=23133
CL=23139
parent 96c20204
...@@ -489,3 +489,35 @@ definetypesigs(void) ...@@ -489,3 +489,35 @@ definetypesigs(void)
if(debug['v']) if(debug['v'])
Bprint(&bso, "%5.2f typesigs %d\n", cputime(), n); Bprint(&bso, "%5.2f typesigs %d\n", cputime(), n);
} }
int
isinitfunc(Sym *s)
{
char *p;
p = utfrune(s->name, 0xb7); // 0xb7 = '·'
if(p == nil)
return 0;
if(memcmp(p, "·Init·", 8) == 0 || memcmp(p, "·init·", 8) == 0)
return 1;
return 0;
}
void
ignoreoptfuncs(void)
{
Prog *p;
// nop out calls to optional functions
// that were not pulled in from libraries.
for(p=firstp; p != P; p=p->link) {
if(p->to.sym != S && p->to.sym->type == SOPT) {
if(p->as != ACALL)
diag("bad use of optional function: %P", p);
p->as = ANOP;
p->from.type = D_NONE;
p->to.type = D_NONE;
}
}
}
...@@ -112,12 +112,14 @@ struct Sym ...@@ -112,12 +112,14 @@ struct Sym
short version; short version;
short become; short become;
short frame; short frame;
ushort file;
uchar subtype; uchar subtype;
uchar dupok; uchar dupok;
ushort file; uchar reachable;
vlong value; vlong value;
int32 sig; int32 sig;
Sym* link; Sym* link;
Prog* text;
}; };
struct Optab struct Optab
{ {
...@@ -146,6 +148,7 @@ enum ...@@ -146,6 +148,7 @@ enum
SFILE, SFILE,
SCONST, SCONST,
SUNDEF, SUNDEF,
SOPT,
SIMPORT, SIMPORT,
SEXPORT, SEXPORT,
...@@ -381,8 +384,10 @@ void ckoff(Sym*, int32); ...@@ -381,8 +384,10 @@ void ckoff(Sym*, int32);
Prog* copyp(Prog*); Prog* copyp(Prog*);
double cputime(void); double cputime(void);
void datblk(int32, int32); void datblk(int32, int32);
void ignoreoptfuncs(void);
void definetypestrings(void); void definetypestrings(void);
void definetypesigs(void); void definetypesigs(void);
void deadcode(void);
void diag(char*, ...); void diag(char*, ...);
void dodata(void); void dodata(void);
void doinit(void); void doinit(void);
...@@ -415,6 +420,7 @@ void main(int, char*[]); ...@@ -415,6 +420,7 @@ void main(int, char*[]);
void mkfwd(void); void mkfwd(void);
void* mysbrk(uint32); void* mysbrk(uint32);
Prog* newdata(Sym*, int, int, int); Prog* newdata(Sym*, int, int, int);
Prog* newtext(Prog*, Sym*);
void nuxiinit(void); void nuxiinit(void);
void objfile(char*); void objfile(char*);
int opsize(Prog*); int opsize(Prog*);
...@@ -434,6 +440,7 @@ void xdefine(char*, int, vlong); ...@@ -434,6 +440,7 @@ void xdefine(char*, int, vlong);
void xfol(Prog*); void xfol(Prog*);
void zaddr(Biobuf*, Adr*, Sym*[]); void zaddr(Biobuf*, Adr*, Sym*[]);
void zerosig(char*); void zerosig(char*);
int isinitfunc(Sym*);
void machseg(char*, vlong, vlong, vlong, vlong, uint32, uint32, uint32, uint32); void machseg(char*, vlong, vlong, vlong, vlong, uint32, uint32, uint32, uint32);
void machsymseg(uint32, uint32); void machsymseg(uint32, uint32);
......
...@@ -368,6 +368,8 @@ main(int argc, char *argv[]) ...@@ -368,6 +368,8 @@ main(int argc, char *argv[])
sprint(a, "%s/lib/lib_%s_%s.a", goroot, goarch, goos); sprint(a, "%s/lib/lib_%s_%s.a", goroot, goarch, goos);
objfile(a); objfile(a);
} }
ignoreoptfuncs();
// TODO(rsc): remove unused code and data
definetypestrings(); definetypestrings();
definetypesigs(); definetypesigs();
...@@ -945,8 +947,11 @@ loop: ...@@ -945,8 +947,11 @@ loop:
if(debug['W']) if(debug['W'])
print(" ANAME %s\n", s->name); print(" ANAME %s\n", s->name);
h[o] = s; h[o] = s;
if((v == D_EXTERN || v == D_STATIC) && s->type == 0) if((v == D_EXTERN || v == D_STATIC) && s->type == 0) {
s->type = SXREF; s->type = SXREF;
if(isinitfunc(s))
s->type = SOPT; // optional function; don't pull in an object file just for s.
}
if(v == D_FILE) { if(v == D_FILE) {
if(s->type != SFILE) { if(s->type != SFILE) {
histgen++; histgen++;
...@@ -1083,7 +1088,7 @@ loop: ...@@ -1083,7 +1088,7 @@ loop:
case ATEXT: case ATEXT:
s = p->from.sym; s = p->from.sym;
if(ntext++ == 0 && s->type != 0 && s->type != SXREF) { if(ntext++ == 0 && s->type != 0 && s->type != SXREF && s->type != SOPT) {
/* redefinition, so file has probably been seen before */ /* redefinition, so file has probably been seen before */
if(debug['v']) if(debug['v'])
Bprint(&bso, "skipping: %s: redefinition: %s", pn, s->name); Bprint(&bso, "skipping: %s: redefinition: %s", pn, s->name);
...@@ -1100,26 +1105,14 @@ loop: ...@@ -1100,26 +1105,14 @@ loop:
diag("%s: no TEXT symbol: %P", pn, p); diag("%s: no TEXT symbol: %P", pn, p);
errorexit(); errorexit();
} }
if(s->type != 0 && s->type != SXREF) { if(s->type != 0 && s->type != SXREF && s->type != SOPT) {
if(p->from.scale & DUPOK) { if(p->from.scale & DUPOK) {
skip = 1; skip = 1;
goto casdef; goto casdef;
} }
diag("%s: redefinition: %s\n%P", pn, s->name, p); diag("%s: redefinition: %s\n%P", pn, s->name, p);
} }
s->type = STEXT; newtext(p, s);
s->value = pc;
lastp->link = p;
lastp = p;
p->pc = pc;
pc++;
if(textp == P) {
textp = p;
etextp = p;
goto loop;
}
etextp->pcond = p;
etextp = p;
goto loop; goto loop;
case AMODE: case AMODE:
......
...@@ -398,7 +398,8 @@ patch(void) ...@@ -398,7 +398,8 @@ patch(void)
q = q->link; q = q->link;
} }
if(q == P) { if(q == P) {
diag("branch out of range in %s\n%P", TNAME, p); diag("branch out of range in %s\n%P [%s]",
TNAME, p, p->to.sym ? p->to.sym->name : "<nil>");
p->to.type = D_NONE; p->to.type = D_NONE;
} }
p->pcond = q; p->pcond = q;
...@@ -853,6 +854,28 @@ newdata(Sym *s, int o, int w, int t) ...@@ -853,6 +854,28 @@ newdata(Sym *s, int o, int w, int t)
return p; return p;
} }
Prog*
newtext(Prog *p, Sym *s)
{
if(p == P) {
p = prg();
p->as = ATEXT;
p->from.sym = s;
}
s->type = STEXT;
s->text = p;
s->value = pc;
lastp->link = p;
lastp = p;
p->pc = pc++;
if(textp == P)
textp = p;
else
etextp->pcond = p;
etextp = p;
return p;
}
void void
export(void) export(void)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment