Index: src/cmd/objdump/objdump_test.go |
=================================================================== |
--- a/src/cmd/objdump/objdump_test.go |
+++ b/src/cmd/objdump/objdump_test.go |
@@ -79,19 +79,10 @@ |
} |
syms := loadSyms(t) |
- tmpDir, err := ioutil.TempDir("", "TestObjDump") |
- if err != nil { |
- t.Fatal("TempDir failed: ", err) |
- } |
- defer os.RemoveAll(tmpDir) |
+ tmp, exe := buildObjdump(t) |
+ defer os.RemoveAll(tmp) |
- exepath := filepath.Join(tmpDir, "testobjdump.exe") |
- out, err := exec.Command("go", "build", "-o", exepath, "cmd/objdump").CombinedOutput() |
- if err != nil { |
- t.Fatalf("go build -o %v cmd/objdump: %v\n%s", exepath, err, string(out)) |
- } |
- |
- srcPath, srcLineNo := runObjDump(t, exepath, syms["cmd/objdump.TestObjDump"]) |
+ srcPath, srcLineNo := runObjDump(t, exe, syms["cmd/objdump.TestObjDump"]) |
fi1, err := os.Stat("objdump_test.go") |
if err != nil { |
t.Fatalf("Stat failed: %v", err) |
@@ -107,3 +98,86 @@ |
t.Fatalf("line number = %v; want 76", srcLineNo) |
} |
} |
+ |
+func buildObjdump(t *testing.T) (tmp, exe string) { |
+ tmp, err := ioutil.TempDir("", "TestObjDump") |
+ if err != nil { |
+ t.Fatal("TempDir failed: ", err) |
+ } |
+ |
+ exe = filepath.Join(tmp, "testobjdump.exe") |
+ out, err := exec.Command("go", "build", "-o", exe, "cmd/objdump").CombinedOutput() |
+ if err != nil { |
+ os.RemoveAll(tmp) |
+ t.Fatalf("go build -o %v cmd/objdump: %v\n%s", exe, err, string(out)) |
+ } |
+ return |
+} |
+ |
+var x86Need = []string{ |
+ "fmthello.go:6", |
+ "TEXT main.main(SB)", |
+ "JMP main.main(SB)", |
+ "CALL fmt.Println(SB)", |
+ "RET", |
+} |
+ |
+var armNeed = []string{ |
+ "fmthello.go:6", |
+ "TEXT main.main(SB)", |
+ "B main.main(SB)", |
+ "BL fmt.Println(SB)", |
+ "RET", |
+} |
+ |
+// objdump is fully cross platform: it can handle binaries |
+// from any known operating system and architecture. |
+// We could in principle add binaries to testdata and check |
+// all the supported systems during this test. However, the |
+// binaries would be about 1 MB each, and we don't want to |
+// add that much junk to the hg repository. Instead, build a |
+// binary for the current system (only) and test that objdump |
+// can handle that one. |
+ |
+func TestDisasm(t *testing.T) { |
+ if runtime.GOOS == "plan9" { |
+ t.Skip("skipping test; see http://golang.org/issue/7947") |
+ } |
+ |
+ tmp, exe := buildObjdump(t) |
+ defer os.RemoveAll(tmp) |
+ |
+ hello := filepath.Join(tmp, "hello.exe") |
+ out, err := exec.Command("go", "build", "-o", hello, "testdata/fmthello.go").CombinedOutput() |
+ if err != nil { |
+ t.Fatalf("go build fmthello.go: %v\n%s", err, out) |
+ } |
+ need := []string{ |
+ "fmthello.go:6", |
+ "TEXT main.main(SB)", |
+ } |
+ switch runtime.GOARCH { |
+ case "amd64", "386": |
+ need = append(need, x86Need...) |
+ case "arm": |
+ need = append(need, armNeed...) |
+ t.Skip("disassembler not ready on arm yet") |
+ } |
+ |
+ out, err = exec.Command(exe, "-s", "main.main", hello).CombinedOutput() |
+ if err != nil { |
+ t.Fatalf("objdump fmthello.exe: %v\n%s", err, out) |
+ } |
+ |
+ text := string(out) |
+ ok := true |
+ for _, s := range need { |
+ if !strings.Contains(text, s) { |
+ t.Errorf("disassembly missing '%s'", s) |
+ ok = false |
+ } |
+ } |
+ if !ok { |
+ t.Logf("full disassembly:\n%s", text) |
+ } |
+} |