summaryrefslogtreecommitdiff
path: root/libgo/go/debug
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2019-09-06 18:12:46 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-09-06 18:12:46 +0000
commitaa8901e9bb0399d2c16f988ba2fe46eb0c0c5d13 (patch)
tree7e63b06d1eec92beec6997c9d3ab47a5d6a835be /libgo/go/debug
parent920ea3b8ba3164b61ac9490dfdfceb6936eda6dd (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.cc34
-rw-r--r--libgo/go/debug/dwarf/testdata/cppunsuptypes.elfbin0 -> 3920 bytes
-rw-r--r--libgo/go/debug/dwarf/type.go24
-rw-r--r--libgo/go/debug/dwarf/type_test.go60
-rw-r--r--libgo/go/debug/elf/file.go7
-rw-r--r--libgo/go/debug/elf/file_test.go11
-rw-r--r--libgo/go/debug/gosym/pclntab.go6
-rw-r--r--libgo/go/debug/gosym/pclntab_test.go5
-rw-r--r--libgo/go/debug/gosym/symtab.go14
-rw-r--r--libgo/go/debug/gosym/symtab_test.go15
-rw-r--r--libgo/go/debug/macho/file_test.go6
-rw-r--r--libgo/go/debug/macho/macho.go7
-rw-r--r--libgo/go/debug/pe/file.go6
-rw-r--r--libgo/go/debug/pe/file_test.go50
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
new file mode 100644
index 00000000000..e955512ecd0
--- /dev/null
+++ b/libgo/go/debug/dwarf/testdata/cppunsuptypes.elf
Binary files differ
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()
+ }
+}