]> Cypherpunks repositories - gostls13.git/commitdiff
6l: do not link in objects from an archive just for init functions.
authorRuss Cox <rsc@golang.org>
Tue, 20 Jan 2009 23:36:43 +0000 (15:36 -0800)
committerRuss Cox <rsc@golang.org>
Tue, 20 Jan 2009 23:36:43 +0000 (15:36 -0800)
   (makes go libraries behave more like c libraries.)

R=r
DELTA=85  (67 added, 12 deleted, 6 changed)
OCL=23133
CL=23139

src/cmd/6l/go.c
src/cmd/6l/l.h
src/cmd/6l/obj.c
src/cmd/6l/pass.c

index 10ebe3fdbb39a36b72bca6cf93b264aaa36027ee..07a0f21d546ebc933ae4841bf5e11492484a3fa4 100644 (file)
@@ -489,3 +489,35 @@ definetypesigs(void)
        if(debug['v'])
                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;
+               }
+       }
+}
+
index e6ce0e7b2305a92db10729815125fcdae96335a8..4a2c456f2d63d66a2ddf4207312914121a2e2fd1 100644 (file)
@@ -112,12 +112,14 @@ struct    Sym
        short   version;
        short   become;
        short   frame;
+       ushort  file;
        uchar   subtype;
        uchar   dupok;
-       ushort  file;
+       uchar   reachable;
        vlong   value;
        int32   sig;
        Sym*    link;
+       Prog*   text;
 };
 struct Optab
 {
@@ -146,6 +148,7 @@ enum
        SFILE,
        SCONST,
        SUNDEF,
+       SOPT,
 
        SIMPORT,
        SEXPORT,
@@ -381,8 +384,10 @@ void       ckoff(Sym*, int32);
 Prog*  copyp(Prog*);
 double cputime(void);
 void   datblk(int32, int32);
+void   ignoreoptfuncs(void);
 void   definetypestrings(void);
 void definetypesigs(void);
+void   deadcode(void);
 void   diag(char*, ...);
 void   dodata(void);
 void   doinit(void);
@@ -415,6 +420,7 @@ void        main(int, char*[]);
 void   mkfwd(void);
 void*  mysbrk(uint32);
 Prog*  newdata(Sym*, int, int, int);
+Prog*  newtext(Prog*, Sym*);
 void   nuxiinit(void);
 void   objfile(char*);
 int    opsize(Prog*);
@@ -434,6 +440,7 @@ void        xdefine(char*, int, vlong);
 void   xfol(Prog*);
 void   zaddr(Biobuf*, Adr*, Sym*[]);
 void   zerosig(char*);
+int    isinitfunc(Sym*);
 
 void   machseg(char*, vlong, vlong, vlong, vlong, uint32, uint32, uint32, uint32);
 void   machsymseg(uint32, uint32);
index a250f1c45c747cb3a28180c0adff538392deccd3..d6af049d9ae73abbbd59536ba998ba4132a8abd8 100644 (file)
@@ -368,6 +368,8 @@ main(int argc, char *argv[])
                sprint(a, "%s/lib/lib_%s_%s.a", goroot, goarch, goos);
                objfile(a);
        }
+       ignoreoptfuncs();
+       // TODO(rsc): remove unused code and data
        definetypestrings();
        definetypesigs();
 
@@ -945,8 +947,11 @@ loop:
                if(debug['W'])
                        print(" ANAME   %s\n", s->name);
                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;
+                       if(isinitfunc(s))
+                               s->type = SOPT; // optional function; don't pull in an object file just for s.
+               }
                if(v == D_FILE) {
                        if(s->type != SFILE) {
                                histgen++;
@@ -1083,7 +1088,7 @@ loop:
 
        case ATEXT:
                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 */
                        if(debug['v'])
                                Bprint(&bso, "skipping: %s: redefinition: %s", pn, s->name);
@@ -1100,26 +1105,14 @@ loop:
                        diag("%s: no TEXT symbol: %P", pn, p);
                        errorexit();
                }
-               if(s->type != 0 && s->type != SXREF) {
+               if(s->type != 0 && s->type != SXREF && s->type != SOPT) {
                        if(p->from.scale & DUPOK) {
                                skip = 1;
                                goto casdef;
                        }
                        diag("%s: redefinition: %s\n%P", pn, s->name, p);
                }
-               s->type = STEXT;
-               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;
+               newtext(p, s);
                goto loop;
 
        case AMODE:
index e5316fe467998ae0d04fbd58e1b7db234c4f3477..45617ac5617b888773e7f465f56374703d5bb656 100644 (file)
@@ -398,7 +398,8 @@ patch(void)
                        q = q->link;
                }
                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->pcond = q;
@@ -853,6 +854,28 @@ newdata(Sym *s, int o, int w, int t)
        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
 export(void)
 {