diff options
| author | Alex Brainman <alex.brainman@gmail.com> | 2015-07-06 15:52:33 +1000 |
|---|---|---|
| committer | Alex Brainman <alex.brainman@gmail.com> | 2015-07-10 03:33:38 +0000 |
| commit | 315e5c99d868bffad5ac75871e486d6f3a625f23 (patch) | |
| tree | cd63400692831a9d32062beeff1a48d1619715b1 /src/debug/pe | |
| parent | b615ad8fd57f9394db14e403d12061c369379c52 (diff) | |
| download | go-315e5c99d868bffad5ac75871e486d6f3a625f23.tar.xz | |
debug/pe: truncate pe sections to their size in memory
Section.Data returns disk section data, but those are rounded up to
some predefined value. Processing these as is confuses dwarf parser
because of garbage at the end. Truncate Section.Data as per memory
section description.
Sometimes dwarf sections have memory section size of 0
(for pe object files). Keep those to their disk size.
Fixes #11608
Change-Id: I8de0a2271201a24aa9ac8dac44f1e9c8a9285183
Reviewed-on: https://go-review.googlesource.com/11950
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/debug/pe')
| -rw-r--r-- | src/debug/pe/file.go | 3 | ||||
| -rw-r--r-- | src/debug/pe/file_test.go | 116 |
2 files changed, 94 insertions, 25 deletions
diff --git a/src/debug/pe/file.go b/src/debug/pe/file.go index 844dffc888..3df4ae7368 100644 --- a/src/debug/pe/file.go +++ b/src/debug/pe/file.go @@ -310,6 +310,9 @@ func (f *File) DWARF() (*dwarf.Data, error) { if err != nil && uint32(len(b)) < s.Size { return nil, err } + if 0 < s.VirtualSize && s.VirtualSize < s.Size { + b = b[:s.VirtualSize] + } dat[i] = b } diff --git a/src/debug/pe/file_test.go b/src/debug/pe/file_test.go index 0d73969bca..316a569ede 100644 --- a/src/debug/pe/file_test.go +++ b/src/debug/pe/file_test.go @@ -5,24 +5,30 @@ package pe import ( + "debug/dwarf" + "io/ioutil" + "os" + "os/exec" + "path/filepath" "reflect" + "runtime" "testing" ) type fileTest struct { - file string - hdr FileHeader - opthdr interface{} - sections []*SectionHeader - symbols []*Symbol + file string + hdr FileHeader + opthdr interface{} + sections []*SectionHeader + symbols []*Symbol + hasNoDwarfInfo bool } var fileTests = []fileTest{ { - "testdata/gcc-386-mingw-obj", - FileHeader{0x014c, 0x000c, 0x0, 0x64a, 0x1e, 0x0, 0x104}, - nil, - []*SectionHeader{ + file: "testdata/gcc-386-mingw-obj", + hdr: FileHeader{0x014c, 0x000c, 0x0, 0x64a, 0x1e, 0x0, 0x104}, + sections: []*SectionHeader{ {".text", 0, 0, 36, 500, 1440, 0, 3, 0, 0x60300020}, {".data", 0, 0, 0, 0, 0, 0, 0, 0, 3224371264}, {".bss", 0, 0, 0, 0, 0, 0, 0, 0, 3224371328}, @@ -36,7 +42,7 @@ var fileTests = []fileTest{ {".debug_pubtypes", 0, 0, 38, 1370, 1580, 0, 1, 0, 1108344832}, {".debug_aranges", 0, 0, 32, 1408, 1590, 0, 2, 0, 1108344832}, }, - []*Symbol{ + symbols: []*Symbol{ {".file", 0x0, -2, 0x0, 0x67}, {"_main", 0x0, 1, 0x20, 0x2}, {".text", 0x0, 1, 0x0, 0x3}, @@ -56,9 +62,9 @@ var fileTests = []fileTest{ }, }, { - "testdata/gcc-386-mingw-exec", - FileHeader{0x014c, 0x000f, 0x4c6a1b60, 0x3c00, 0x282, 0xe0, 0x107}, - &OptionalHeader32{ + file: "testdata/gcc-386-mingw-exec", + hdr: FileHeader{0x014c, 0x000f, 0x4c6a1b60, 0x3c00, 0x282, 0xe0, 0x107}, + opthdr: &OptionalHeader32{ 0x10b, 0x2, 0x38, 0xe00, 0x1a00, 0x200, 0x1160, 0x1000, 0x2000, 0x400000, 0x1000, 0x200, 0x4, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x10000, 0x400, 0x14abb, 0x3, 0x0, 0x200000, 0x1000, 0x100000, 0x1000, 0x0, 0x10, [16]DataDirectory{ {0x0, 0x0}, @@ -79,7 +85,7 @@ var fileTests = []fileTest{ {0x0, 0x0}, }, }, - []*SectionHeader{ + sections: []*SectionHeader{ {".text", 0xcd8, 0x1000, 0xe00, 0x400, 0x0, 0x0, 0x0, 0x0, 0x60500060}, {".data", 0x10, 0x2000, 0x200, 0x1200, 0x0, 0x0, 0x0, 0x0, 0xc0300040}, {".rdata", 0x120, 0x3000, 0x200, 0x1400, 0x0, 0x0, 0x0, 0x0, 0x40300040}, @@ -96,13 +102,11 @@ var fileTests = []fileTest{ {".debug_frame", 0x34, 0xe000, 0x200, 0x3800, 0x0, 0x0, 0x0, 0x0, 0x42300000}, {".debug_loc", 0x38, 0xf000, 0x200, 0x3a00, 0x0, 0x0, 0x0, 0x0, 0x42100000}, }, - []*Symbol{}, }, { - "testdata/gcc-amd64-mingw-obj", - FileHeader{0x8664, 0x6, 0x0, 0x198, 0x12, 0x0, 0x4}, - nil, - []*SectionHeader{ + file: "testdata/gcc-amd64-mingw-obj", + hdr: FileHeader{0x8664, 0x6, 0x0, 0x198, 0x12, 0x0, 0x4}, + sections: []*SectionHeader{ {".text", 0x0, 0x0, 0x30, 0x104, 0x15c, 0x0, 0x3, 0x0, 0x60500020}, {".data", 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0500040}, {".bss", 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0500080}, @@ -110,7 +114,7 @@ var fileTests = []fileTest{ {".xdata", 0x0, 0x0, 0xc, 0x144, 0x0, 0x0, 0x0, 0x0, 0x40300040}, {".pdata", 0x0, 0x0, 0xc, 0x150, 0x17a, 0x0, 0x3, 0x0, 0x40300040}, }, - []*Symbol{ + symbols: []*Symbol{ {".file", 0x0, -2, 0x0, 0x67}, {"main", 0x0, 1, 0x20, 0x2}, {".text", 0x0, 1, 0x0, 0x3}, @@ -122,11 +126,12 @@ var fileTests = []fileTest{ {"__main", 0x0, 0, 0x20, 0x2}, {"puts", 0x0, 0, 0x20, 0x2}, }, + hasNoDwarfInfo: true, }, { - "testdata/gcc-amd64-mingw-exec", - FileHeader{0x8664, 0x11, 0x53e4364f, 0x39600, 0x6fc, 0xf0, 0x27}, - &OptionalHeader64{ + file: "testdata/gcc-amd64-mingw-exec", + hdr: FileHeader{0x8664, 0x11, 0x53e4364f, 0x39600, 0x6fc, 0xf0, 0x27}, + opthdr: &OptionalHeader64{ 0x20b, 0x2, 0x16, 0x6a00, 0x2400, 0x1600, 0x14e0, 0x1000, 0x400000, 0x1000, 0x200, 0x4, 0x0, 0x0, 0x0, 0x5, 0x2, 0x0, 0x45000, 0x600, 0x46f19, 0x3, 0x0, 0x200000, 0x1000, 0x100000, 0x1000, 0x0, 0x10, [16]DataDirectory{ {0x0, 0x0}, @@ -146,7 +151,7 @@ var fileTests = []fileTest{ {0x0, 0x0}, {0x0, 0x0}, }}, - []*SectionHeader{ + sections: []*SectionHeader{ {".text", 0x6860, 0x1000, 0x6a00, 0x600, 0x0, 0x0, 0x0, 0x0, 0x60500020}, {".data", 0xe0, 0x8000, 0x200, 0x7000, 0x0, 0x0, 0x0, 0x0, 0xc0500040}, {".rdata", 0x6b0, 0x9000, 0x800, 0x7200, 0x0, 0x0, 0x0, 0x0, 0x40600040}, @@ -165,7 +170,6 @@ var fileTests = []fileTest{ {".debug_loc", 0x13240, 0x30000, 0x13400, 0x25600, 0x0, 0x0, 0x0, 0x0, 0x42100040}, {".debug_ranges", 0xa70, 0x44000, 0xc00, 0x38a00, 0x0, 0x0, 0x0, 0x0, 0x42100040}, }, - []*Symbol{}, }, } @@ -231,6 +235,12 @@ func TestOpen(t *testing.T) { t.Errorf("open %s, symbol %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want) } } + if !tt.hasNoDwarfInfo { + _, err = f.DWARF() + if err != nil { + t.Errorf("fetching %s dwarf details failed: %v", tt.file, err) + } + } } } @@ -241,3 +251,59 @@ func TestOpenFailure(t *testing.T) { t.Errorf("open %s: succeeded unexpectedly", filename) } } + +func TestDWARF(t *testing.T) { + if runtime.GOOS != "windows" { + t.Skip("skipping windows only test") + } + + tmpdir, err := ioutil.TempDir("", "TestDWARF") + if err != nil { + t.Fatal("TempDir failed: ", err) + } + defer os.RemoveAll(tmpdir) + + prog := ` +package main +func main() { +} +` + src := filepath.Join(tmpdir, "a.go") + exe := filepath.Join(tmpdir, "a.exe") + err = ioutil.WriteFile(src, []byte(prog), 0644) + output, err := exec.Command("go", "build", "-o", exe, src).CombinedOutput() + if err != nil { + t.Fatalf("building test executable failed: %s %s", err, output) + } + + f, err := Open(exe) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + d, err := f.DWARF() + if err != nil { + t.Fatal(err) + } + + // look for main.main + r := d.Reader() + for { + e, err := r.Next() + if err != nil { + t.Fatal("r.Next:", err) + } + if e == nil { + break + } + if e.Tag == dwarf.TagSubprogram { + for _, f := range e.Field { + if f.Attr == dwarf.AttrName && e.Val(dwarf.AttrName) == "main.main" { + return + } + } + } + } + t.Fatal("main.main not found") +} |
