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 "bufio" 9 "bytes" 10 "fmt" 11 "internal/testenv" 12 "io/ioutil" 13 "os" 14 "os/exec" 15 "path/filepath" 16 "runtime" 17 "strings" 18 "testing" 19 ) 20 21 var testData uint32 22 23 func checkSymbols(t *testing.T, nmoutput []byte) { 24 var checkSymbolsFound, testDataFound bool 25 scanner := bufio.NewScanner(bytes.NewBuffer(nmoutput)) 26 for scanner.Scan() { 27 f := strings.Fields(scanner.Text()) 28 if len(f) < 3 { 29 continue 30 } 31 switch f[2] { 32 case "cmd/nm.checkSymbols": 33 checkSymbolsFound = true 34 addr := "0x" + f[0] 35 if addr != fmt.Sprintf("%p", checkSymbols) { 36 t.Errorf("nm shows wrong address %v for checkSymbols (%p)", addr, checkSymbols) 37 } 38 case "cmd/nm.testData": 39 testDataFound = true 40 addr := "0x" + f[0] 41 if addr != fmt.Sprintf("%p", &testData) { 42 t.Errorf("nm shows wrong address %v for testData (%p)", addr, &testData) 43 } 44 } 45 } 46 if err := scanner.Err(); err != nil { 47 t.Errorf("error while reading symbols: %v", err) 48 return 49 } 50 if !checkSymbolsFound { 51 t.Error("nm shows no checkSymbols symbol") 52 } 53 if !testDataFound { 54 t.Error("nm shows no testData symbol") 55 } 56 } 57 58 func TestNM(t *testing.T) { 59 testenv.MustHaveGoBuild(t) 60 61 tmpDir, err := ioutil.TempDir("", "TestNM") 62 if err != nil { 63 t.Fatal("TempDir failed: ", err) 64 } 65 defer os.RemoveAll(tmpDir) 66 67 testnmpath := filepath.Join(tmpDir, "testnm.exe") 68 out, err := exec.Command("go", "build", "-o", testnmpath, "cmd/nm").CombinedOutput() 69 if err != nil { 70 t.Fatalf("go build -o %v cmd/nm: %v\n%s", testnmpath, err, string(out)) 71 } 72 73 testfiles := []string{ 74 "elf/testdata/gcc-386-freebsd-exec", 75 "elf/testdata/gcc-amd64-linux-exec", 76 "macho/testdata/gcc-386-darwin-exec", 77 "macho/testdata/gcc-amd64-darwin-exec", 78 // "pe/testdata/gcc-amd64-mingw-exec", // no symbols! 79 "pe/testdata/gcc-386-mingw-exec", 80 "plan9obj/testdata/amd64-plan9-exec", 81 "plan9obj/testdata/386-plan9-exec", 82 } 83 for _, f := range testfiles { 84 exepath := filepath.Join(runtime.GOROOT(), "src", "debug", f) 85 cmd := exec.Command(testnmpath, exepath) 86 out, err := cmd.CombinedOutput() 87 if err != nil { 88 t.Errorf("go tool nm %v: %v\n%s", exepath, err, string(out)) 89 } 90 } 91 92 cmd := exec.Command(testnmpath, os.Args[0]) 93 out, err = cmd.CombinedOutput() 94 if err != nil { 95 t.Fatalf("go tool nm %v: %v\n%s", os.Args[0], err, string(out)) 96 } 97 checkSymbols(t, out) 98 } 99