diff options
Diffstat (limited to 'src/cmd/6l/obj.c')
| -rw-r--r-- | src/cmd/6l/obj.c | 655 |
1 files changed, 12 insertions, 643 deletions
diff --git a/src/cmd/6l/obj.c b/src/cmd/6l/obj.c index 47cb44f48..7098b42eb 100644 --- a/src/cmd/6l/obj.c +++ b/src/cmd/6l/obj.c @@ -30,17 +30,15 @@ #define EXTERN #include "l.h" +#include "../ld/lib.h" #include "../ld/elf.h" #include "../ld/macho.h" #include <ar.h> char *noname = "<none>"; -char symname[] = SYMDEF; char thechar = '6'; char* thestring = "amd64"; char* paramspace = "FP"; -char* libdir[16]; // contains "." first, goroot last -int nlibdir = 0; /* * -H2 -T4136 -R4096 is plan9 64-bit format @@ -85,7 +83,6 @@ void main(int argc, char *argv[]) { int i, c; - char *a; Binit(&bso, 1, OWRITE); cout = -1; @@ -98,7 +95,6 @@ main(int argc, char *argv[]) INITDAT = -1; INITRND = -1; INITENTRY = 0; - libdir[nlibdir++] = "."; // look in dot first ARGBEGIN { default: @@ -116,11 +112,7 @@ main(int argc, char *argv[]) HEADTYPE = atolwhex(EARGF(usage())); break; case 'L': - if(nlibdir >= nelem(libdir)-1) { - print("too many -L's: %d\n", nlibdir); - usage(); - } - libdir[nlibdir++] = EARGF(usage()); + Lflag(EARGF(usage())); break; case 'T': INITTEXT = atolwhex(EARGF(usage())); @@ -147,12 +139,7 @@ main(int argc, char *argv[]) if(*argv == 0) usage(); - mywhatsys(); // get goroot, goarch, goos - if(strcmp(goarch, thestring) != 0) - print("goarch is not known: %s\n", goarch); - - // put goroot in the libdir list. - libdir[nlibdir++] = smprint("%s/pkg/%s_%s", goroot, goos, goarch); + libinit(); if(HEADTYPE == -1) { HEADTYPE = 2; @@ -348,33 +335,18 @@ main(int argc, char *argv[]) edatap = P; pc = 0; dtype = 4; - unlink(outfile); - cout = create(outfile, 1, 0775); - if(cout < 0) { - diag("cannot create %s", outfile); - errorexit(); - } version = 0; cbp = buf.cbuf; cbc = sizeof(buf.cbuf); firstp = prg(); lastp = firstp; - if(INITENTRY == nil) { - INITENTRY = mal(strlen(goarch)+strlen(goos)+10); - sprint(INITENTRY, "_rt0_%s_%s", goarch, goos); - } - lookup(INITENTRY, 0)->type = SXREF; - while(*argv) objfile(*argv++); - if(!debug['l']) { + if(!debug['l']) loadlib(); - a = mal(strlen(goroot)+strlen(goarch)+strlen(goos)+20); - sprint(a, "%s/pkg/%s_%s/runtime.a", goroot, goos, goarch); - objfile(a); - } + deadcode(); firstp = firstp->link; @@ -419,7 +391,6 @@ main(int argc, char *argv[]) if(debug['v']) { Bprint(&bso, "%5.2f cpu time\n", cputime()); Bprint(&bso, "%ld symbols\n", nsymbol); - Bprint(&bso, "%ld memory used\n", thunk); Bprint(&bso, "%d sizeof adr\n", sizeof(Adr)); Bprint(&bso, "%d sizeof prog\n", sizeof(Prog)); } @@ -429,160 +400,6 @@ main(int argc, char *argv[]) } void -loadlib(void) -{ - int i; - int32 h; - Sym *s; - -loop: - xrefresolv = 0; - for(i=0; i<libraryp; i++) { - if(debug['v']) - Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i], libraryobj[i]); - objfile(library[i]); - } - if(xrefresolv) - for(h=0; h<nelem(hash); h++) - for(s = hash[h]; s != S; s = s->link) - if(s->type == SXREF) - goto loop; -} - -void -errorexit(void) -{ - if(nerrors) { - if(cout >= 0) - remove(outfile); - exits("error"); - } - exits(0); -} - -void -objfile(char *file) -{ - int32 off, esym, cnt, l; - int work; - Biobuf *f; - Sym *s; - char magbuf[SARMAG]; - char name[100], pname[150]; - struct ar_hdr arhdr; - char *e, *start, *stop; - - 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\n", cputime(), file); - Bflush(&bso); - f = Bopen(file, 0); - if(f == nil) { - diag("cannot open file: %s", file); - errorexit(); - } - l = Bread(f, magbuf, SARMAG); - if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){ - /* load it as a regular file */ - l = Bseek(f, 0L, 2); - Bseek(f, 0L, 0); - ldobj(f, l, file); - Bterm(f); - return; - } - - l = Bread(f, &arhdr, SAR_HDR); - if(l != SAR_HDR) { - diag("%s: short read on archive file symbol header", file); - goto out; - } - if(strncmp(arhdr.name, symname, strlen(symname))) { - diag("%s: first entry not symbol header", file); - goto out; - } - - esym = SARMAG + SAR_HDR + atolwhex(arhdr.size); - off = SARMAG + SAR_HDR; - - /* - * just bang the whole symbol file into memory - */ - 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) { - s = lookup(e+5, 0); - 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, l, pname); - if(s->type == SXREF) { - diag("%s: failed to load: %s", file, s->name); - errorexit(); - } - work = 1; - xrefresolv = 1; - } - } - return; - -bad: - diag("%s: bad or out of date archive", file); -out: - Bterm(f); -} - -int32 -Bget4(Biobuf *f) -{ - uchar p[4]; - - if(Bread(f, p, 4) != 4) - return 0; - return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); -} - -void zaddr(Biobuf *f, Adr *a, Sym *h[]) { int t; @@ -655,182 +472,6 @@ zaddr(Biobuf *f, Adr *a, Sym *h[]) } void -addlib(char *src, char *obj) -{ - char name[1024], pname[1024], comp[256], *p; - int i, search; - - if(histfrogp <= 0) - return; - - search = 0; - if(histfrog[0]->name[1] == '/') { - sprint(name, ""); - i = 1; - } else - if(histfrog[0]->name[1] == '.') { - sprint(name, "."); - i = 0; - } else { - sprint(name, ""); - i = 0; - search = 1; - } - - for(; i<histfrogp; i++) { - snprint(comp, sizeof comp, histfrog[i]->name+1); - for(;;) { - p = strstr(comp, "$O"); - if(p == 0) - break; - memmove(p+1, p+2, strlen(p+2)+1); - p[0] = thechar; - } - for(;;) { - p = strstr(comp, "$M"); - if(p == 0) - break; - if(strlen(comp)+strlen(thestring)-2+1 >= sizeof comp) { - diag("library component too long"); - return; - } - memmove(p+strlen(thestring), p+2, strlen(p+2)+1); - memmove(p, thestring, strlen(thestring)); - } - if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) { - diag("library component too long"); - return; - } - strcat(name, "/"); - strcat(name, comp); - } - - if(search) { - // try dot, -L "libdir", and then goroot. - for(i=0; i<nlibdir; i++) { - snprint(pname, sizeof pname, "%s/%s", libdir[i], name); - if(access(pname, AEXIST) >= 0) - break; - } - strcpy(name, pname); - } - cleanname(name); - if(debug['v']) - Bprint(&bso, "%5.2f addlib: %s %s pulls in %s\n", cputime(), obj, src, name); - - for(i=0; i<libraryp; i++) - if(strcmp(name, library[i]) == 0) - return; - if(libraryp == nelem(library)){ - diag("too many autolibs; skipping %s", name); - return; - } - - p = mal(strlen(name) + 1); - strcpy(p, name); - library[libraryp] = p; - p = mal(strlen(obj) + 1); - strcpy(p, obj); - libraryobj[libraryp] = p; - libraryp++; -} - -void -copyhistfrog(char *buf, int nbuf) -{ - char *p, *ep; - int i; - - p = buf; - ep = buf + nbuf; - i = 0; - for(i=0; i<histfrogp; i++) { - p = seprint(p, ep, "%s", histfrog[i]->name+1); - if(i+1<histfrogp && (p == buf || p[-1] != '/')) - p = seprint(p, ep, "/"); - } -} - -void -addhist(int32 line, int type) -{ - Auto *u; - Sym *s; - int i, j, k; - - u = mal(sizeof(Auto)); - s = mal(sizeof(Sym)); - s->name = mal(2*(histfrogp+1) + 1); - - u->asym = s; - u->type = type; - u->aoffset = line; - u->link = curhist; - curhist = u; - - s->name[0] = 0; - j = 1; - for(i=0; i<histfrogp; i++) { - k = histfrog[i]->value; - s->name[j+0] = k>>8; - s->name[j+1] = k; - j += 2; - } - s->name[j] = 0; - s->name[j+1] = 0; -} - -void -histtoauto(void) -{ - Auto *l; - - while(l = curhist) { - curhist = l->link; - l->link = curauto; - curauto = l; - } -} - -void -collapsefrog(Sym *s) -{ - int i; - - /* - * bad encoding of path components only allows - * MAXHIST components. if there is an overflow, - * first try to collapse xxx/.. - */ - for(i=1; i<histfrogp; i++) - if(strcmp(histfrog[i]->name+1, "..") == 0) { - memmove(histfrog+i-1, histfrog+i+1, - (histfrogp-i-1)*sizeof(histfrog[0])); - histfrogp--; - goto out; - } - - /* - * next try to collapse . - */ - for(i=0; i<histfrogp; i++) - if(strcmp(histfrog[i]->name+1, ".") == 0) { - memmove(histfrog+i, histfrog+i+1, - (histfrogp-i-1)*sizeof(histfrog[0])); - goto out; - } - - /* - * last chance, just truncate from front - */ - memmove(histfrog+0, histfrog+1, - (histfrogp-1)*sizeof(histfrog[0])); - -out: - histfrog[histfrogp-1] = s; -} - -void nopout(Prog *p) { p->as = ANOP; @@ -839,71 +480,22 @@ nopout(Prog *p) } void -ldobj(Biobuf *f, int64 len, char *pn) +ldobj1(Biobuf *f, int64 len, char *pn) { vlong ipc; Prog *p, *t; int v, o, r, skip, mode; Sym *h[NSYM], *s, *di; uint32 sig; - static int files; - static char **filen; - char **nfilen, *line, *name; - int ntext, n, c1, c2, c3; + char *name; + int ntext; vlong eof; - vlong import0, import1; char src[1024]; - src[0] = '\0'; - eof = Boffset(f) + len; - ntext = 0; - - if((files&15) == 0){ - nfilen = malloc((files+16)*sizeof(char*)); - memmove(nfilen, filen, files*sizeof(char*)); - free(filen); - filen = nfilen; - } - pn = strdup(pn); - filen[files++] = pn; - + eof = Boffset(f) + len; di = S; - - /* check the header */ - line = Brdline(f, '\n'); - if(line == nil) { - if(Blinelen(f) > 0) { - diag("%s: malformed object file", pn); - return; - } - goto eof; - } - n = Blinelen(f) - 1; - if(n != strlen(thestring) || strncmp(line, thestring, n) != 0) { - if(line) - line[n] = '\0'; - diag("file not %s [%s]\n", thestring, line); - return; - } - - /* skip over exports and other info -- ends with \n!\n */ - import0 = Boffset(f); - c1 = '\n'; // the last line ended in \n - c2 = Bgetc(f); - c3 = Bgetc(f); - while(c1 != '\n' || c2 != '!' || c3 != '\n') { - c1 = c2; - c2 = c3; - c3 = Bgetc(f); - if(c3 == Beof) - goto eof; - } - import1 = Boffset(f); - - Bseek(f, import0, 0); - ldpkg(f, import1 - import0 - 2, pn); // -2 for !\n - Bseek(f, import1, 0); + src[0] = 0; newloop: memset(h, 0, sizeof(h)); @@ -953,9 +545,9 @@ loop: if(s->sig != 0 && s->sig != sig) diag("incompatible type signatures" "%lux(%s) and %lux(%s) for %s", - s->sig, filen[s->file], sig, pn, s->name); + s->sig, s->file, sig, pn, s->name); s->sig = sig; - s->file = files-1; + s->file = pn; } if(debug['W']) @@ -1256,43 +848,6 @@ eof: diag("truncated object file: %s", pn); } -Sym* -lookup(char *symb, int v) -{ - Sym *s; - char *p; - int32 h; - int l, c; - - h = v; - for(p=symb; c = *p; p++) - h = h+h+h + c; - l = (p - symb) + 1; - if(h < 0) - h = ~h; - h %= NHASH; - for(s = hash[h]; s != S; s = s->link) - if(s->version == v) - if(memcmp(s->name, symb, l) == 0) - return s; - - s = mal(sizeof(*s)); - if(debug['v'] > 1) - Bprint(&bso, "lookup %s\n", symb); - - s->name = mal(l + 1); - memmove(s->name, symb, l); - - s->link = hash[h]; - s->type = 0; - s->version = v; - s->value = 0; - s->sig = 0; - hash[h] = s; - nsymbol++; - return s; -} - Prog* prg(void) { @@ -1477,189 +1032,3 @@ doprof2(void) } } -void -nuxiinit(void) -{ - int i, c; - - for(i=0; i<4; i++) { - c = find1(0x04030201L, i+1); - if(i < 2) - inuxi2[i] = c; - if(i < 1) - inuxi1[i] = c; - inuxi4[i] = c; - inuxi8[i] = c; - inuxi8[i+4] = c+4; - fnuxi4[i] = c; - fnuxi8[i] = c; - fnuxi8[i+4] = c+4; - } - if(debug['v']) { - Bprint(&bso, "inuxi = "); - for(i=0; i<1; i++) - Bprint(&bso, "%d", inuxi1[i]); - Bprint(&bso, " "); - for(i=0; i<2; i++) - Bprint(&bso, "%d", inuxi2[i]); - Bprint(&bso, " "); - for(i=0; i<4; i++) - Bprint(&bso, "%d", inuxi4[i]); - Bprint(&bso, " "); - for(i=0; i<8; i++) - Bprint(&bso, "%d", inuxi8[i]); - Bprint(&bso, "\nfnuxi = "); - for(i=0; i<4; i++) - Bprint(&bso, "%d", fnuxi4[i]); - Bprint(&bso, " "); - for(i=0; i<8; i++) - Bprint(&bso, "%d", fnuxi8[i]); - Bprint(&bso, "\n"); - } - Bflush(&bso); -} - -int -find1(int32 l, int c) -{ - char *p; - int i; - - p = (char*)&l; - for(i=0; i<4; i++) - if(*p++ == c) - return i; - return 0; -} - -int -find2(int32 l, int c) -{ - short *p; - int i; - - p = (short*)&l; - for(i=0; i<4; i+=2) { - if(((*p >> 8) & 0xff) == c) - return i; - if((*p++ & 0xff) == c) - return i+1; - } - return 0; -} - -int32 -ieeedtof(Ieee *e) -{ - int exp; - int32 v; - - if(e->h == 0) - return 0; - exp = (e->h>>20) & ((1L<<11)-1L); - exp -= (1L<<10) - 2L; - v = (e->h & 0xfffffL) << 3; - v |= (e->l >> 29) & 0x7L; - if((e->l >> 28) & 1) { - v++; - if(v & 0x800000L) { - v = (v & 0x7fffffL) >> 1; - exp++; - } - } - if(exp <= -126 || exp >= 130) - diag("double fp to single fp overflow"); - v |= ((exp + 126) & 0xffL) << 23; - v |= e->h & 0x80000000L; - return v; -} - -double -ieeedtod(Ieee *ieeep) -{ - Ieee e; - double fr; - int exp; - - if(ieeep->h & (1L<<31)) { - e.h = ieeep->h & ~(1L<<31); - e.l = ieeep->l; - return -ieeedtod(&e); - } - if(ieeep->l == 0 && ieeep->h == 0) - return 0; - fr = ieeep->l & ((1L<<16)-1L); - fr /= 1L<<16; - fr += (ieeep->l>>16) & ((1L<<16)-1L); - fr /= 1L<<16; - fr += (ieeep->h & (1L<<20)-1L) | (1L<<20); - fr /= 1L<<21; - exp = (ieeep->h>>20) & ((1L<<11)-1L); - exp -= (1L<<10) - 2L; - return ldexp(fr, exp); -} - -void -undefsym(Sym *s) -{ - int n; - - n = imports; - if(s->value != 0) - diag("value != 0 on SXREF"); - if(n >= 1<<Rindex) - diag("import index %d out of range", n); - s->value = n<<Roffset; - s->type = SUNDEF; - imports++; -} - -void -zerosig(char *sp) -{ - Sym *s; - - s = lookup(sp, 0); - s->sig = 0; -} - -void -readundefs(char *f, int t) -{ - int i, n; - Sym *s; - Biobuf *b; - char *l, buf[256], *fields[64]; - - if(f == nil) - return; - b = Bopen(f, OREAD); - if(b == nil){ - diag("could not open %s: %r", f); - errorexit(); - } - while((l = Brdline(b, '\n')) != nil){ - n = Blinelen(b); - if(n >= sizeof(buf)){ - diag("%s: line too long", f); - errorexit(); - } - memmove(buf, l, n); - buf[n-1] = '\0'; - n = getfields(buf, fields, nelem(fields), 1, " \t\r\n"); - if(n == nelem(fields)){ - diag("%s: bad format", f); - errorexit(); - } - for(i = 0; i < n; i++){ - s = lookup(fields[i], 0); - s->type = SXREF; - s->subtype = t; - if(t == SIMPORT) - nimports++; - else - nexports++; - } - } - Bterm(b); -} |
