diff options
Diffstat (limited to 'src/cmd/ld/go.c')
-rw-r--r-- | src/cmd/ld/go.c | 157 |
1 files changed, 33 insertions, 124 deletions
diff --git a/src/cmd/ld/go.c b/src/cmd/ld/go.c index 39ffa3d87..9c296b740 100644 --- a/src/cmd/ld/go.c +++ b/src/cmd/ld/go.c @@ -151,28 +151,11 @@ ldpkg(Biobuf *f, char *pkg, int64 len, char *filename, int whence) } loadpkgdata(filename, pkg, p0, p1 - p0); } - - // The __.PKGDEF archive summary has no local types. + + // __.PKGDEF has no cgo section - those are in the C compiler-generated object files. if(whence == Pkgdef) return; - // local types begin where exports end. - // skip rest of line after $$ we found above - p0 = p1 + 3; - while(*p0 != '\n' && *p0 != '\0') - p0++; - - // local types end at next \n$$. - p1 = strstr(p0, "\n$$"); - if(p1 == nil) { - fprint(2, "%s: cannot find end of local types in %s\n", argv0, filename); - if(debug['u']) - errorexit(); - return; - } - - loadpkgdata(filename, pkg, p0, p1 - p0); - // look for cgo section p0 = strstr(p1, "\n$$ // cgo"); if(p0 != nil) { @@ -228,39 +211,6 @@ loadpkgdata(char *file, char *pkg, char *data, int len) free(file); } -// replace all "". with pkg. -char* -expandpkg(char *t0, char *pkg) -{ - int n; - char *p; - char *w, *w0, *t; - - n = 0; - for(p=t0; (p=strstr(p, "\"\".")) != nil; p+=3) - n++; - - if(n == 0) - return estrdup(t0); - - // use malloc, not mal, so that caller can free - w0 = malloc(strlen(t0) + strlen(pkg)*n); - if(w0 == nil) { - diag("out of memory"); - errorexit(); - } - w = w0; - for(p=t=t0; (p=strstr(p, "\"\".")) != nil; p=t) { - memmove(w, t, p - t); - w += p-t; - strcpy(w, pkg); - w += strlen(pkg); - t = p+2; - } - strcpy(w, t); - return w0; -} - static int parsepkgdata(char *file, char *pkg, char **pp, char *ep, char **prefixp, char **namep, char **defp) { @@ -413,7 +363,7 @@ loadcgo(char *file, char *pkg, char *p, int n) char *pend, *next, *p0, *q; char *f[10], *local, *remote, *lib; int nf; - Sym *s; + LSym *s; USED(file); pend = p + n; @@ -459,7 +409,7 @@ loadcgo(char *file, char *pkg, char *p, int n) q = strchr(remote, '#'); if(q) *q++ = '\0'; - s = lookup(local, 0); + s = linklookup(ctxt, local, 0); if(local != f[1]) free(local); if(s->type == 0 || s->type == SXREF || s->type == SHOSTOBJ) { @@ -477,7 +427,7 @@ loadcgo(char *file, char *pkg, char *p, int n) if(nf != 2) goto err; local = f[1]; - s = lookup(local, 0); + s = linklookup(ctxt, local, 0); s->type = SHOSTOBJ; s->size = 0; continue; @@ -496,9 +446,9 @@ loadcgo(char *file, char *pkg, char *p, int n) else remote = local; local = expandpkg(local, pkg); - s = lookup(local, 0); + s = linklookup(ctxt, local, 0); - if(flag_shared && s == lookup("main", 0)) + if(flag_shared && s == linklookup(ctxt, "main", 0)) continue; // export overrides import, for openbsd/cgo. @@ -562,11 +512,11 @@ err: nerrors++; } -static Sym *markq; -static Sym *emarkq; +static LSym *markq; +static LSym *emarkq; static void -mark1(Sym *s, Sym *parent) +mark1(LSym *s, LSym *parent) { if(s == S || s->reachable) return; @@ -582,7 +532,7 @@ mark1(Sym *s, Sym *parent) } void -mark(Sym *s) +mark(LSym *s) { mark1(s, nil); } @@ -591,23 +541,22 @@ static void markflood(void) { Auto *a; - Prog *p; - Sym *s; + LSym *s; int i; for(s=markq; s!=S; s=s->queue) { - if(s->text) { + if(s->type == STEXT) { if(debug['v'] > 1) Bprint(&bso, "marktext %s\n", s->name); for(a=s->autom; a; a=a->link) mark1(a->gotype, s); - for(p=s->text; p != P; p=p->link) { - mark1(p->from.sym, s); - mark1(p->to.sym, s); - } } for(i=0; i<s->nr; i++) mark1(s->r[i].sym, s); + if(s->pcln) { + for(i=0; i<s->pcln->nfuncdata; i++) + mark1(s->pcln->funcdata[i], s); + } mark1(s->gotype, s); mark1(s->sub, s); mark1(s->outer, s); @@ -639,51 +588,19 @@ markextra[] = "_modu", }; -static int -isz(Auto *a) -{ - for(; a; a=a->link) - if(a->type == D_FILE || a->type == D_FILE1) - return 1; - return 0; -} - -static void -addz(Sym *s, Auto *z) -{ - Auto *a, *last; - - // strip out non-z - last = nil; - for(a = z; a != nil; a = a->link) { - if(a->type == D_FILE || a->type == D_FILE1) { - if(last == nil) - z = a; - else - last->link = a; - last = a; - } - } - if(last) { - last->link = s->autom; - s->autom = z; - } -} - void deadcode(void) { int i; - Sym *s, *last, *p; - Auto *z; + LSym *s, *last, *p; Fmt fmt; if(debug['v']) Bprint(&bso, "%5.2f deadcode\n", cputime()); - mark(lookup(INITENTRY, 0)); + mark(linklookup(ctxt, INITENTRY, 0)); for(i=0; i<nelem(markextra); i++) - mark(lookup(markextra[i], 0)); + mark(linklookup(ctxt, markextra[i], 0)); for(i=0; i<ndynexp; i++) mark(dynexp[i]); @@ -691,37 +608,29 @@ deadcode(void) markflood(); // keep each beginning with 'typelink.' if the symbol it points at is being kept. - for(s = allsym; s != S; s = s->allsym) { + for(s = ctxt->allsym; s != S; s = s->allsym) { if(strncmp(s->name, "go.typelink.", 12) == 0) s->reachable = s->nr==1 && s->r[0].sym->reachable; } // remove dead text but keep file information (z symbols). last = nil; - z = nil; - for(s = textp; s != nil; s = s->next) { - if(!s->reachable) { - if(isz(s->autom)) - z = s->autom; + for(s = ctxt->textp; s != nil; s = s->next) { + if(!s->reachable) continue; - } + // NOTE: Removing s from old textp and adding to new, shorter textp. if(last == nil) - textp = s; + ctxt->textp = s; else last->next = s; last = s; - if(z != nil) { - if(!isz(s->autom)) - addz(s, z); - z = nil; - } } if(last == nil) - textp = nil; + ctxt->textp = nil; else last->next = nil; - for(s = allsym; s != S; s = s->allsym) + for(s = ctxt->allsym; s != S; s = s->allsym) if(strncmp(s->name, "go.weak.", 8) == 0) { s->special = 1; // do not lay out in data segment s->reachable = 1; @@ -730,7 +639,7 @@ deadcode(void) // record field tracking references fmtstrinit(&fmt); - for(s = allsym; s != S; s = s->allsym) { + for(s = ctxt->allsym; s != S; s = s->allsym) { if(strncmp(s->name, "go.track.", 9) == 0) { s->special = 1; // do not lay out in data segment s->hide = 1; @@ -746,7 +655,7 @@ deadcode(void) } if(tracksym == nil) return; - s = lookup(tracksym, 0); + s = linklookup(ctxt, tracksym, 0); if(!s->reachable) return; addstrdata(tracksym, fmtstrflush(&fmt)); @@ -755,13 +664,13 @@ deadcode(void) void doweak(void) { - Sym *s, *t; + LSym *s, *t; // resolve weak references only if // target symbol will be in binary anyway. - for(s = allsym; s != S; s = s->allsym) { + for(s = ctxt->allsym; s != S; s = s->allsym) { if(strncmp(s->name, "go.weak.", 8) == 0) { - t = rlookup(s->name+8, s->version); + t = linkrlookup(ctxt, s->name+8, s->version); if(t && t->type != 0 && t->reachable) { s->value = t->value; s->type = t->type; @@ -784,7 +693,7 @@ addexport(void) return; for(i=0; i<ndynexp; i++) - adddynsym(dynexp[i]); + adddynsym(ctxt, dynexp[i]); } /* %Z from gc, for quoting import paths */ |