aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/symbolizer
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/symbolizer')
-rw-r--r--pkg/symbolizer/nm.go27
-rw-r--r--pkg/symbolizer/nm_test.go37
2 files changed, 40 insertions, 24 deletions
diff --git a/pkg/symbolizer/nm.go b/pkg/symbolizer/nm.go
index 01d23ab94..caa246629 100644
--- a/pkg/symbolizer/nm.go
+++ b/pkg/symbolizer/nm.go
@@ -18,7 +18,7 @@ type Symbol struct {
// ReadSymbols returns list of text symbols in the binary bin.
func ReadSymbols(bin string) (map[string][]Symbol, error) {
- cmd := osutil.Command("nm", "-nS", bin)
+ cmd := osutil.Command("nm", "-Ptx", bin)
stdout, err := cmd.StdoutPipe()
if err != nil {
return nil, err
@@ -32,32 +32,39 @@ func ReadSymbols(bin string) (map[string][]Symbol, error) {
s := bufio.NewScanner(stdout)
text := [][]byte{[]byte(" t "), []byte(" T ")}
for s.Scan() {
- // A line looks as: "ffffffff8104db90 0000000000000059 t snb_uncore_msr_enable_box"
+ // A line looks as: "snb_uncore_msr_enable_box t ffffffff8104db90 0000000000000059"
ln := s.Bytes()
if !bytes.Contains(ln, text[0]) && !bytes.Contains(ln, text[1]) {
continue
}
+
sp1 := bytes.IndexByte(ln, ' ')
if sp1 == -1 {
continue
}
- sp2 := bytes.IndexByte(ln[sp1+1:], ' ')
- if sp2 == -1 {
+ if !bytes.HasPrefix(ln[sp1:], text[0]) && !bytes.HasPrefix(ln[sp1:], text[1]) {
continue
}
- sp2 += sp1 + 1
- if !bytes.HasPrefix(ln[sp2:], text[0]) && !bytes.HasPrefix(ln[sp2:], text[1]) {
+
+ sp2 := sp1 + len(text[0])
+ sp3 := bytes.IndexByte(ln[sp2:], ' ')
+ if sp3 == -1 {
continue
}
- addr, err := strconv.ParseUint(string(ln[:sp1]), 16, 64)
+ sp3 += sp2
+
+ addr, err := strconv.ParseUint(string(ln[sp2:sp3]), 16, 64)
if err != nil {
continue
}
- size, err := strconv.ParseUint(string(ln[sp1+1:sp2]), 16, 64)
- if err != nil {
+
+ size, err := strconv.ParseUint(string(ln[sp3+1:]), 16, 64)
+ if err != nil || size == 0 {
continue
}
- name := string(ln[sp2+len(text[0]):])
+
+ name := string(ln[:sp1])
+
// Note: sizes reported by kernel do not match nm.
// Kernel probably subtracts address of this symbol from address of the next symbol.
// We could do the same, but for now we just round up size to 16.
diff --git a/pkg/symbolizer/nm_test.go b/pkg/symbolizer/nm_test.go
index 7aca6cb67..44a02f3cc 100644
--- a/pkg/symbolizer/nm_test.go
+++ b/pkg/symbolizer/nm_test.go
@@ -4,15 +4,10 @@
package symbolizer
import (
- "runtime"
"testing"
)
func TestSymbols(t *testing.T) {
- if runtime.GOOS != "linux" {
- // On openbsd it fails because nm does not have -S flag.
- t.Skipf("broken on %v", runtime.GOOS)
- }
symbols, err := ReadSymbols("testdata/nm.test.out")
if err != nil {
t.Fatalf("failed to read symbols: %v", err)
@@ -37,17 +32,31 @@ func TestSymbols(t *testing.T) {
if len(s) != 2 {
t.Fatalf("got %v foobar symbols, want 2", len(s))
}
- if s[0].Addr != 0x4004ed {
- t.Fatalf("bad foobar[0] address: 0x%x", s[0].Addr)
- }
- if s[0].Size != 0x10 {
- t.Fatalf("bad foobar[0] size: 0x%x", s[0].Size)
+ want := []Symbol{
+ {
+ Addr: 0x4004fa,
+ Size: 0x10,
+ },
+ {
+ Addr: 0x4004ed,
+ Size: 0x10,
+ },
}
- if s[1].Addr != 0x4004fa {
- t.Fatalf("bad foobar[1] address: 0x%x", s[1].Addr)
+ if !symcmp(want[0], s[0]) && !symcmp(want[0], s[1]) {
+ t.Fatalf("foobar symbol %+v not found", want[0])
}
- if s[1].Size != 0x10 {
- t.Fatalf("bad foobar[1] size: 0x%x", s[1].Size)
+ if !symcmp(want[1], s[0]) && !symcmp(want[1], s[1]) {
+ t.Fatalf("foobar symbol %+v not found", want[1])
}
}
}
+
+func symcmp(want Symbol, got Symbol) bool {
+ if want.Addr != got.Addr {
+ return false
+ }
+ if want.Size != got.Size {
+ return false
+ }
+ return true
+}