aboutsummaryrefslogtreecommitdiff
path: root/src/liblink/objfile.c
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2015-01-19 13:24:43 -0500
committerRuss Cox <rsc@golang.org>2015-01-21 03:15:04 +0000
commitbe818361b9a5e73ade75fa1999ed0dec81de7cb6 (patch)
tree34b62d0de1c4998e5ae4a6f8af2999c4a5d2d8c6 /src/liblink/objfile.c
parent35d3987dbc49d0e2cae4e0cf70dabb62e62cbc50 (diff)
downloadgo-be818361b9a5e73ade75fa1999ed0dec81de7cb6.tar.xz
[dev.cc] liblink: invoke 'go tool objwriter' to implement writeobj, if directed
This CL enables moving the bulk of the object writing code out of liblink and into translated Go libraries in cmd/internal/obj, but it does not do the move. This CL introduces two new environment variables, $GOOBJ and $GOOBJWRITER, but both will be deleted along with the rest of the liblink C code. The default behavior of a build is unchanged by this CL: the C version of liblink uses the C object layout and writing code. If $GOOBJ=1, liblink invokes go tool objwriter instead. If $GOOBJ=2, liblink does its own layout and then invokes go tool objwriter, which checks that it gets the same answer. That is, in $GOOBJ=2 mode, both the C and the Go version of the code run, and the operation fails if the two produce different answers. This provides a very strong check that the translation is working correctly. Change-Id: I56ab49b07ccb2c7b81085f1d6950131047c6aa3c Reviewed-on: https://go-review.googlesource.com/3048 Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/liblink/objfile.c')
-rw-r--r--src/liblink/objfile.c52
1 files changed, 34 insertions, 18 deletions
diff --git a/src/liblink/objfile.c b/src/liblink/objfile.c
index 6711aaf776..8c2257de8a 100644
--- a/src/liblink/objfile.c
+++ b/src/liblink/objfile.c
@@ -119,29 +119,45 @@ static char *rdstring(Biobuf*);
static void rddata(Biobuf*, uchar**, int*);
static LSym *rdsym(Link*, Biobuf*, char*);
-void writeobjdirect(Link*, Biobuf*);
+void writeobjdirect(Link *ctxt, Biobuf *b);
+
+void writeobjgo1(Link*, char*);
+void writeobjgo2(Link*, char*, int64);
+
+extern char *outfile;
void
writeobj(Link *ctxt, Biobuf *b)
{
- char *cmd[3];
-
- // TODO(rsc): Use 'go tool objwriter' to write object file,
- // allowing the bulk of liblink to be moved into Go.
- // As a first step, we check that we can invoke objwriter at all
- // (it is an empty program for now).
- // This tests the cmd/dist bootstrap process, making sure
- // that objwriter is available when it needs to be.
- // Once the support mechanisms are there, we can put the
- // real code in.
-
- cmd[0] = smprint("%s/pkg/tool/%s_%s/objwriter", getgoroot(), getgohostos(), getgohostarch());
- cmd[1] = "ping";
- cmd[2] = nil;
- if(runcmd(cmd) < 0)
- sysfatal("cannot run objwriter: %r");
+ vlong start;
+ char *env;
- writeobjdirect(ctxt, b);
+ // If $GOOBJ > 0, invoke the Go version of the liblink
+ // output routines via a subprocess.
+ // If $GOOBJ == 1, copy that subprocess's output to
+ // the actual output file.
+ // If $GOOBJ >= 2, generate output using the usual C version
+ // but then check that the subprocess wrote the same bytes.
+ // $GOOBJ is a temporary setting for the transition to a
+ // Go liblink back end. Once the C liblink back ends are deleted,
+ // we will hard code the GOOBJ=1 behavior.
+ env = getenv("GOOBJ");
+ if(env == nil)
+ env = "2";
+ if(atoi(env) == 0) {
+ writeobjdirect(ctxt, b);
+ return;
+ }
+
+ Bflush(b);
+ start = Boffset(b);
+ writeobjgo1(ctxt, outfile);
+ if(atoi(env) > 1) {
+ writeobjdirect(ctxt, b);
+ Bflush(b);
+ }
+ writeobjgo2(ctxt, outfile, start);
+ Bseek(b, 0, 2);
}
// The Go and C compilers, and the assembler, call writeobj to write