aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/nm
diff options
context:
space:
mode:
authorHiroshi Ioka <hirochachacha@gmail.com>2017-09-16 15:28:14 +0900
committerIan Lance Taylor <iant@golang.org>2017-09-21 01:01:44 +0000
commit589ea93678850ad1e5c1192df5768177c3104937 (patch)
treea6ba4177df2d16ca506c5e683268a29f4bb3de2b /src/cmd/nm
parent6a537c1d4718f2804bbad983037b9a6e4b40bc60 (diff)
downloadgo-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.go71
-rw-r--r--src/cmd/nm/nm_cgo_test.go11
-rw-r--r--src/cmd/nm/nm_test.go55
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() {}