]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.cc] cmd/go: run C and Go assemblers side by side and verify matching output
authorRuss Cox <rsc@golang.org>
Wed, 21 Jan 2015 17:04:35 +0000 (12:04 -0500)
committerRuss Cox <rsc@golang.org>
Wed, 21 Jan 2015 19:43:24 +0000 (19:43 +0000)
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 <r@golang.org>
src/cmd/go/build.go
src/cmd/go/main.go

index e201f29e766576cb38acbbc924af2881fe359064..0cb7dbb239ea14b919e906bb4059dc93eb2c92c6 100644 (file)
@@ -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 {
index f3dfc8824f979cdae5d3c4ea9ebce28f70b0aa7f..1482a3958220051683edf23f2eb5269ca279c09d 100644 (file)
@@ -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