mirror of
https://github.com/golang/go
synced 2024-11-23 07:20:06 -07:00
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>
This commit is contained in:
parent
b615ad8fd5
commit
315e5c99d8
@ -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
|
||||
}
|
||||
|
||||
|
@ -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")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user