From 5282e3ab26dd01180640a1a0e59ed5a4d070ba44 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 21 Jan 2015 12:04:35 -0500 Subject: [PATCH] [dev.cc] cmd/go: run C and Go assemblers side by side and verify matching output When an assembly file must be assembled, cmd/go now runs both (say) 6a and new6a and checks that they write identical output files. This serves as a build-time test that the new assemblers are accurate conversions of the old ones. As long as they are producing identical bytes, there's no need for run-time testing. Once the C conversion is done, we'll throw away the C code and this checking. Change-Id: I0216dad56b7e79011eecd27f1aff4fe79bfe720b Reviewed-on: https://go-review.googlesource.com/3145 Reviewed-by: Rob Pike --- src/cmd/go/build.go | 31 ++++++++++++++++++++++++++++++- src/cmd/go/main.go | 2 +- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go index e201f29e76..0cb7dbb239 100644 --- a/src/cmd/go/build.go +++ b/src/cmd/go/build.go @@ -1672,11 +1672,40 @@ func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, return ofile, output, err } +// verifyAsm specifies whether to check the assemblers written in Go +// against the assemblers written in C. If set, asm will run both (say) 6a and new6a +// and fail if the two produce different output files. +const verifyAsm = true + func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error { // Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files. inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch)) sfile = mkAbs(p.Dir, sfile) - return b.run(p.Dir, p.ImportPath, nil, tool(archChar+"a"), "-trimpath", b.work, "-I", obj, "-I", inc, "-o", ofile, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, sfile) + args := []interface{}{tool(archChar + "a"), "-o", ofile, "-trimpath", b.work, "-I", obj, "-I", inc, "-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch, sfile} + if err := b.run(p.Dir, p.ImportPath, nil, args...); err != nil { + return err + } + if verifyAsm { + newArgs := make([]interface{}, len(args)) + copy(newArgs, args) + newArgs[0] = tool("new" + archChar + "a") + newArgs[2] = ofile + ".new" // x.6 becomes x.6.new + if err := b.run(p.Dir, p.ImportPath, nil, newArgs...); err != nil { + return err + } + data1, err := ioutil.ReadFile(ofile) + if err != nil { + return err + } + data2, err := ioutil.ReadFile(ofile + ".new") + if err != nil { + return err + } + if !bytes.Equal(data1, data2) { + return fmt.Errorf("%sa and n%sa produced different output files:\n%s\n%s", archChar, archChar, strings.Join(stringList(args...), " "), strings.Join(stringList(newArgs...), " ")) + } + } + return nil } func (gcToolchain) pkgpath(basedir string, p *Package) string { diff --git a/src/cmd/go/main.go b/src/cmd/go/main.go index f3dfc8824f..1482a39582 100644 --- a/src/cmd/go/main.go +++ b/src/cmd/go/main.go @@ -662,7 +662,7 @@ func stringList(args ...interface{}) []string { case string: x = append(x, arg) default: - panic("stringList: invalid argument") + panic("stringList: invalid argument of type " + fmt.Sprintf("%T", arg)) } } return x -- 2.48.1