github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/cmd/objdump/objdump_test.go (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "io/ioutil" 9 "os" 10 "os/exec" 11 "path/filepath" 12 "runtime" 13 "strings" 14 "testing" 15 ) 16 17 func buildObjdump(t *testing.T) (tmp, exe string) { 18 switch runtime.GOOS { 19 case "android", "nacl": 20 t.Skipf("skipping on %s", runtime.GOOS) 21 case "darwin": 22 switch runtime.GOARCH { 23 case "arm", "arm64": 24 t.Skipf("skipping on %s/%s, cannot fork", runtime.GOOS, runtime.GOARCH) 25 } 26 } 27 28 tmp, err := ioutil.TempDir("", "TestObjDump") 29 if err != nil { 30 t.Fatal("TempDir failed: ", err) 31 } 32 33 exe = filepath.Join(tmp, "testobjdump.exe") 34 out, err := exec.Command("go", "build", "-o", exe, "cmd/objdump").CombinedOutput() 35 if err != nil { 36 os.RemoveAll(tmp) 37 t.Fatalf("go build -o %v cmd/objdump: %v\n%s", exe, err, string(out)) 38 } 39 return 40 } 41 42 var x86Need = []string{ 43 "fmthello.go:6", 44 "TEXT main.main(SB)", 45 "JMP main.main(SB)", 46 "CALL fmt.Println(SB)", 47 "RET", 48 } 49 50 var armNeed = []string{ 51 "fmthello.go:6", 52 "TEXT main.main(SB)", 53 //"B.LS main.main(SB)", // TODO(rsc): restore; golang.org/issue/9021 54 "BL fmt.Println(SB)", 55 "RET", 56 } 57 58 // objdump is fully cross platform: it can handle binaries 59 // from any known operating system and architecture. 60 // We could in principle add binaries to testdata and check 61 // all the supported systems during this test. However, the 62 // binaries would be about 1 MB each, and we don't want to 63 // add that much junk to the hg repository. Instead, build a 64 // binary for the current system (only) and test that objdump 65 // can handle that one. 66 67 func testDisasm(t *testing.T, flags ...string) { 68 tmp, exe := buildObjdump(t) 69 defer os.RemoveAll(tmp) 70 71 hello := filepath.Join(tmp, "hello.exe") 72 args := []string{"build", "-o", hello} 73 args = append(args, flags...) 74 args = append(args, "testdata/fmthello.go") 75 out, err := exec.Command("go", args...).CombinedOutput() 76 if err != nil { 77 t.Fatalf("go build fmthello.go: %v\n%s", err, out) 78 } 79 need := []string{ 80 "fmthello.go:6", 81 "TEXT main.main(SB)", 82 } 83 switch runtime.GOARCH { 84 case "amd64", "386": 85 need = append(need, x86Need...) 86 case "arm": 87 need = append(need, armNeed...) 88 } 89 90 out, err = exec.Command(exe, "-s", "main.main", hello).CombinedOutput() 91 if err != nil { 92 t.Fatalf("objdump fmthello.exe: %v\n%s", err, out) 93 } 94 95 text := string(out) 96 ok := true 97 for _, s := range need { 98 if !strings.Contains(text, s) { 99 t.Errorf("disassembly missing '%s'", s) 100 ok = false 101 } 102 } 103 if !ok { 104 t.Logf("full disassembly:\n%s", text) 105 } 106 } 107 108 func TestDisasm(t *testing.T) { 109 switch runtime.GOARCH { 110 case "ppc64", "ppc64le": 111 t.Skipf("skipping on %s, issue 9039", runtime.GOARCH) 112 case "arm64": 113 t.Skipf("skipping on %s, issue 10106", runtime.GOARCH) 114 } 115 testDisasm(t) 116 } 117 118 func TestDisasmExtld(t *testing.T) { 119 switch runtime.GOOS { 120 case "plan9", "windows": 121 t.Skipf("skipping on %s", runtime.GOOS) 122 } 123 switch runtime.GOARCH { 124 case "ppc64", "ppc64le": 125 t.Skipf("skipping on %s, no support for external linking, issue 9038", runtime.GOARCH) 126 case "arm64": 127 t.Skipf("skipping on %s, issue 10106", runtime.GOARCH) 128 } 129 testDisasm(t, "-ldflags=-linkmode=external") 130 }