Commit b0223340 authored by Russ Cox's avatar Russ Cox

cmd/gc: implement -pack flag

The -pack flag causes 5g, 6g, 8g to write a Go archive directly,
instead of requiring the use of 'go tool pack' to convert the .5/.6/.8
to .a format.

Writing directly avoids the copy and also avoids having the
export data stored twice in the archive (once in __.PKGDEF,
once in .5/.6/.8).

A separate CL will enable the use of this flag by cmd/go.

Other build systems that do not know about -pack will be unaffected.

The changes to cmd/ld handle a minor simplification to the format:
an unused section is removed.

R=iant, r
CC=golang-dev
https://golang.org/cl/42880043
parent deb55493
...@@ -354,7 +354,7 @@ dumpexport(void) ...@@ -354,7 +354,7 @@ dumpexport(void)
lno = lineno; lno = lineno;
Bprint(bout, "\n$$ // exports\n package %s", localpkg->name); Bprint(bout, "\n$$\npackage %s", localpkg->name);
if(safemode) if(safemode)
Bprint(bout, " safe"); Bprint(bout, " safe");
Bprint(bout, "\n"); Bprint(bout, "\n");
...@@ -369,8 +369,7 @@ dumpexport(void) ...@@ -369,8 +369,7 @@ dumpexport(void)
dumpsym(l->n->sym); dumpsym(l->n->sym);
} }
Bprint(bout, "\n$$ // local types\n\n$$\n"); // 6l expects this. (see ld/go.c) Bprint(bout, "\n$$\n");
lineno = lno; lineno = lno;
} }
......
...@@ -977,6 +977,7 @@ EXTERN Link* ctxt; ...@@ -977,6 +977,7 @@ EXTERN Link* ctxt;
EXTERN int nointerface; EXTERN int nointerface;
EXTERN int fieldtrack_enabled; EXTERN int fieldtrack_enabled;
EXTERN int precisestack_enabled; EXTERN int precisestack_enabled;
EXTERN int writearchive;
EXTERN Biobuf bstdout; EXTERN Biobuf bstdout;
......
...@@ -267,6 +267,7 @@ main(int argc, char *argv[]) ...@@ -267,6 +267,7 @@ main(int argc, char *argv[])
flagcount("m", "print optimization decisions", &debug['m']); flagcount("m", "print optimization decisions", &debug['m']);
flagstr("o", "obj: set output file", &outfile); flagstr("o", "obj: set output file", &outfile);
flagstr("p", "path: set expected package import path", &myimportpath); flagstr("p", "path: set expected package import path", &myimportpath);
flagcount("pack", "write package file instead of object file", &writearchive);
flagcount("r", "debug generated wrappers", &debug['r']); flagcount("r", "debug generated wrappers", &debug['r']);
flagcount("race", "enable race detector", &flag_race); flagcount("race", "enable race detector", &flag_race);
flagcount("s", "warn about composite literals that can be simplified", &debug['s']); flagcount("s", "warn about composite literals that can be simplified", &debug['s']);
...@@ -518,12 +519,13 @@ skiptopkgdef(Biobuf *b) ...@@ -518,12 +519,13 @@ skiptopkgdef(Biobuf *b)
return 0; return 0;
if(memcmp(p, "!<arch>\n", 8) != 0) if(memcmp(p, "!<arch>\n", 8) != 0)
return 0; return 0;
/* symbol table is first; skip it */ /* symbol table may be first; skip it */
sz = arsize(b, "__.GOSYMDEF"); sz = arsize(b, "__.GOSYMDEF");
if(sz < 0) if(sz >= 0)
return 0; Bseek(b, sz, 1);
Bseek(b, sz, 1); else
/* package export block is second */ Bseek(b, 8, 0);
/* package export block is next */
sz = arsize(b, "__.PKGDEF"); sz = arsize(b, "__.PKGDEF");
if(sz <= 0) if(sz <= 0)
return 0; return 0;
......
...@@ -12,10 +12,25 @@ ...@@ -12,10 +12,25 @@
static void dumpglobls(void); static void dumpglobls(void);
enum
{
ArhdrSize = 60
};
static void
formathdr(char *arhdr, char *name, vlong size)
{
snprint(arhdr, ArhdrSize, "%-16s%-12d%-6d%-6d%-8o%-10d`",
name, 0, 0, 0, 0644, size);
arhdr[ArhdrSize-1] = '\n'; // overwrite \0 written by snprint
}
void void
dumpobj(void) dumpobj(void)
{ {
NodeList *externs, *tmp; NodeList *externs, *tmp;
char arhdr[ArhdrSize];
vlong startobj, size;
Sym *zero; Sym *zero;
bout = Bopen(outfile, OWRITE); bout = Bopen(outfile, OWRITE);
...@@ -25,10 +40,33 @@ dumpobj(void) ...@@ -25,10 +40,33 @@ dumpobj(void)
errorexit(); errorexit();
} }
startobj = 0;
if(writearchive) {
Bwrite(bout, "!<arch>\n", 8);
memset(arhdr, 0, sizeof arhdr);
Bwrite(bout, arhdr, sizeof arhdr);
startobj = Boffset(bout);
}
Bprint(bout, "go object %s %s %s %s\n", getgoos(), thestring, getgoversion(), expstring()); Bprint(bout, "go object %s %s %s %s\n", getgoos(), thestring, getgoversion(), expstring());
Bprint(bout, " exports automatically generated from\n");
Bprint(bout, " %s in package \"%s\"\n", curio.infile, localpkg->name);
dumpexport(); dumpexport();
if(writearchive) {
Bflush(bout);
size = Boffset(bout) - startobj;
if(size&1)
Bputc(bout, 0);
Bseek(bout, startobj - ArhdrSize, 0);
formathdr(arhdr, "__.PKGDEF", size);
Bwrite(bout, arhdr, ArhdrSize);
Bflush(bout);
Bseek(bout, startobj + size + (size&1), 0);
memset(arhdr, 0, ArhdrSize);
Bwrite(bout, arhdr, ArhdrSize);
startobj = Boffset(bout);
Bprint(bout, "go object %s %s %s %s\n", getgoos(), thestring, getgoversion(), expstring());
}
Bprint(bout, "\n!\n"); Bprint(bout, "\n!\n");
externs = nil; externs = nil;
...@@ -51,6 +89,16 @@ dumpobj(void) ...@@ -51,6 +89,16 @@ dumpobj(void)
dumpdata(); dumpdata();
linkwriteobj(ctxt, bout); linkwriteobj(ctxt, bout);
if(writearchive) {
Bflush(bout);
size = Boffset(bout) - startobj;
if(size&1)
Bputc(bout, 0);
Bseek(bout, startobj - ArhdrSize, 0);
snprint(namebuf, sizeof namebuf, "_go_.%c", thechar);
formathdr(arhdr, namebuf, size);
Bwrite(bout, arhdr, ArhdrSize);
}
Bterm(bout); Bterm(bout);
} }
......
...@@ -151,28 +151,11 @@ ldpkg(Biobuf *f, char *pkg, int64 len, char *filename, int whence) ...@@ -151,28 +151,11 @@ ldpkg(Biobuf *f, char *pkg, int64 len, char *filename, int whence)
} }
loadpkgdata(filename, pkg, p0, p1 - p0); 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) if(whence == Pkgdef)
return; 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 // look for cgo section
p0 = strstr(p1, "\n$$ // cgo"); p0 = strstr(p1, "\n$$ // cgo");
if(p0 != nil) { if(p0 != nil) {
......
...@@ -327,25 +327,22 @@ objfile(char *file, char *pkg) ...@@ -327,25 +327,22 @@ objfile(char *file, char *pkg)
return; return;
} }
/* skip over __.GOSYMDEF */ /* skip over optional __.GOSYMDEF and process __.PKGDEF */
off = Boffset(f); off = Boffset(f);
if((l = nextar(f, off, &arhdr)) <= 0) { if((l = nextar(f, off, &arhdr)) <= 0) {
diag("%s: short read on archive file symbol header", file); diag("%s: short read on archive file symbol header", file);
goto out; goto out;
} }
if(strncmp(arhdr.name, symname, strlen(symname))) { if(strncmp(arhdr.name, symname, strlen(symname)) == 0) {
diag("%s: first entry not symbol header", file); off += l;
goto out; if((l = nextar(f, off, &arhdr)) <= 0) {
} diag("%s: short read on archive file symbol header", file);
off += l; goto out;
}
/* 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))) { if(strncmp(arhdr.name, pkgname, strlen(pkgname))) {
diag("%s: second entry not package header", file); diag("%s: cannot find package header", file);
goto out; goto out;
} }
off += l; off += l;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment