diff --git a/src/cmd/5l/l.h b/src/cmd/5l/l.h index e3ca88a943..86885b421a 100644 --- a/src/cmd/5l/l.h +++ b/src/cmd/5l/l.h @@ -320,7 +320,6 @@ EXTERN int32 elfdatsize; EXTERN char debug[128]; EXTERN Sym* etextp; EXTERN char* noname; -EXTERN int xrefresolv; EXTERN Prog* lastp; EXTERN int32 lcsize; EXTERN char literal[32]; diff --git a/src/cmd/6l/l.h b/src/cmd/6l/l.h index ae40d135be..4f56fe983f 100644 --- a/src/cmd/6l/l.h +++ b/src/cmd/6l/l.h @@ -328,7 +328,6 @@ EXTERN char debug[128]; EXTERN char literal[32]; EXTERN Sym* textp; EXTERN Sym* etextp; -EXTERN int xrefresolv; EXTERN char ycover[Ymax*Ymax]; EXTERN uchar* andptr; EXTERN uchar* rexptr; diff --git a/src/cmd/8l/l.h b/src/cmd/8l/l.h index 8545641c0f..0049c3f1f3 100644 --- a/src/cmd/8l/l.h +++ b/src/cmd/8l/l.h @@ -292,7 +292,6 @@ EXTERN char debug[128]; EXTERN char literal[32]; EXTERN Sym* etextp; EXTERN Prog* firstp; -EXTERN int xrefresolv; EXTERN uchar ycover[Ymax*Ymax]; EXTERN uchar* andptr; EXTERN uchar and[100]; diff --git a/src/cmd/ld/lib.c b/src/cmd/ld/lib.c index cb1d6deaf8..43cff969c8 100644 --- a/src/cmd/ld/lib.c +++ b/src/cmd/ld/lib.c @@ -147,6 +147,22 @@ addlib(char *src, char *obj) strcat(name, comp); } cleanname(name); + + // runtime.a -> runtime + p = nil; + if(strlen(name) > 2 && name[strlen(name)-2] == '.') { + p = name+strlen(name)-2; + *p = '\0'; + } + + // already loaded? + for(i=0; i runtime.a for search + if(p != nil) + *p = '.'; if(search) { // try dot, -L "libdir", and then goroot. @@ -160,8 +176,8 @@ addlib(char *src, char *obj) cleanname(pname); /* runtime.a -> runtime */ - if(strlen(name) > 2 && name[strlen(name)-2] == '.') - name[strlen(name)-2] = '\0'; + if(p != nil) + *p = '\0'; if(debug['v']) Bprint(&bso, "%5.2f addlib: %s %s pulls in %s\n", cputime(), obj, src, pname); @@ -187,9 +203,9 @@ addlibpath(char *srcref, char *objref, char *file, char *pkg) if(strcmp(file, library[i].file) == 0) return; - if(debug['v']) + if(debug['v'] > 1) Bprint(&bso, "%5.2f addlibpath: srcref: %s objref: %s file: %s pkg: %s\n", - cputime(), srcref, objref, file, pkg); + cputime(), srcref, objref, file, pkg); if(libraryp == nlibrary){ nlibrary = 50 + 2*libraryp; @@ -220,8 +236,6 @@ loadlib(void) { char pname[1024]; int i, found; - int32 h; - Sym *s; found = 0; for(i=0; ihash) - if(s->type == SXREF) - goto loop; +/* + * look for the next file in an archive. + * adapted from libmach. + */ +int +nextar(Biobuf *bp, int off, struct ar_hdr *a) +{ + int r; + int32 arsize; + if (off&01) + off++; + Bseek(bp, off, 0); + r = Bread(bp, a, SAR_HDR); + if(r != SAR_HDR) + return 0; + if(strncmp(a->fmag, ARFMAG, sizeof(a->fmag))) + return -1; + arsize = strtol(a->size, 0, 0); + if (arsize&1) + arsize++; + return arsize + SAR_HDR; } void objfile(char *file, char *pkg) { - int32 off, esym, cnt, l; - int work; + int32 off, l; Biobuf *f; - Sym *s; char magbuf[SARMAG]; - char name[100], pname[150]; + char pname[150]; struct ar_hdr arhdr; - char *e, *start, *stop, *x; pkg = smprint("%i", pkg); - if(file[0] == '-' && file[1] == 'l') { // TODO: fix this - if(debug['9']) - sprint(name, "/%s/lib/lib", thestring); - else - sprint(name, "/usr/%clib/lib", thechar); - strcat(name, file+2); - strcat(name, ".a"); - file = name; - } if(debug['v']) Bprint(&bso, "%5.2f ldobj: %s (%s)\n", cputime(), file, pkg); Bflush(&bso); @@ -292,9 +310,10 @@ objfile(char *file, char *pkg) Bterm(f); return; } - - l = Bread(f, &arhdr, SAR_HDR); - if(l != SAR_HDR) { + + /* skip over __.SYMDEF */ + off = Boffset(f); + if((l = nextar(f, off, &arhdr)) <= 0) { diag("%s: short read on archive file symbol header", file); goto out; } @@ -302,88 +321,52 @@ objfile(char *file, char *pkg) diag("%s: first entry not symbol header", file); goto out; } - - esym = SARMAG + SAR_HDR + atolwhex(arhdr.size); - off = SARMAG + SAR_HDR; - - if(debug['u']) { - struct ar_hdr pkghdr; - int n; - - // Read next ar header to check for package safe bit. - Bseek(f, esym+(esym&1), 0); - l = Bread(f, &pkghdr, SAR_HDR); - if(l != SAR_HDR) { - diag("%s: short read on second archive header", file); - goto out; - } - if(strncmp(pkghdr.name, pkgname, strlen(pkgname))) { - diag("%s: second entry not package header", file); - goto out; - } - n = atolwhex(pkghdr.size); - ldpkg(f, pkg, n, file, Pkgdef); + off += l; + + /* skip over (or process) __.PKGDEF */ + if((l = nextar(f, off, &arhdr)) <= 0) { + diag("%s: short read on archive file symbol header", file); + goto out; } + if(strncmp(arhdr.name, pkgname, strlen(pkgname))) { + diag("%s: second entry not package header", file); + goto out; + } + off += l; + + if(debug['u']) + ldpkg(f, pkg, atolwhex(arhdr.size), file, Pkgdef); /* - * just bang the whole symbol file into memory + * load all the object files from the archive now. + * this gives us sequential file access and keeps us + * from needing to come back later to pick up more + * objects. it breaks the usual C archive model, but + * this is Go, not C. the common case in Go is that + * we need to load all the objects, and then we throw away + * the individual symbols that are unused. + * + * loading every object will also make it possible to + * load foreign objects not referenced by __.SYMDEF. */ - Bseek(f, off, 0); - cnt = esym - off; - start = mal(cnt + 10); - cnt = Bread(f, start, cnt); - if(cnt <= 0){ - Bterm(f); - return; - } - stop = &start[cnt]; - memset(stop, 0, 10); - - work = 1; - while(work) { - if(debug['v']) - Bprint(&bso, "%5.2f library pass: %s\n", cputime(), file); - Bflush(&bso); - work = 0; - for(e = start; e < stop; e = strchr(e+5, 0) + 1) { - x = expandpkg(e+5, pkg); - s = lookup(x, 0); - if(x != e+5) - free(x); - if(s->type != SXREF) - continue; - sprint(pname, "%s(%s)", file, s->name); - if(debug['v']) - Bprint(&bso, "%5.2f library: %s\n", cputime(), pname); - Bflush(&bso); - l = e[1] & 0xff; - l |= (e[2] & 0xff) << 8; - l |= (e[3] & 0xff) << 16; - l |= (e[4] & 0xff) << 24; - Bseek(f, l, 0); - l = Bread(f, &arhdr, SAR_HDR); - if(l != SAR_HDR) - goto bad; - if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag))) - goto bad; - l = SARNAME; - while(l > 0 && arhdr.name[l-1] == ' ') - l--; - sprint(pname, "%s(%.*s)", file, l, arhdr.name); - l = atolwhex(arhdr.size); - ldobj(f, pkg, l, pname, ArchiveObj); - if(s->type == SXREF) { - diag("%s: failed to load: %s", file, s->name); - errorexit(); - } - work = 1; - xrefresolv = 1; + for(;;) { + l = nextar(f, off, &arhdr); + if(l == 0) + break; + if(l < 0) { + diag("%s: malformed archive", file); + goto out; } - } - return; + off += l; + + l = SARNAME; + while(l > 0 && arhdr.name[l-1] == ' ') + l--; + snprint(pname, sizeof pname, "%s(%.*s)", file, utfnlen(arhdr.name, l), arhdr.name); + l = atolwhex(arhdr.size); + ldobj(f, pkg, l, pname, ArchiveObj); + } -bad: - diag("%s: bad or out of date archive", file); out: Bterm(f); }