diff options
author | Ian Lance Taylor <iant@google.com> | 2016-02-03 21:58:02 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2016-02-03 21:58:02 +0000 |
commit | f98dd1a338867a408f7c72d73fbad7fe7fc93e3a (patch) | |
tree | 2f8da9862a9c1fe0df138917f997b03439c02773 /libgo/go/debug/dwarf | |
parent | b081ed4efc144da0c45a6484aebfd10e0eb9fda3 (diff) | |
download | gcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.zip gcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.tar.gz gcc-f98dd1a338867a408f7c72d73fbad7fe7fc93e3a.tar.bz2 |
libgo: Update to go1.6rc1.
Reviewed-on: https://go-review.googlesource.com/19200
From-SVN: r233110
Diffstat (limited to 'libgo/go/debug/dwarf')
-rw-r--r-- | libgo/go/debug/dwarf/class_string.go | 7 | ||||
-rw-r--r-- | libgo/go/debug/dwarf/entry.go | 11 | ||||
-rw-r--r-- | libgo/go/debug/dwarf/entry_test.go | 36 | ||||
-rw-r--r-- | libgo/go/debug/dwarf/testdata/cycle.c | 7 | ||||
-rw-r--r-- | libgo/go/debug/dwarf/testdata/cycle.elf | bin | 0 -> 2624 bytes | |||
-rw-r--r-- | libgo/go/debug/dwarf/testdata/split.c | 5 | ||||
-rw-r--r-- | libgo/go/debug/dwarf/testdata/split.elf | bin | 0 -> 9509 bytes | |||
-rw-r--r-- | libgo/go/debug/dwarf/type.go | 34 | ||||
-rw-r--r-- | libgo/go/debug/dwarf/type_test.go | 34 | ||||
-rw-r--r-- | libgo/go/debug/dwarf/typeunit.go | 2 |
10 files changed, 121 insertions, 15 deletions
diff --git a/libgo/go/debug/dwarf/class_string.go b/libgo/go/debug/dwarf/class_string.go index 0b1206b..d57d9f7 100644 --- a/libgo/go/debug/dwarf/class_string.go +++ b/libgo/go/debug/dwarf/class_string.go @@ -4,14 +4,13 @@ package dwarf import "fmt" -const _Class_name = "ClassAddressClassBlockClassConstantClassExprLocClassFlagClassLinePtrClassLocListPtrClassMacPtrClassRangeListPtrClassReferenceClassReferenceSigClassStringClassReferenceAltClassStringAlt" +const _Class_name = "ClassUnknownClassAddressClassBlockClassConstantClassExprLocClassFlagClassLinePtrClassLocListPtrClassMacPtrClassRangeListPtrClassReferenceClassReferenceSigClassStringClassReferenceAltClassStringAlt" -var _Class_index = [...]uint8{0, 12, 22, 35, 47, 56, 68, 83, 94, 111, 125, 142, 153, 170, 184} +var _Class_index = [...]uint8{0, 12, 24, 34, 47, 59, 68, 80, 95, 106, 123, 137, 154, 165, 182, 196} func (i Class) String() string { - i -= 1 if i < 0 || i+1 >= Class(len(_Class_index)) { - return fmt.Sprintf("Class(%d)", i+1) + return fmt.Sprintf("Class(%d)", i) } return _Class_name[_Class_index[i]:_Class_index[i+1]] } diff --git a/libgo/go/debug/dwarf/entry.go b/libgo/go/debug/dwarf/entry.go index d607e5b..5ca8667 100644 --- a/libgo/go/debug/dwarf/entry.go +++ b/libgo/go/debug/dwarf/entry.go @@ -193,8 +193,7 @@ func formToClass(form format, attr Attr, vers int, b *buf) Class { if class, ok := attrPtrClass[attr]; ok { return class } - b.error("cannot determine class of unknown attribute with formSecOffset") - return 0 + return ClassUnknown case formExprloc: return ClassExprLoc @@ -235,6 +234,9 @@ type Entry struct { // loclistptr int64 ClassLocListPtr // macptr int64 ClassMacPtr // rangelistptr int64 ClassRangeListPtr +// +// For unrecognized or vendor-defined attributes, Class may be +// ClassUnknown. type Field struct { Attr Attr Val interface{} @@ -258,9 +260,12 @@ type Field struct { type Class int const ( + // ClassUnknown represents values of unknown DWARF class. + ClassUnknown Class = iota + // ClassAddress represents values of type uint64 that are // addresses on the target machine. - ClassAddress Class = 1 + iota + ClassAddress // ClassBlock represents values of type []byte whose // interpretation depends on the attribute. diff --git a/libgo/go/debug/dwarf/entry_test.go b/libgo/go/debug/dwarf/entry_test.go new file mode 100644 index 0000000..8bd2d2a --- /dev/null +++ b/libgo/go/debug/dwarf/entry_test.go @@ -0,0 +1,36 @@ +// Copyright 2009 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. + +package dwarf_test + +import ( + . "debug/dwarf" + "testing" +) + +func TestSplit(t *testing.T) { + // debug/dwarf doesn't (currently) support split DWARF, but + // the attributes that pointed to the split DWARF used to + // cause loading the DWARF data to fail entirely (issue + // #12592). Test that we can at least read the DWARF data. + d := elfData(t, "testdata/split.elf") + r := d.Reader() + e, err := r.Next() + if err != nil { + t.Fatal(err) + } + if e.Tag != TagCompileUnit { + t.Fatalf("bad tag: have %s, want %s", e.Tag, TagCompileUnit) + } + // Check that we were able to parse the unknown section offset + // field, even if we can't figure out its DWARF class. + const AttrGNUAddrBase Attr = 0x2133 + f := e.AttrField(AttrGNUAddrBase) + if _, ok := f.Val.(int64); !ok { + t.Fatalf("bad attribute value type: have %T, want int64", f.Val) + } + if f.Class != ClassUnknown { + t.Fatalf("bad class: have %s, want %s", f.Class, ClassUnknown) + } +} diff --git a/libgo/go/debug/dwarf/testdata/cycle.c b/libgo/go/debug/dwarf/testdata/cycle.c new file mode 100644 index 0000000..a0b53df --- /dev/null +++ b/libgo/go/debug/dwarf/testdata/cycle.c @@ -0,0 +1,7 @@ +typedef struct aaa *AAA; +typedef AAA BBB; +struct aaa { BBB val; }; + +AAA x(void) { + return (AAA)0; +} diff --git a/libgo/go/debug/dwarf/testdata/cycle.elf b/libgo/go/debug/dwarf/testdata/cycle.elf Binary files differnew file mode 100644 index 0000000..e0b66ca --- /dev/null +++ b/libgo/go/debug/dwarf/testdata/cycle.elf diff --git a/libgo/go/debug/dwarf/testdata/split.c b/libgo/go/debug/dwarf/testdata/split.c new file mode 100644 index 0000000..0ef3427 --- /dev/null +++ b/libgo/go/debug/dwarf/testdata/split.c @@ -0,0 +1,5 @@ +// gcc -gsplit-dwarf split.c -o split.elf + +int main() +{ +} diff --git a/libgo/go/debug/dwarf/testdata/split.elf b/libgo/go/debug/dwarf/testdata/split.elf Binary files differnew file mode 100644 index 0000000..99ee2c2 --- /dev/null +++ b/libgo/go/debug/dwarf/testdata/split.elf diff --git a/libgo/go/debug/dwarf/type.go b/libgo/go/debug/dwarf/type.go index a5daa1d..c76a472 100644 --- a/libgo/go/debug/dwarf/type.go +++ b/libgo/go/debug/dwarf/type.go @@ -275,12 +275,14 @@ type typeReader interface { // Type reads the type at off in the DWARF ``info'' section. func (d *Data) Type(off Offset) (Type, error) { - return d.readType("info", d.Reader(), off, d.typeCache) + return d.readType("info", d.Reader(), off, d.typeCache, nil) } -// readType reads a type from r at off of name using and updating a -// type cache. -func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Offset]Type) (Type, error) { +// readType reads a type from r at off of name. It adds types to the +// type cache, appends new typedef types to typedefs, and computes the +// sizes of types. Callers should pass nil for typedefs; this is used +// for internal recursion. +func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Offset]Type, typedefs *[]*TypedefType) (Type, error) { if t, ok := typeCache[off]; ok { return t, nil } @@ -294,9 +296,24 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off return nil, DecodeError{name, off, "no type at offset"} } + // If this is the root of the recursion, prepare to resolve + // typedef sizes once the recursion is done. This must be done + // after the type graph is constructed because it may need to + // resolve cycles in a different order than readType + // encounters them. + if typedefs == nil { + var typedefList []*TypedefType + defer func() { + for _, t := range typedefList { + t.Common().ByteSize = t.Type.Size() + } + }() + typedefs = &typedefList + } + // Parse type from Entry. // Must always set typeCache[off] before calling - // d.Type recursively, to handle circular types correctly. + // d.readType recursively, to handle circular types correctly. var typ Type nextDepth := 0 @@ -345,7 +362,7 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off var t Type switch toff := tval.(type) { case Offset: - if t, err = d.readType(name, r.clone(), toff, typeCache); err != nil { + if t, err = d.readType(name, r.clone(), toff, typeCache, typedefs); err != nil { return nil } case uint64: @@ -674,7 +691,10 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off b = -1 switch t := typ.(type) { case *TypedefType: - b = t.Type.Size() + // Record that we need to resolve this + // type's size once the type graph is + // constructed. + *typedefs = append(*typedefs, t) case *PtrType: b = int64(addressSize) } diff --git a/libgo/go/debug/dwarf/type_test.go b/libgo/go/debug/dwarf/type_test.go index 2cb85e7..ad6308d 100644 --- a/libgo/go/debug/dwarf/type_test.go +++ b/libgo/go/debug/dwarf/type_test.go @@ -120,3 +120,37 @@ func testTypedefs(t *testing.T, d *Data, kind string) { } } } + +func TestTypedefCycle(t *testing.T) { + // See issue #13039: reading a typedef cycle starting from a + // different place than the size needed to be computed from + // used to crash. + // + // cycle.elf built with GCC 4.8.4: + // gcc -g -c -o cycle.elf cycle.c + d := elfData(t, "testdata/cycle.elf") + r := d.Reader() + offsets := []Offset{} + for { + e, err := r.Next() + if err != nil { + t.Fatal("r.Next:", err) + } + if e == nil { + break + } + switch e.Tag { + case TagBaseType, TagTypedef, TagPointerType, TagStructType: + offsets = append(offsets, e.Offset) + } + } + + // Parse each type with a fresh type cache. + for _, offset := range offsets { + d := elfData(t, "testdata/cycle.elf") + _, err := d.Type(offset) + if err != nil { + t.Fatalf("d.Type(0x%x): %s", offset, err) + } + } +} diff --git a/libgo/go/debug/dwarf/typeunit.go b/libgo/go/debug/dwarf/typeunit.go index 9cfb4a8..0f4e07e 100644 --- a/libgo/go/debug/dwarf/typeunit.go +++ b/libgo/go/debug/dwarf/typeunit.go @@ -101,7 +101,7 @@ func (d *Data) sigToType(sig uint64) (Type, error) { b := makeBuf(d, tu, tu.name, tu.off, tu.data) r := &typeUnitReader{d: d, tu: tu, b: b} - t, err := d.readType(tu.name, r, Offset(tu.toff), make(map[Offset]Type)) + t, err := d.readType(tu.name, r, Offset(tu.toff), make(map[Offset]Type), nil) if err != nil { return nil, err } |