diff options
author | Hiroshi Ioka <hirochachacha@gmail.com> | 2017-09-16 15:28:14 +0900 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2017-09-21 01:01:44 +0000 |
commit | 589ea93678850ad1e5c1192df5768177c3104937 (patch) | |
tree | a6ba4177df2d16ca506c5e683268a29f4bb3de2b /src/cmd/nm | |
parent | 6a537c1d4718f2804bbad983037b9a6e4b40bc60 (diff) | |
download | go-589ea93678850ad1e5c1192df5768177c3104937.tar.gz go-589ea93678850ad1e5c1192df5768177c3104937.zip |
cmd/nm: handle cgo archive
This CL also make cmd/nm accept PE object file.
Fixes #21706
Change-Id: I4a528b7d53da1082e61523ebeba02c4c514a43a7
Reviewed-on: https://go-review.googlesource.com/64890
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/cmd/nm')
-rw-r--r-- | src/cmd/nm/nm.go | 71 | ||||
-rw-r--r-- | src/cmd/nm/nm_cgo_test.go | 11 | ||||
-rw-r--r-- | src/cmd/nm/nm_test.go | 55 |
3 files changed, 98 insertions, 39 deletions
diff --git a/src/cmd/nm/nm.go b/src/cmd/nm/nm.go index 2e2dd75018..65ef5b4295 100644 --- a/src/cmd/nm/nm.go +++ b/src/cmd/nm/nm.go @@ -106,41 +106,54 @@ func nm(file string) { } defer f.Close() - syms, err := f.Symbols() - if err != nil { - errorf("reading %s: %v", file, err) - } - if len(syms) == 0 { - errorf("reading %s: no symbols", file) - } + w := bufio.NewWriter(os.Stdout) - switch *sortOrder { - case "address": - sort.Slice(syms, func(i, j int) bool { return syms[i].Addr < syms[j].Addr }) - case "name": - sort.Slice(syms, func(i, j int) bool { return syms[i].Name < syms[j].Name }) - case "size": - sort.Slice(syms, func(i, j int) bool { return syms[i].Size > syms[j].Size }) - } + entries := f.Entries() - w := bufio.NewWriter(os.Stdout) - for _, sym := range syms { - if filePrefix { - fmt.Fprintf(w, "%s:\t", file) + for _, e := range entries { + syms, err := e.Symbols() + if err != nil { + errorf("reading %s: %v", file, err) } - if sym.Code == 'U' { - fmt.Fprintf(w, "%8s", "") - } else { - fmt.Fprintf(w, "%8x", sym.Addr) + if len(syms) == 0 { + errorf("reading %s: no symbols", file) } - if *printSize { - fmt.Fprintf(w, " %10d", sym.Size) + + switch *sortOrder { + case "address": + sort.Slice(syms, func(i, j int) bool { return syms[i].Addr < syms[j].Addr }) + case "name": + sort.Slice(syms, func(i, j int) bool { return syms[i].Name < syms[j].Name }) + case "size": + sort.Slice(syms, func(i, j int) bool { return syms[i].Size > syms[j].Size }) } - fmt.Fprintf(w, " %c %s", sym.Code, sym.Name) - if *printType && sym.Type != "" { - fmt.Fprintf(w, " %s", sym.Type) + + for _, sym := range syms { + if len(entries) > 1 { + name := e.Name() + if name == "" { + fmt.Fprintf(w, "%s(%s):\t", file, "_go_.o") + } else { + fmt.Fprintf(w, "%s(%s):\t", file, name) + } + } else if filePrefix { + fmt.Fprintf(w, "%s:\t", file) + } + if sym.Code == 'U' { + fmt.Fprintf(w, "%8s", "") + } else { + fmt.Fprintf(w, "%8x", sym.Addr) + } + if *printSize { + fmt.Fprintf(w, " %10d", sym.Size) + } + fmt.Fprintf(w, " %c %s", sym.Code, sym.Name) + if *printType && sym.Type != "" { + fmt.Fprintf(w, " %s", sym.Type) + } + fmt.Fprintf(w, "\n") } - fmt.Fprintf(w, "\n") } + w.Flush() } diff --git a/src/cmd/nm/nm_cgo_test.go b/src/cmd/nm/nm_cgo_test.go index 31ab1d67b5..4e67560e2e 100644 --- a/src/cmd/nm/nm_cgo_test.go +++ b/src/cmd/nm/nm_cgo_test.go @@ -34,3 +34,14 @@ func TestInternalLinkerCgoExec(t *testing.T) { func TestExternalLinkerCgoExec(t *testing.T) { testGoExec(t, true, true) } + +func TestCgoLib(t *testing.T) { + if runtime.GOARCH == "arm" { + switch runtime.GOOS { + case "darwin", "android", "nacl": + default: + t.Skip("skip test due to #19811") + } + } + testGoLib(t, true) +} diff --git a/src/cmd/nm/nm_test.go b/src/cmd/nm/nm_test.go index c6f6d3b9d4..4be5d0e74e 100644 --- a/src/cmd/nm/nm_test.go +++ b/src/cmd/nm/nm_test.go @@ -161,7 +161,7 @@ func TestGoExec(t *testing.T) { testGoExec(t, false, false) } -func testGoLib(t *testing.T) { +func testGoLib(t *testing.T, iscgo bool) { tmpdir, err := ioutil.TempDir("", "TestGoLib") if err != nil { t.Fatal(err) @@ -180,7 +180,7 @@ func testGoLib(t *testing.T) { if err != nil { t.Fatal(err) } - err = template.Must(template.New("mylib").Parse(testlib)).Execute(file, nil) + err = template.Must(template.New("mylib").Parse(testlib)).Execute(file, iscgo) if e := file.Close(); err == nil { err = e } @@ -212,23 +212,46 @@ func testGoLib(t *testing.T) { type symType struct { Type string Name string + CSym bool Found bool } var syms = []symType{ - {"B", "%22%22.Testdata", false}, - {"T", "%22%22.Testfunc", false}, + {"B", "%22%22.Testdata", false, false}, + {"T", "%22%22.Testfunc", false, false}, + } + if iscgo { + syms = append(syms, symType{"B", "%22%22.TestCgodata", false, false}) + syms = append(syms, symType{"T", "%22%22.TestCgofunc", false, false}) + if runtime.GOOS == "darwin" || (runtime.GOOS == "windows" && runtime.GOARCH == "386") { + syms = append(syms, symType{"D", "_cgodata", true, false}) + syms = append(syms, symType{"T", "_cgofunc", true, false}) + } else { + syms = append(syms, symType{"D", "cgodata", true, false}) + syms = append(syms, symType{"T", "cgofunc", true, false}) + } } scanner := bufio.NewScanner(bytes.NewBuffer(out)) for scanner.Scan() { f := strings.Fields(scanner.Text()) - if len(f) < 3 { - continue + var typ, name string + var csym bool + if iscgo { + if len(f) < 4 { + continue + } + csym = !strings.Contains(f[0], "_go_.o") + typ = f[2] + name = f[3] + } else { + if len(f) < 3 { + continue + } + typ = f[1] + name = f[2] } - typ := f[1] - name := f[2] for i := range syms { sym := &syms[i] - if sym.Type == typ && sym.Name == name { + if sym.Type == typ && sym.Name == name && sym.CSym == csym { if sym.Found { t.Fatalf("duplicate symbol %s %s", sym.Type, sym.Name) } @@ -248,7 +271,7 @@ func testGoLib(t *testing.T) { } func TestGoLib(t *testing.T) { - testGoLib(t) + testGoLib(t, false) } const testexec = ` @@ -274,6 +297,18 @@ func testfunc() { const testlib = ` package mylib +{{if .}} +// int cgodata = 5; +// void cgofunc(void) {} +import "C" + +var TestCgodata = C.cgodata + +func TestCgofunc() { + C.cgofunc() +} +{{end}} + var Testdata uint32 func Testfunc() {} |