diff options
author | Ian Lance Taylor <iant@golang.org> | 2019-09-06 18:12:46 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-09-06 18:12:46 +0000 |
commit | aa8901e9bb0399d2c16f988ba2fe46eb0c0c5d13 (patch) | |
tree | 7e63b06d1eec92beec6997c9d3ab47a5d6a835be /libgo/go/debug | |
parent | 920ea3b8ba3164b61ac9490dfdfceb6936eda6dd (diff) |
libgo: update to Go 1.13beta1 release
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/193497
From-SVN: r275473
Diffstat (limited to 'libgo/go/debug')
-rw-r--r-- | libgo/go/debug/dwarf/testdata/cppunsuptypes.cc | 34 | ||||
-rw-r--r-- | libgo/go/debug/dwarf/testdata/cppunsuptypes.elf | bin | 0 -> 3920 bytes | |||
-rw-r--r-- | libgo/go/debug/dwarf/type.go | 24 | ||||
-rw-r--r-- | libgo/go/debug/dwarf/type_test.go | 60 | ||||
-rw-r--r-- | libgo/go/debug/elf/file.go | 7 | ||||
-rw-r--r-- | libgo/go/debug/elf/file_test.go | 11 | ||||
-rw-r--r-- | libgo/go/debug/gosym/pclntab.go | 6 | ||||
-rw-r--r-- | libgo/go/debug/gosym/pclntab_test.go | 5 | ||||
-rw-r--r-- | libgo/go/debug/gosym/symtab.go | 14 | ||||
-rw-r--r-- | libgo/go/debug/gosym/symtab_test.go | 15 | ||||
-rw-r--r-- | libgo/go/debug/macho/file_test.go | 6 | ||||
-rw-r--r-- | libgo/go/debug/macho/macho.go | 7 | ||||
-rw-r--r-- | libgo/go/debug/pe/file.go | 6 | ||||
-rw-r--r-- | libgo/go/debug/pe/file_test.go | 50 |
14 files changed, 232 insertions, 13 deletions
diff --git a/libgo/go/debug/dwarf/testdata/cppunsuptypes.cc b/libgo/go/debug/dwarf/testdata/cppunsuptypes.cc new file mode 100644 index 00000000000..e9281c7dec7 --- /dev/null +++ b/libgo/go/debug/dwarf/testdata/cppunsuptypes.cc @@ -0,0 +1,34 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// cppunsuptypes.elf built with g++ 7.3 +// g++ -g -c -o cppunsuptypes.elf cppunsuptypes.cc + +int i = 3; +double d = 3; + +// anonymous reference type +int &culprit = i; + +// named reference type +typedef double &dref; +dref dr = d; + +// incorporated into another type +typedef struct { + dref q; + int &r; +} hasrefs; + +hasrefs hr = { d, i }; + +// This code is intended to trigger a DWARF "pointer to member" type DIE +struct CS { int dm; }; + +int foo() +{ + int CS::* pdm = &CS::dm; + CS cs = {42}; + return cs.*pdm; +} diff --git a/libgo/go/debug/dwarf/testdata/cppunsuptypes.elf b/libgo/go/debug/dwarf/testdata/cppunsuptypes.elf Binary files differnew file mode 100644 index 00000000000..e955512ecd0 --- /dev/null +++ b/libgo/go/debug/dwarf/testdata/cppunsuptypes.elf diff --git a/libgo/go/debug/dwarf/type.go b/libgo/go/debug/dwarf/type.go index 4352092ed0d..316db258f65 100644 --- a/libgo/go/debug/dwarf/type.go +++ b/libgo/go/debug/dwarf/type.go @@ -261,6 +261,20 @@ func (t *TypedefType) String() string { return t.Name } func (t *TypedefType) Size() int64 { return t.Type.Size() } +// An UnsupportedType is a placeholder returned in situations where we +// encounter a type that isn't supported. +type UnsupportedType struct { + CommonType + Tag Tag +} + +func (t *UnsupportedType) String() string { + if t.Name != "" { + return t.Name + } + return t.Name + "(unsupported type " + t.Tag.String() + ")" +} + // typeReader is used to read from either the info section or the // types section. type typeReader interface { @@ -680,6 +694,16 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off typ = t typeCache[off] = t t.Name, _ = e.Val(AttrName).(string) + + default: + // This is some other type DIE that we're currently not + // equipped to handle. Return an abstract "unsupported type" + // object in such cases. + t := new(UnsupportedType) + typ = t + typeCache[off] = t + t.Tag = e.Tag + t.Name, _ = e.Val(AttrName).(string) } if err != nil { diff --git a/libgo/go/debug/dwarf/type_test.go b/libgo/go/debug/dwarf/type_test.go index 6c06731ea18..aa2fbeca0b3 100644 --- a/libgo/go/debug/dwarf/type_test.go +++ b/libgo/go/debug/dwarf/type_test.go @@ -9,6 +9,8 @@ import ( "debug/elf" "debug/macho" "debug/pe" + "fmt" + "strconv" "testing" ) @@ -168,3 +170,61 @@ func TestTypedefCycle(t *testing.T) { } } } + +var unsupportedTypeTests = []string{ + // varname:typename:string:size + "culprit::(unsupported type ReferenceType):8", + "pdm::(unsupported type PtrToMemberType):-1", +} + +func TestUnsupportedTypes(t *testing.T) { + // Issue 29601: + // When reading DWARF from C++ load modules, we can encounter + // oddball type DIEs. These will be returned as "UnsupportedType" + // objects; check to make sure this works properly. + d := elfData(t, "testdata/cppunsuptypes.elf") + r := d.Reader() + seen := make(map[string]bool) + for { + e, err := r.Next() + if err != nil { + t.Fatal("r.Next:", err) + } + if e == nil { + break + } + if e.Tag == TagVariable { + vname, _ := e.Val(AttrName).(string) + tAttr := e.Val(AttrType) + typOff, ok := tAttr.(Offset) + if !ok { + t.Errorf("variable at offset %v has no type", e.Offset) + continue + } + typ, err := d.Type(typOff) + if err != nil { + t.Errorf("err in type decode: %v\n", err) + continue + } + unsup, isok := typ.(*UnsupportedType) + if !isok { + continue + } + tag := vname + ":" + unsup.Name + ":" + unsup.String() + + ":" + strconv.FormatInt(unsup.Size(), 10) + seen[tag] = true + } + } + dumpseen := false + for _, v := range unsupportedTypeTests { + if !seen[v] { + t.Errorf("missing %s", v) + dumpseen = true + } + } + if dumpseen { + for k, _ := range seen { + fmt.Printf("seen: %s\n", k) + } + } +} diff --git a/libgo/go/debug/elf/file.go b/libgo/go/debug/elf/file.go index bd6146437c9..1a5424f54e8 100644 --- a/libgo/go/debug/elf/file.go +++ b/libgo/go/debug/elf/file.go @@ -276,7 +276,6 @@ func NewFile(r io.ReaderAt) (*File, error) { var phentsize, phnum int var shoff int64 var shentsize, shnum, shstrndx int - shstrndx = -1 switch f.Class { case ELFCLASS32: hdr := new(Header32) @@ -318,7 +317,11 @@ func NewFile(r io.ReaderAt) (*File, error) { shstrndx = int(hdr.Shstrndx) } - if shnum > 0 && shoff > 0 && (shstrndx < 0 || shstrndx >= shnum) { + if shoff == 0 && shnum != 0 { + return nil, &FormatError{0, "invalid ELF shnum for shoff=0", shnum} + } + + if shnum > 0 && shstrndx >= shnum { return nil, &FormatError{0, "invalid ELF shstrndx", shstrndx} } diff --git a/libgo/go/debug/elf/file_test.go b/libgo/go/debug/elf/file_test.go index d7c1e9f800d..b826a0ff050 100644 --- a/libgo/go/debug/elf/file_test.go +++ b/libgo/go/debug/elf/file_test.go @@ -810,3 +810,14 @@ func TestNoSectionOverlaps(t *testing.T) { } } } + +func TestIssue10996(t *testing.T) { + data := []byte("\u007fELF\x02\x01\x010000000000000" + + "\x010000000000000000000" + + "\x00\x00\x00\x00\x00\x00\x00\x0000000000\x00\x00\x00\x00" + + "0000") + _, err := NewFile(bytes.NewReader(data)) + if err == nil { + t.Fatalf("opening invalid ELF file unexpectedly suceeded") + } +} diff --git a/libgo/go/debug/gosym/pclntab.go b/libgo/go/debug/gosym/pclntab.go index ad99b4dc5a6..7e54a943510 100644 --- a/libgo/go/debug/gosym/pclntab.go +++ b/libgo/go/debug/gosym/pclntab.go @@ -93,7 +93,8 @@ func (t *LineTable) slice(pc uint64) *LineTable { } // PCToLine returns the line number for the given program counter. -// Callers should use Table's PCToLine method instead. +// +// Deprecated: Use Table's PCToLine method instead. func (t *LineTable) PCToLine(pc uint64) int { if t.isGo12() { return t.go12PCToLine(pc) @@ -104,7 +105,8 @@ func (t *LineTable) PCToLine(pc uint64) int { // LineToPC returns the program counter for the given line number, // considering only program counters before maxpc. -// Callers should use Table's LineToPC method instead. +// +// Deprecated: Use Table's LineToPC method instead. func (t *LineTable) LineToPC(line int, maxpc uint64) uint64 { if t.isGo12() { return 0 diff --git a/libgo/go/debug/gosym/pclntab_test.go b/libgo/go/debug/gosym/pclntab_test.go index d21f0e24a83..6baa53defd1 100644 --- a/libgo/go/debug/gosym/pclntab_test.go +++ b/libgo/go/debug/gosym/pclntab_test.go @@ -55,7 +55,7 @@ func endtest() { // These tests open and examine the test binary, and use elf.Open to do so. func skipIfNotELF(t *testing.T) { switch runtime.GOOS { - case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris": + case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris", "illumos": // OK. default: t.Skipf("skipping on non-ELF system %s", runtime.GOOS) @@ -196,6 +196,9 @@ func TestLineAline(t *testing.T) { } func TestPCLine(t *testing.T) { + if testing.Short() { + t.Skip("skipping in -short mode") + } dotest(t) defer endtest() diff --git a/libgo/go/debug/gosym/symtab.go b/libgo/go/debug/gosym/symtab.go index a84b7f6def1..3be612e1df7 100644 --- a/libgo/go/debug/gosym/symtab.go +++ b/libgo/go/debug/gosym/symtab.go @@ -35,13 +35,21 @@ func (s *Sym) Static() bool { return s.Type >= 'a' } // PackageName returns the package part of the symbol name, // or the empty string if there is none. func (s *Sym) PackageName() string { - pathend := strings.LastIndex(s.Name, "/") + name := s.Name + + // A prefix of "type." and "go." is a compiler-generated symbol that doesn't belong to any package. + // See variable reservedimports in cmd/compile/internal/gc/subr.go + if strings.HasPrefix(name, "go.") || strings.HasPrefix(name, "type.") { + return "" + } + + pathend := strings.LastIndex(name, "/") if pathend < 0 { pathend = 0 } - if i := strings.Index(s.Name[pathend:], "."); i != -1 { - return s.Name[:pathend+i] + if i := strings.Index(name[pathend:], "."); i != -1 { + return name[:pathend+i] } return "" } diff --git a/libgo/go/debug/gosym/symtab_test.go b/libgo/go/debug/gosym/symtab_test.go index 08e86336b8e..b6ed8f554c5 100644 --- a/libgo/go/debug/gosym/symtab_test.go +++ b/libgo/go/debug/gosym/symtab_test.go @@ -41,3 +41,18 @@ func TestRemotePackage(t *testing.T) { assertString(t, fmt.Sprintf("receiver of %q", s1.Name), s1.ReceiverName(), "(*FlagSet)") assertString(t, fmt.Sprintf("receiver of %q", s2.Name), s2.ReceiverName(), "") } + +func TestIssue29551(t *testing.T) { + symNames := []string{ + "type..eq.[9]debug/elf.intName", + "type..hash.debug/elf.ProgHeader", + "type..eq.runtime._panic", + "type..hash.struct { runtime.gList; runtime.n int32 }", + "go.(*struct { sync.Mutex; math/big.table [64]math/big", + } + + for _, symName := range symNames { + s := Sym{Name: symName} + assertString(t, fmt.Sprintf("package of %q", s.Name), s.PackageName(), "") + } +} diff --git a/libgo/go/debug/macho/file_test.go b/libgo/go/debug/macho/file_test.go index 003c14e69b1..28b76f93d7a 100644 --- a/libgo/go/debug/macho/file_test.go +++ b/libgo/go/debug/macho/file_test.go @@ -154,7 +154,7 @@ var fileTests = []fileTest{ nil, nil, map[string][]Reloc{ - "__text": []Reloc{ + "__text": { { Addr: 0x1d, Type: uint8(GENERIC_RELOC_VANILLA), @@ -189,7 +189,7 @@ var fileTests = []fileTest{ nil, nil, map[string][]Reloc{ - "__text": []Reloc{ + "__text": { { Addr: 0x19, Type: uint8(X86_64_RELOC_BRANCH), @@ -207,7 +207,7 @@ var fileTests = []fileTest{ Value: 2, }, }, - "__compact_unwind": []Reloc{ + "__compact_unwind": { { Addr: 0x0, Type: uint8(X86_64_RELOC_UNSIGNED), diff --git a/libgo/go/debug/macho/macho.go b/libgo/go/debug/macho/macho.go index 7bc1950bfdb..49e107eed3d 100644 --- a/libgo/go/debug/macho/macho.go +++ b/libgo/go/debug/macho/macho.go @@ -3,7 +3,12 @@ // license that can be found in the LICENSE file. // Mach-O header data structures -// http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html +// Originally at: +// http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html (since deleted by Apply) +// Archived copy at: +// https://web.archive.org/web/20090819232456/http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachORuntime/index.html +// For cloned PDF see: +// https://github.com/aidansteele/osx-abi-macho-file-format-reference package macho diff --git a/libgo/go/debug/pe/file.go b/libgo/go/debug/pe/file.go index 1c308b3dc3b..58814162bcf 100644 --- a/libgo/go/debug/pe/file.go +++ b/libgo/go/debug/pe/file.go @@ -324,6 +324,10 @@ type ImportDirectory struct { // satisfied by other libraries at dynamic load time. // It does not return weak symbols. func (f *File) ImportedSymbols() ([]string, error) { + if f.OptionalHeader == nil { + return nil, nil + } + pe64 := f.Machine == IMAGE_FILE_MACHINE_AMD64 // grab the number of data directory entries @@ -373,7 +377,7 @@ func (f *File) ImportedSymbols() ([]string, error) { // start decoding the import directory var ida []ImportDirectory - for len(d) > 0 { + for len(d) >= 20 { var dt ImportDirectory dt.OriginalFirstThunk = binary.LittleEndian.Uint32(d[0:4]) dt.TimeDateStamp = binary.LittleEndian.Uint32(d[4:8]) diff --git a/libgo/go/debug/pe/file_test.go b/libgo/go/debug/pe/file_test.go index 9613af3a3c3..6c7fe13caf0 100644 --- a/libgo/go/debug/pe/file_test.go +++ b/libgo/go/debug/pe/file_test.go @@ -5,6 +5,7 @@ package pe import ( + "bytes" "debug/dwarf" "internal/testenv" "io/ioutil" @@ -627,3 +628,52 @@ func TestImportTableInUnknownSection(t *testing.T) { t.Fatalf("unable to locate any imported symbols within file %q.", path) } } + +func TestInvalidFormat(t *testing.T) { + crashers := [][]byte{ + // https://golang.org/issue/30250 + []byte("\x00\x00\x00\x0000000\x00\x00\x00\x00\x00\x00\x000000" + + "00000000000000000000" + + "000000000\x00\x00\x0000000000" + + "00000000000000000000" + + "0000000000000000"), + // https://golang.org/issue/30253 + []byte("L\x01\b\x00regi\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x00\x0f\x03" + + "\v\x01\x02\x18\x00\x0e\x00\x00\x00\x1e\x00\x00\x00\x02\x00\x00\x80\x12\x00\x00" + + "\x00\x10\x00\x00\x00 \x00\x00\x00\x00@\x00\x00\x10\x00\x00\x00\x02\x00\x00" + + "\x04\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00" + + "\x00\x04\x00\x00\x06S\x00\x00\x03\x00\x00\x00\x00\x00 \x00\x00\x10\x00\x00" + + "\x00\x00\x10\x00\x00\x10\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00`\x00\x00x\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x04\x80\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb8`\x00\x00|\x00\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x00\x00\x00\x00.text\x00\x00\x00d\f\x00\x00\x00\x10\x00\x00" + + "\x00\x0e\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "`\x00P`.data\x00\x00\x00\x10\x00\x00\x00\x00 \x00\x00" + + "\x00\x02\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "@\x000\xc0.rdata\x00\x004\x01\x00\x00\x000\x00\x00" + + "\x00\x02\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "@\x000@.eh_fram\xa0\x03\x00\x00\x00@\x00\x00" + + "\x00\x04\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "@\x000@.bss\x00\x00\x00\x00`\x00\x00\x00\x00P\x00\x00" + + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + + "\x80\x000\xc0.idata\x00\x00x\x03\x00\x00\x00`\x00\x00" + + "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00" + + "0\xc0.CRT\x00\x00\x00\x00\x18\x00\x00\x00\x00p\x00\x00\x00\x02" + + "\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x00" + + "0\xc0.tls\x00\x00\x00\x00 \x00\x00\x00\x00\x80\x00\x00\x00\x02" + + "\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001\xc9" + + "H\x895\x1d"), + } + + for _, data := range crashers { + f, err := NewFile(bytes.NewReader(data)) + if err != nil { + t.Error(err) + } + f.ImportedSymbols() + } +} |