Commit 6e8c7f5b authored by Alex Brainman's avatar Alex Brainman

cmd/nm: print symbol sizes for windows pe executables

Fixes #6973

LGTM=r
R=golang-codereviews, r
CC=golang-codereviews
https://golang.org/cl/88820043
parent 7c7aaa41
...@@ -9,6 +9,7 @@ package main ...@@ -9,6 +9,7 @@ package main
import ( import (
"debug/pe" "debug/pe"
"os" "os"
"sort"
) )
func peSymbols(f *os.File) []Sym { func peSymbols(f *os.File) []Sym {
...@@ -18,6 +19,10 @@ func peSymbols(f *os.File) []Sym { ...@@ -18,6 +19,10 @@ func peSymbols(f *os.File) []Sym {
return nil return nil
} }
// Build sorted list of addresses of all symbols.
// We infer the size of a symbol by looking at where the next symbol begins.
var addrs []uint64
var imageBase uint64 var imageBase uint64
switch oh := p.OptionalHeader.(type) { switch oh := p.OptionalHeader.(type) {
case *pe.OptionalHeader32: case *pe.OptionalHeader32:
...@@ -78,6 +83,15 @@ func peSymbols(f *os.File) []Sym { ...@@ -78,6 +83,15 @@ func peSymbols(f *os.File) []Sym {
sym.Addr += imageBase + uint64(sect.VirtualAddress) sym.Addr += imageBase + uint64(sect.VirtualAddress)
} }
syms = append(syms, sym) syms = append(syms, sym)
addrs = append(addrs, sym.Addr)
}
sort.Sort(uint64s(addrs))
for i := range syms {
j := sort.Search(len(addrs), func(x int) bool { return addrs[x] > syms[i].Addr })
if j < len(addrs) {
syms[i].Size = int64(addrs[j] - syms[i].Addr)
}
} }
return syms return syms
......
...@@ -8,9 +8,13 @@ enum { ...@@ -8,9 +8,13 @@ enum {
CacheLineSize = 64, CacheLineSize = 64,
#ifdef GOOS_solaris #ifdef GOOS_solaris
RuntimeGogoBytes = 80, RuntimeGogoBytes = 80,
#else
#ifdef GOOS_windows
RuntimeGogoBytes = 80,
#else #else
RuntimeGogoBytes = 64, RuntimeGogoBytes = 64,
#endif #endif // Windows
#endif // Solaris
PhysPageSize = 4096, PhysPageSize = 4096,
PCQuantum = 1 PCQuantum = 1
}; };
...@@ -95,10 +95,6 @@ func BenchmarkDeferMany(b *testing.B) { ...@@ -95,10 +95,6 @@ func BenchmarkDeferMany(b *testing.B) {
// The value reported will include the padding between runtime.gogo and the // The value reported will include the padding between runtime.gogo and the
// next function in memory. That's fine. // next function in memory. That's fine.
func TestRuntimeGogoBytes(t *testing.T) { func TestRuntimeGogoBytes(t *testing.T) {
// TODO(brainman): delete when issue 6973 is fixed.
if GOOS == "windows" {
t.Skip("skipping broken test on windows")
}
dir, err := ioutil.TempDir("", "go-build") dir, err := ioutil.TempDir("", "go-build")
if err != nil { if err != nil {
t.Fatalf("failed to create temp directory: %v", err) t.Fatalf("failed to create temp directory: %v", err)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment