github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/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 "flag" 9 "fmt" 10 "go/build" 11 "internal/testenv" 12 "io/ioutil" 13 "os" 14 "os/exec" 15 "path/filepath" 16 "runtime" 17 "strings" 18 "testing" 19 ) 20 21 var tmp, exe string // populated by buildObjdump 22 23 func TestMain(m *testing.M) { 24 if !testenv.HasGoBuild() { 25 return 26 } 27 var exitcode int 28 if err := buildObjdump(); err == nil { 29 exitcode = m.Run() 30 } else { 31 fmt.Println(err) 32 exitcode = 1 33 } 34 os.RemoveAll(tmp) 35 os.Exit(exitcode) 36 } 37 38 func buildObjdump() error { 39 var err error 40 tmp, err = ioutil.TempDir("", "TestObjDump") 41 if err != nil { 42 return fmt.Errorf("TempDir failed: %v", err) 43 } 44 45 exe = filepath.Join(tmp, "testobjdump.exe") 46 gotool, err := testenv.GoTool() 47 if err != nil { 48 return err 49 } 50 out, err := exec.Command(gotool, "build", "-o", exe, "cmd/objdump").CombinedOutput() 51 if err != nil { 52 os.RemoveAll(tmp) 53 return fmt.Errorf("go build -o %v cmd/objdump: %v\n%s", exe, err, string(out)) 54 } 55 56 return nil 57 } 58 59 var x86Need = []string{ 60 "fmthello.go:6", 61 "TEXT main.main(SB)", 62 "JMP main.main(SB)", 63 "CALL fmt.Println(SB)", 64 "RET", 65 } 66 67 var armNeed = []string{ 68 "fmthello.go:6", 69 "TEXT main.main(SB)", 70 //"B.LS main.main(SB)", // TODO(rsc): restore; golang.org/issue/9021 71 "BL fmt.Println(SB)", 72 "RET", 73 } 74 75 var ppcNeed = []string{ 76 "fmthello.go:6", 77 "TEXT main.main(SB)", 78 "BR main.main(SB)", 79 "CALL fmt.Println(SB)", 80 "RET", 81 } 82 83 var target = flag.String("target", "", "test disassembly of `goos/goarch` binary") 84 85 // objdump is fully cross platform: it can handle binaries 86 // from any known operating system and architecture. 87 // We could in principle add binaries to testdata and check 88 // all the supported systems during this test. However, the 89 // binaries would be about 1 MB each, and we don't want to 90 // add that much junk to the hg repository. Instead, build a 91 // binary for the current system (only) and test that objdump 92 // can handle that one. 93 94 func testDisasm(t *testing.T, flags ...string) { 95 goarch := runtime.GOARCH 96 if *target != "" { 97 f := strings.Split(*target, "/") 98 if len(f) != 2 { 99 t.Fatalf("-target argument must be goos/goarch") 100 } 101 defer os.Setenv("GOOS", os.Getenv("GOOS")) 102 defer os.Setenv("GOARCH", os.Getenv("GOARCH")) 103 os.Setenv("GOOS", f[0]) 104 os.Setenv("GOARCH", f[1]) 105 goarch = f[1] 106 } 107 108 hello := filepath.Join(tmp, "hello.exe") 109 args := []string{"build", "-o", hello} 110 args = append(args, flags...) 111 args = append(args, "testdata/fmthello.go") 112 out, err := exec.Command(testenv.GoToolPath(t), args...).CombinedOutput() 113 if err != nil { 114 t.Fatalf("go build fmthello.go: %v\n%s", err, out) 115 } 116 need := []string{ 117 "fmthello.go:6", 118 "TEXT main.main(SB)", 119 } 120 switch goarch { 121 case "amd64", "386": 122 need = append(need, x86Need...) 123 case "arm": 124 need = append(need, armNeed...) 125 case "ppc64", "ppc64le": 126 need = append(need, ppcNeed...) 127 } 128 129 out, err = exec.Command(exe, "-s", "main.main", hello).CombinedOutput() 130 if err != nil { 131 t.Fatalf("objdump fmthello.exe: %v\n%s", err, out) 132 } 133 134 text := string(out) 135 ok := true 136 for _, s := range need { 137 if !strings.Contains(text, s) { 138 t.Errorf("disassembly missing '%s'", s) 139 ok = false 140 } 141 } 142 if !ok { 143 t.Logf("full disassembly:\n%s", text) 144 } 145 } 146 147 func TestDisasm(t *testing.T) { 148 switch runtime.GOARCH { 149 case "arm64": 150 t.Skipf("skipping on %s, issue 10106", runtime.GOARCH) 151 case "mips", "mipsle", "mips64", "mips64le": 152 t.Skipf("skipping on %s, issue 12559", runtime.GOARCH) 153 case "s390x": 154 t.Skipf("skipping on %s, issue 15255", runtime.GOARCH) 155 } 156 testDisasm(t) 157 } 158 159 func TestDisasmExtld(t *testing.T) { 160 switch runtime.GOOS { 161 case "plan9", "windows": 162 t.Skipf("skipping on %s", runtime.GOOS) 163 } 164 switch runtime.GOARCH { 165 case "ppc64": 166 t.Skipf("skipping on %s, no support for external linking, issue 9038", runtime.GOARCH) 167 case "arm64": 168 t.Skipf("skipping on %s, issue 10106", runtime.GOARCH) 169 case "mips64", "mips64le", "mips", "mipsle": 170 t.Skipf("skipping on %s, issue 12559 and 12560", runtime.GOARCH) 171 case "s390x": 172 t.Skipf("skipping on %s, issue 15255", runtime.GOARCH) 173 } 174 // TODO(jsing): Reenable once openbsd/arm has external linking support. 175 if runtime.GOOS == "openbsd" && runtime.GOARCH == "arm" { 176 t.Skip("skipping on openbsd/arm, no support for external linking, issue 10619") 177 } 178 if !build.Default.CgoEnabled { 179 t.Skip("skipping because cgo is not enabled") 180 } 181 testDisasm(t, "-ldflags=-linkmode=external") 182 }