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 {