From d7d133736888f011c7746ff6edb3cb90c6cf0309 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Thu, 2 Apr 2015 11:19:00 -0400 Subject: [PATCH] debug/dwarf: add DWARF attribute value class to Field 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 --- src/debug/dwarf/class_string.go | 17 +++ src/debug/dwarf/entry.go | 240 +++++++++++++++++++++++++++++--- src/debug/dwarf/typeunit.go | 6 +- src/debug/dwarf/unit.go | 2 +- src/debug/elf/file_test.go | 20 +-- 5 files changed, 252 insertions(+), 33 deletions(-) create mode 100644 src/debug/dwarf/class_string.go diff --git a/src/debug/dwarf/class_string.go b/src/debug/dwarf/class_string.go new file mode 100644 index 0000000000..6fd212fe4c --- /dev/null +++ b/src/debug/dwarf/class_string.go @@ -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]] +} diff --git a/src/debug/dwarf/entry.go b/src/debug/dwarf/entry.go index 5a21da0e9e..760ddec5a4 100644 --- a/src/debug/dwarf/entry.go +++ b/src/debug/dwarf/entry.go @@ -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()) diff --git a/src/debug/dwarf/typeunit.go b/src/debug/dwarf/typeunit.go index 80971bbb90..98a46857fa 100644 --- a/src/debug/dwarf/typeunit.go +++ b/src/debug/dwarf/typeunit.go @@ -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 } diff --git a/src/debug/dwarf/unit.go b/src/debug/dwarf/unit.go index 901ba0dabf..ceb6cdbff3 100644 --- a/src/debug/dwarf/unit.go +++ b/src/debug/dwarf/unit.go @@ -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 diff --git a/src/debug/elf/file_test.go b/src/debug/elf/file_test.go index 0d10ec51b1..48fe9d26e1 100644 --- a/src/debug/elf/file_test.go +++ b/src/debug/elf/file_test.go @@ -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}}}}, }, }, }