]> Cypherpunks repositories - gostls13.git/commitdiff
debug/dwarf: add DWARF attribute value class to Field
authorAustin Clements <austin@google.com>
Thu, 2 Apr 2015 15:19:00 +0000 (11:19 -0400)
committerAustin Clements <austin@google.com>
Sun, 12 Apr 2015 14:37:35 +0000 (14:37 +0000)
To return DWARF attribute values, debug/dwarf maps the DWARF attribute
value classes to Go types. Unfortunately, this mapping is ambiguous in
a way that makes it impossible to correctly interpret some DWARF
attributes as of DWARF 4. For example, AttrStartScope can be either a
constant or a rangelistptr. The attribute is interpreted differently
depending on its class, but debug/dwarf maps both classes to int64, so
the caller can't distinguish them from the Go type.
AttrDataMemberLocation is similar.

To address this, this change adds a field to type Field that indicates
the exact DWARF attribute value class of that field's value. This
makes it possible to distinguish value classes that can't be
distinguished by their Go type alone.

The root of this type ambiguity was DWARF itself. For example, DWARF 2
made no distinction between constants that were just constants and
constants that were section offsets because no attribute could have
both meanings. Hence, the single int64 type was sufficient. To avoid
introducing just another layer of ambiguity, this change takes pains
to canonicalize ambiguous classes in DWARF 2 and 3 files into the
unambiguous classes of DWARF 4.

Of course, there's no guarantee that future DWARF versions won't do
the same thing again and further subdivide the DWARF 4 classes. This
change gets ahead of this somewhat by distinguishing the various *ptr
classes even though the encoding does not. If there's some other form
of split, we can handle this in a backwards-compatible way by
introducing, for example, a Class5 field and type.

Change-Id: I4ef96d1223b0fd7f96ecf44fcc0e704a36af02b4
Reviewed-on: https://go-review.googlesource.com/8502
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/debug/dwarf/class_string.go [new file with mode: 0644]
src/debug/dwarf/entry.go
src/debug/dwarf/typeunit.go
src/debug/dwarf/unit.go
src/debug/elf/file_test.go

diff --git a/src/debug/dwarf/class_string.go b/src/debug/dwarf/class_string.go
new file mode 100644 (file)
index 0000000..6fd212f
--- /dev/null
@@ -0,0 +1,17 @@
+// generated by stringer -type=Class; DO NOT EDIT
+
+package dwarf
+
+import "fmt"
+
+const _Class_name = "ClassAddressClassBlockClassConstantClassExprLocClassFlagClassLinePtrClassLocListPtrClassMacPtrClassRangeListPtrClassReferenceClassStringClassReferenceAltClassStringAlt"
+
+var _Class_index = [...]uint8{0, 12, 22, 35, 47, 56, 68, 83, 94, 111, 125, 136, 153, 167}
+
+func (i Class) String() string {
+       i -= 1
+       if i < 0 || i+1 >= Class(len(_Class_index)) {
+               return fmt.Sprintf("Class(%d)", i+1)
+       }
+       return _Class_name[_Class_index[i]:_Class_index[i+1]]
+}
index 5a21da0e9eb42bfd4d419761e0ef42c48c5d57b8..760ddec5a434cc7aefa4d58cefd473e0aa3ab58e 100644 (file)
@@ -23,8 +23,9 @@ type abbrev struct {
 }
 
 type afield struct {
-       attr Attr
-       fmt  format
+       attr  Attr
+       fmt   format
+       class Class
 }
 
 // a map from entry format ids to their descriptions
@@ -32,7 +33,7 @@ type abbrevTable map[uint32]abbrev
 
 // ParseAbbrev returns the abbreviation table that starts at byte off
 // in the .debug_abbrev section.
-func (d *Data) parseAbbrev(off uint32) (abbrevTable, error) {
+func (d *Data) parseAbbrev(off uint32, vers int) (abbrevTable, error) {
        if m, ok := d.abbrevCache[off]; ok {
                return m, nil
        }
@@ -80,6 +81,7 @@ func (d *Data) parseAbbrev(off uint32) (abbrevTable, error) {
                for i := range a.field {
                        a.field[i].attr = Attr(b.uint())
                        a.field[i].fmt = format(b.uint())
+                       a.field[i].class = formToClass(a.field[i].fmt, a.field[i].attr, vers, &b)
                }
                b.uint()
                b.uint()
@@ -93,6 +95,118 @@ func (d *Data) parseAbbrev(off uint32) (abbrevTable, error) {
        return m, nil
 }
 
+// attrIsExprloc indicates attributes that allow exprloc values that
+// are encoded as block values in DWARF 2 and 3. See DWARF 4, Figure
+// 20.
+var attrIsExprloc = map[Attr]bool{
+       AttrLocation:      true,
+       AttrByteSize:      true,
+       AttrBitOffset:     true,
+       AttrBitSize:       true,
+       AttrStringLength:  true,
+       AttrLowerBound:    true,
+       AttrReturnAddr:    true,
+       AttrStrideSize:    true,
+       AttrUpperBound:    true,
+       AttrCount:         true,
+       AttrDataMemberLoc: true,
+       AttrFrameBase:     true,
+       AttrSegment:       true,
+       AttrStaticLink:    true,
+       AttrUseLocation:   true,
+       AttrVtableElemLoc: true,
+       AttrAllocated:     true,
+       AttrAssociated:    true,
+       AttrDataLocation:  true,
+       AttrStride:        true,
+}
+
+// attrPtrClass indicates the *ptr class of attributes that have
+// encoding formSecOffset in DWARF 4 or formData* in DWARF 2 and 3.
+var attrPtrClass = map[Attr]Class{
+       AttrLocation:      ClassLocListPtr,
+       AttrStmtList:      ClassLinePtr,
+       AttrStringLength:  ClassLocListPtr,
+       AttrReturnAddr:    ClassLocListPtr,
+       AttrStartScope:    ClassRangeListPtr,
+       AttrDataMemberLoc: ClassLocListPtr,
+       AttrFrameBase:     ClassLocListPtr,
+       AttrMacroInfo:     ClassMacPtr,
+       AttrSegment:       ClassLocListPtr,
+       AttrStaticLink:    ClassLocListPtr,
+       AttrUseLocation:   ClassLocListPtr,
+       AttrVtableElemLoc: ClassLocListPtr,
+       AttrRanges:        ClassRangeListPtr,
+}
+
+// formToClass returns the DWARF 4 Class for the given form. If the
+// DWARF version is less then 4, it will disambiguate some forms
+// depending on the attribute.
+func formToClass(form format, attr Attr, vers int, b *buf) Class {
+       switch form {
+       default:
+               b.error("cannot determine class of unknown attribute form")
+               return 0
+
+       case formAddr:
+               return ClassAddress
+
+       case formDwarfBlock1, formDwarfBlock2, formDwarfBlock4, formDwarfBlock:
+               // In DWARF 2 and 3, ClassExprLoc was encoded as a
+               // block. DWARF 4 distinguishes ClassBlock and
+               // ClassExprLoc, but there are no attributes that can
+               // be both, so we also promote ClassBlock values in
+               // DWARF 4 that should be ClassExprLoc in case
+               // producers get this wrong.
+               if attrIsExprloc[attr] {
+                       return ClassExprLoc
+               }
+               return ClassBlock
+
+       case formData1, formData2, formData4, formData8, formSdata, formUdata:
+               // In DWARF 2 and 3, ClassPtr was encoded as a
+               // constant. Unlike ClassExprLoc/ClassBlock, some
+               // DWARF 4 attributes need to distinguish Class*Ptr
+               // from ClassConstant, so we only do this promotion
+               // for versions 2 and 3.
+               if class, ok := attrPtrClass[attr]; vers < 4 && ok {
+                       return class
+               }
+               return ClassConstant
+
+       case formFlag, formFlagPresent:
+               return ClassFlag
+
+       case formRefAddr, formRef1, formRef2, formRef4, formRef8, formRefUdata:
+               return ClassReference
+
+       case formRefSig8:
+               return ClassReferenceSig
+
+       case formString, formStrp:
+               return ClassString
+
+       case formSecOffset:
+               // DWARF 4 defines four *ptr classes, but doesn't
+               // distinguish them in the encoding. Disambiguate
+               // these classes using the attribute.
+               if class, ok := attrPtrClass[attr]; ok {
+                       return class
+               }
+               b.error("cannot determine class of unknown attribute with formSecOffset")
+               return 0
+
+       case formExprloc:
+               return ClassExprLoc
+
+       case formGnuRefAlt:
+               return ClassReferenceAlt
+
+       case formGnuStrpAlt:
+               return ClassStringAlt
+       }
+}
+
 // An entry is a sequence of attribute/value pairs.
 type Entry struct {
        Offset   Offset // offset of Entry in DWARF info
@@ -106,24 +220,111 @@ type Entry struct {
 // A value can be one of several "attribute classes" defined by DWARF.
 // The Go types corresponding to each class are:
 //
-//    Class             Go type
-//    -----             -------
-//    address           uint64
-//    block             []byte
-//    constant          int64
-//    flag              bool
+//    DWARF class       Go type        Class
+//    -----------       -------        -----
+//    address           uint64         ClassAddress
+//    block             []byte         ClassBlock
+//    constant          int64          ClassConstant
+//    flag              bool           ClassFlag
 //    reference
-//      to info         dwarf.Offset (for use with Reader.Seek)
-//      to type unit    uint64 (type signature)
-//    string            string
-//    exprloc           []byte
-//    lineptr           int64
-//    loclistptr        int64
-//    macptr            int64
-//    rangelistptr      int64
+//      to info         dwarf.Offset   ClassReference
+//      to type unit    uint64         ClassReferenceSig
+//    string            string         ClassString
+//    exprloc           []byte         ClassExprLoc
+//    lineptr           int64          ClassLinePtr
+//    loclistptr        int64          ClassLocListPtr
+//    macptr            int64          ClassMacPtr
+//    rangelistptr      int64          ClassRangeListPtr
 type Field struct {
-       Attr Attr
-       Val  interface{}
+       Attr  Attr
+       Val   interface{}
+       Class Class
+}
+
+// A Class is the DWARF 4 class of an attibute value.
+//
+// In general, a given attribute's value may take on one of several
+// possible classes defined by DWARF, each of which leads to a
+// slightly different interpretation of the attribute.
+//
+// DWARF version 4 distinguishes attribute value classes more finely
+// than previous versions of DWARF. The reader will disambiguate
+// coarser classes from earlier versions of DWARF into the appropriate
+// DWARF 4 class. For example, DWARF 2 uses "constant" for constants
+// as well as all types of section offsets, but the reader will
+// canonicalize attributes in DWARF 2 files that refer to section
+// offsets to one of the Class*Ptr classes, even though these classes
+// were only defined in DWARF 3.
+type Class int
+
+const (
+       // ClassAddress represents values of type uint64 that are
+       // addresses on the target machine.
+       ClassAddress Class = 1 + iota
+
+       // ClassBlock represents values of type []byte whose
+       // interpretation depends on the attribute.
+       ClassBlock
+
+       // ClassConstant represents values of type int64 that are
+       // constants. The interpretation of this constant depends on
+       // the attribute.
+       ClassConstant
+
+       // ClassExprLoc represents values of type []byte that contain
+       // an encoded DWARF expression or location description.
+       ClassExprLoc
+
+       // ClassFlag represents values of type bool.
+       ClassFlag
+
+       // ClassLinePtr represents values that are an int64 offset
+       // into the "line" section.
+       ClassLinePtr
+
+       // ClassLocListPtr repersents values that are an int64 offset
+       // into the "loclist" section.
+       ClassLocListPtr
+
+       // ClassMacPtr represents values that are an int64 offset into
+       // the "mac" section.
+       ClassMacPtr
+
+       // ClassMacPtr represents values that are an int64 offset into
+       // the "rangelist" section.
+       ClassRangeListPtr
+
+       // ClassReference represents values that are an Offset offset
+       // of an Entry in the info section (for use with Reader.Seek).
+       // The DWARF specification combines ClassReference and
+       // ClassReferenceSig into class "reference".
+       ClassReference
+
+       // ClassReferenceSig represents values that are a uint64 type
+       // signature referencing a type Entry.
+       ClassReferenceSig
+
+       // ClassString represents values that are strings. If the
+       // compilation unit specifies the AttrUseUTF8 flag (strongly
+       // recommended), the string value will be encoded in UTF-8.
+       // Otherwise, the encoding is unspecified.
+       ClassString
+
+       // ClassReferenceAlt represents values of type int64 that are
+       // an offset into the DWARF "info" section of an alternate
+       // object file.
+       ClassReferenceAlt
+
+       // ClassStringAlt represents values of type int64 that are an
+       // offset into the DWARF string section of an alternate object
+       // file.
+       ClassStringAlt
+)
+
+//go:generate stringer -type=Class
+
+func (i Class) GoString() string {
+       return "dwarf." + i.String()
 }
 
 // Val returns the value associated with attribute Attr in Entry,
@@ -167,6 +368,7 @@ func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry {
        }
        for i := range e.Field {
                e.Field[i].Attr = a.field[i].attr
+               e.Field[i].Class = a.field[i].class
                fmt := a.field[i].fmt
                if fmt == formIndirect {
                        fmt = format(b.uint())
index 80971bbb90bb1183d6e12afac79d1f57fce29ad7..98a46857fa5f2dfa7f0d49d6bd198a325dfe5084 100644 (file)
@@ -33,9 +33,9 @@ func (d *Data) parseTypes(name string, types []byte) error {
                        return b.err
                }
                hdroff := b.off
-               vers := b.uint16()
+               vers := int(b.uint16())
                if vers != 4 {
-                       b.error("unsupported DWARF version " + strconv.Itoa(int(vers)))
+                       b.error("unsupported DWARF version " + strconv.Itoa(vers))
                        return b.err
                }
                var ao uint32
@@ -49,7 +49,7 @@ func (d *Data) parseTypes(name string, types []byte) error {
                        }
                        ao = uint32(ao64)
                }
-               atable, err := d.parseAbbrev(ao)
+               atable, err := d.parseAbbrev(ao, vers)
                if err != nil {
                        return err
                }
index 901ba0dabf1068da1e3468213222ac9f2f94ce99..ceb6cdbff321933cd10f06c5c174070fc7344fd3 100644 (file)
@@ -67,7 +67,7 @@ func (d *Data) parseUnits() ([]unit, error) {
                        break
                }
                u.vers = int(vers)
-               atable, err := d.parseAbbrev(b.uint32())
+               atable, err := d.parseAbbrev(b.uint32(), u.vers)
                if err != nil {
                        if b.err == nil {
                                b.err = err
index 0d10ec51b1b6900da4ad9aa885fc367230325f5d..48fe9d26e1ac62e32accecd4686014852f22c3fc 100644 (file)
@@ -245,56 +245,56 @@ var relocationTests = []relocationTest{
        {
                "testdata/go-relocation-test-gcc441-x86-64.obj",
                []relocationTestEntry{
-                       {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
+                       {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString}, {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrName, Val: "go-relocation-test.c", Class: dwarf.ClassString}, {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress}, {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}}}},
                },
        },
        {
                "testdata/go-relocation-test-gcc441-x86.obj",
                []relocationTestEntry{
-                       {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "t.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x5)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
+                       {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString}, {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrName, Val: "t.c", Class: dwarf.ClassString}, {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, {Attr: dwarf.AttrHighpc, Val: uint64(0x5), Class: dwarf.ClassAddress}, {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}}}},
                },
        },
        {
                "testdata/go-relocation-test-gcc424-x86-64.obj",
                []relocationTestEntry{
-                       {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
+                       {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)", Class: dwarf.ClassString}, {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c", Class: dwarf.ClassString}, {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress}, {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}}}},
                },
        },
        {
                "testdata/go-relocation-test-gcc482-aarch64.obj",
                []relocationTestEntry{
-                       {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -g -fstack-protector"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: int64(0x24)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
+                       {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -g -fstack-protector", Class: dwarf.ClassString}, {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482.c", Class: dwarf.ClassString}, {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, {Attr: dwarf.AttrHighpc, Val: int64(0x24), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}}}},
                },
        },
        {
                "testdata/go-relocation-test-gcc492-arm.obj",
                []relocationTestEntry{
-                       {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 20141224 (prerelease) -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -mtls-dialect=gnu -g"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc492.c"}, {Attr: dwarf.AttrCompDir, Val: "/root/go/src/debug/elf/testdata"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: int64(0x28)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
+                       {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 20141224 (prerelease) -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -mtls-dialect=gnu -g", Class: dwarf.ClassString}, {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc492.c", Class: dwarf.ClassString}, {Attr: dwarf.AttrCompDir, Val: "/root/go/src/debug/elf/testdata", Class: dwarf.ClassString}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, {Attr: dwarf.AttrHighpc, Val: int64(0x28), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}}}},
                },
        },
        {
                "testdata/go-relocation-test-gcc5-ppc.obj",
                []relocationTestEntry{
-                       {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{dwarf.Field{Attr: dwarf.AttrProducer, Val: "GNU C11 5.0.0 20150116 (experimental) -Asystem=linux -Asystem=unix -Asystem=posix -g"}, dwarf.Field{Attr: dwarf.AttrLanguage, Val: int64(12)}, dwarf.Field{Attr: dwarf.AttrName, Val: "go-relocation-test-gcc5-ppc.c"}, dwarf.Field{Attr: dwarf.AttrCompDir, Val: "/tmp"}, dwarf.Field{Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, dwarf.Field{Attr: dwarf.AttrHighpc, Val: int64(0x44)}, dwarf.Field{Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
+                       {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{dwarf.Field{Attr: dwarf.AttrProducer, Val: "GNU C11 5.0.0 20150116 (experimental) -Asystem=linux -Asystem=unix -Asystem=posix -g", Class: dwarf.ClassString}, dwarf.Field{Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, dwarf.Field{Attr: dwarf.AttrName, Val: "go-relocation-test-gcc5-ppc.c", Class: dwarf.ClassString}, dwarf.Field{Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, dwarf.Field{Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, dwarf.Field{Attr: dwarf.AttrHighpc, Val: int64(0x44), Class: dwarf.ClassConstant}, dwarf.Field{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}}}},
                },
        },
        {
                "testdata/go-relocation-test-gcc482-ppc64le.obj",
                []relocationTestEntry{
-                       {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{dwarf.Field{Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -Asystem=linux -Asystem=unix -Asystem=posix -msecure-plt -mtune=power8 -mcpu=power7 -gdwarf-2 -fstack-protector"}, dwarf.Field{Attr: dwarf.AttrLanguage, Val: int64(1)}, dwarf.Field{Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482-ppc64le.c"}, dwarf.Field{Attr: dwarf.AttrCompDir, Val: "/tmp"}, dwarf.Field{Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, dwarf.Field{Attr: dwarf.AttrHighpc, Val: uint64(0x24)}, dwarf.Field{Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
+                       {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{dwarf.Field{Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -Asystem=linux -Asystem=unix -Asystem=posix -msecure-plt -mtune=power8 -mcpu=power7 -gdwarf-2 -fstack-protector", Class: dwarf.ClassString}, dwarf.Field{Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, dwarf.Field{Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482-ppc64le.c", Class: dwarf.ClassString}, dwarf.Field{Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, dwarf.Field{Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, dwarf.Field{Attr: dwarf.AttrHighpc, Val: uint64(0x24), Class: dwarf.ClassAddress}, dwarf.Field{Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}}}},
                },
        },
        {
                "testdata/go-relocation-test-clang-x86.obj",
                []relocationTestEntry{
-                       {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "clang version google3-trunk (trunk r209387)"}, {Attr: dwarf.AttrLanguage, Val: int64(12)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-clang.c"}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}}}},
+                       {0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "clang version google3-trunk (trunk r209387)", Class: dwarf.ClassString}, {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrName, Val: "go-relocation-test-clang.c", Class: dwarf.ClassString}, {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}}}},
                },
        },
        {
                "testdata/gcc-amd64-openbsd-debug-with-rela.obj",
                []relocationTestEntry{
-                       {203, &dwarf.Entry{Offset: 0xc62, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{{Attr: dwarf.AttrName, Val: "it_interval"}, {Attr: dwarf.AttrDeclFile, Val: int64(7)}, {Attr: dwarf.AttrDeclLine, Val: int64(236)}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f)}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}}}}},
-                       {204, &dwarf.Entry{Offset: 0xc70, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{{Attr: dwarf.AttrName, Val: "it_value"}, {Attr: dwarf.AttrDeclFile, Val: int64(7)}, {Attr: dwarf.AttrDeclLine, Val: int64(237)}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f)}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}}}}},
+                       {203, &dwarf.Entry{Offset: 0xc62, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{{Attr: dwarf.AttrName, Val: "it_interval", Class: dwarf.ClassString}, {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrDeclLine, Val: int64(236), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}, Class: dwarf.ClassExprLoc}}}},
+                       {204, &dwarf.Entry{Offset: 0xc70, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{{Attr: dwarf.AttrName, Val: "it_value", Class: dwarf.ClassString}, {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrDeclLine, Val: int64(237), Class: dwarf.ClassConstant}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}, Class: dwarf.ClassExprLoc}}}},
                },
        },
 }