/* * read an archive file, * processing the symbols for each intermediate file in it. */ void doar(Biobuf *bp) { int offset, size, obj; char membername[SARNAME]; multifile = 1; for (offset = Boffset(bp);;offset += size) { size = nextar(bp, offset, membername); if (size < 0) { error("phase error on ar header %ld", offset); return; } if (size == 0) return; if (strcmp(membername, symname) == 0) continue; obj = objtype(bp, 0); if (obj < 0) { error("inconsistent file %s in %s", membername, filename); return; } if (!readar(bp, obj, offset+size, 1)) { error("invalid symbol reference in file %s", membername); return; } filename = membername; nsym=0; objtraverse(psym, 0); printsyms(symptr, nsym); } }
static void doar(Biobuf *bp, char *file) { int offset, size, obj; char membername[SARNAME]; char symname[]="__.SYMDEF"; /* table of contents file name */ for (offset = Boffset(bp);;offset += size) { size = nextar(bp, offset, membername); if (size < 0) { fprint(2, "%s: phase error on ar header %ld", file, offset); return; } if (size == 0) return; if (strcmp(membername, symname) == 0) continue; obj = objtype(bp, 0); if (obj < 0) { fprint(2, "%s: %s inconsistent file", file, membername); return; } if (!readar(bp, obj, offset+size, 1)) { fprint(2, "%s: %s invalid symbol reference in file", file, membername); return; } objtraverse(addfunc, 0); } }
void objfile(char *file, char *pkg) { vlong off, l; Biobuf *f; char magbuf[SARMAG]; char pname[150]; struct ar_hdr arhdr; pkg = smprint("%i", pkg); if(debug['v'] > 1) Bprint(&bso, "%5.2f ldobj: %s (%s)\n", cputime(), file, pkg); 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, pkg, l, file, file, FileObj); Bterm(f); free(pkg); return; } /* skip over optional __.GOSYMDEF and process __.PKGDEF */ off = Boffset(f); l = nextar(f, off, &arhdr); if(l <= 0) { diag("%s: short read on archive file symbol header", file); goto out; } if(strncmp(arhdr.name, symname, strlen(symname)) == 0) { off += l; l = nextar(f, off, &arhdr); if(l <= 0) { diag("%s: short read on archive file symbol header", file); goto out; } } if(strncmp(arhdr.name, pkgname, strlen(pkgname))) { diag("%s: cannot find package header", file); goto out; } off += l; if(debug['u']) ldpkg(f, pkg, atolwhex(arhdr.size), file, Pkgdef); /* * 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 __.GOSYMDEF. */ for(;;) { l = nextar(f, off, &arhdr); if(l == 0) break; if(l < 0) { diag("%s: malformed archive", file); goto out; } 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, file, ArchiveObj); } out: Bterm(f); free(pkg); }