summaryrefslogtreecommitdiff
path: root/src/pkg/debug/dwarf
diff options
context:
space:
mode:
authorTianon Gravi <admwiggin@gmail.com>2015-01-15 11:54:00 -0700
committerTianon Gravi <admwiggin@gmail.com>2015-01-15 11:54:00 -0700
commitf154da9e12608589e8d5f0508f908a0c3e88a1bb (patch)
treef8255d51e10c6f1e0ed69702200b966c9556a431 /src/pkg/debug/dwarf
parent8d8329ed5dfb9622c82a9fbec6fd99a580f9c9f6 (diff)
downloadgolang-upstream/1.4.tar.gz
Imported Upstream version 1.4upstream/1.4
Diffstat (limited to 'src/pkg/debug/dwarf')
-rw-r--r--src/pkg/debug/dwarf/buf.go181
-rw-r--r--src/pkg/debug/dwarf/const.go454
-rw-r--r--src/pkg/debug/dwarf/entry.go401
-rw-r--r--src/pkg/debug/dwarf/open.go87
-rw-r--r--src/pkg/debug/dwarf/testdata/typedef.c85
-rwxr-xr-xsrc/pkg/debug/dwarf/testdata/typedef.elfbin12448 -> 0 bytes
-rw-r--r--src/pkg/debug/dwarf/testdata/typedef.elf4bin9496 -> 0 bytes
-rw-r--r--src/pkg/debug/dwarf/testdata/typedef.machobin5024 -> 0 bytes
-rw-r--r--src/pkg/debug/dwarf/type.go659
-rw-r--r--src/pkg/debug/dwarf/type_test.go122
-rw-r--r--src/pkg/debug/dwarf/typeunit.go166
-rw-r--r--src/pkg/debug/dwarf/unit.go90
12 files changed, 0 insertions, 2245 deletions
diff --git a/src/pkg/debug/dwarf/buf.go b/src/pkg/debug/dwarf/buf.go
deleted file mode 100644
index 53c46eb4b..000000000
--- a/src/pkg/debug/dwarf/buf.go
+++ /dev/null
@@ -1,181 +0,0 @@
-// 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.
-
-// Buffered reading and decoding of DWARF data streams.
-
-package dwarf
-
-import (
- "encoding/binary"
- "strconv"
-)
-
-// Data buffer being decoded.
-type buf struct {
- dwarf *Data
- order binary.ByteOrder
- format dataFormat
- name string
- off Offset
- data []byte
- err error
-}
-
-// Data format, other than byte order. This affects the handling of
-// certain field formats.
-type dataFormat interface {
- // DWARF version number. Zero means unknown.
- version() int
-
- // 64-bit DWARF format?
- dwarf64() (dwarf64 bool, isKnown bool)
-
- // Size of an address, in bytes. Zero means unknown.
- addrsize() int
-}
-
-// Some parts of DWARF have no data format, e.g., abbrevs.
-type unknownFormat struct{}
-
-func (u unknownFormat) version() int {
- return 0
-}
-
-func (u unknownFormat) dwarf64() (bool, bool) {
- return false, false
-}
-
-func (u unknownFormat) addrsize() int {
- return 0
-}
-
-func makeBuf(d *Data, format dataFormat, name string, off Offset, data []byte) buf {
- return buf{d, d.order, format, name, off, data, nil}
-}
-
-func (b *buf) uint8() uint8 {
- if len(b.data) < 1 {
- b.error("underflow")
- return 0
- }
- val := b.data[0]
- b.data = b.data[1:]
- b.off++
- return val
-}
-
-func (b *buf) bytes(n int) []byte {
- if len(b.data) < n {
- b.error("underflow")
- return nil
- }
- data := b.data[0:n]
- b.data = b.data[n:]
- b.off += Offset(n)
- return data
-}
-
-func (b *buf) skip(n int) { b.bytes(n) }
-
-func (b *buf) string() string {
- for i := 0; i < len(b.data); i++ {
- if b.data[i] == 0 {
- s := string(b.data[0:i])
- b.data = b.data[i+1:]
- b.off += Offset(i + 1)
- return s
- }
- }
- b.error("underflow")
- return ""
-}
-
-func (b *buf) uint16() uint16 {
- a := b.bytes(2)
- if a == nil {
- return 0
- }
- return b.order.Uint16(a)
-}
-
-func (b *buf) uint32() uint32 {
- a := b.bytes(4)
- if a == nil {
- return 0
- }
- return b.order.Uint32(a)
-}
-
-func (b *buf) uint64() uint64 {
- a := b.bytes(8)
- if a == nil {
- return 0
- }
- return b.order.Uint64(a)
-}
-
-// Read a varint, which is 7 bits per byte, little endian.
-// the 0x80 bit means read another byte.
-func (b *buf) varint() (c uint64, bits uint) {
- for i := 0; i < len(b.data); i++ {
- byte := b.data[i]
- c |= uint64(byte&0x7F) << bits
- bits += 7
- if byte&0x80 == 0 {
- b.off += Offset(i + 1)
- b.data = b.data[i+1:]
- return c, bits
- }
- }
- return 0, 0
-}
-
-// Unsigned int is just a varint.
-func (b *buf) uint() uint64 {
- x, _ := b.varint()
- return x
-}
-
-// Signed int is a sign-extended varint.
-func (b *buf) int() int64 {
- ux, bits := b.varint()
- x := int64(ux)
- if x&(1<<(bits-1)) != 0 {
- x |= -1 << bits
- }
- return x
-}
-
-// Address-sized uint.
-func (b *buf) addr() uint64 {
- switch b.format.addrsize() {
- case 1:
- return uint64(b.uint8())
- case 2:
- return uint64(b.uint16())
- case 4:
- return uint64(b.uint32())
- case 8:
- return uint64(b.uint64())
- }
- b.error("unknown address size")
- return 0
-}
-
-func (b *buf) error(s string) {
- if b.err == nil {
- b.data = nil
- b.err = DecodeError{b.name, b.off, s}
- }
-}
-
-type DecodeError struct {
- Name string
- Offset Offset
- Err string
-}
-
-func (e DecodeError) Error() string {
- return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.FormatInt(int64(e.Offset), 16) + ": " + e.Err
-}
diff --git a/src/pkg/debug/dwarf/const.go b/src/pkg/debug/dwarf/const.go
deleted file mode 100644
index 93c68881a..000000000
--- a/src/pkg/debug/dwarf/const.go
+++ /dev/null
@@ -1,454 +0,0 @@
-// 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.
-
-// Constants
-
-package dwarf
-
-import "strconv"
-
-// An Attr identifies the attribute type in a DWARF Entry's Field.
-type Attr uint32
-
-const (
- AttrSibling Attr = 0x01
- AttrLocation Attr = 0x02
- AttrName Attr = 0x03
- AttrOrdering Attr = 0x09
- AttrByteSize Attr = 0x0B
- AttrBitOffset Attr = 0x0C
- AttrBitSize Attr = 0x0D
- AttrStmtList Attr = 0x10
- AttrLowpc Attr = 0x11
- AttrHighpc Attr = 0x12
- AttrLanguage Attr = 0x13
- AttrDiscr Attr = 0x15
- AttrDiscrValue Attr = 0x16
- AttrVisibility Attr = 0x17
- AttrImport Attr = 0x18
- AttrStringLength Attr = 0x19
- AttrCommonRef Attr = 0x1A
- AttrCompDir Attr = 0x1B
- AttrConstValue Attr = 0x1C
- AttrContainingType Attr = 0x1D
- AttrDefaultValue Attr = 0x1E
- AttrInline Attr = 0x20
- AttrIsOptional Attr = 0x21
- AttrLowerBound Attr = 0x22
- AttrProducer Attr = 0x25
- AttrPrototyped Attr = 0x27
- AttrReturnAddr Attr = 0x2A
- AttrStartScope Attr = 0x2C
- AttrStrideSize Attr = 0x2E
- AttrUpperBound Attr = 0x2F
- AttrAbstractOrigin Attr = 0x31
- AttrAccessibility Attr = 0x32
- AttrAddrClass Attr = 0x33
- AttrArtificial Attr = 0x34
- AttrBaseTypes Attr = 0x35
- AttrCalling Attr = 0x36
- AttrCount Attr = 0x37
- AttrDataMemberLoc Attr = 0x38
- AttrDeclColumn Attr = 0x39
- AttrDeclFile Attr = 0x3A
- AttrDeclLine Attr = 0x3B
- AttrDeclaration Attr = 0x3C
- AttrDiscrList Attr = 0x3D
- AttrEncoding Attr = 0x3E
- AttrExternal Attr = 0x3F
- AttrFrameBase Attr = 0x40
- AttrFriend Attr = 0x41
- AttrIdentifierCase Attr = 0x42
- AttrMacroInfo Attr = 0x43
- AttrNamelistItem Attr = 0x44
- AttrPriority Attr = 0x45
- AttrSegment Attr = 0x46
- AttrSpecification Attr = 0x47
- AttrStaticLink Attr = 0x48
- AttrType Attr = 0x49
- AttrUseLocation Attr = 0x4A
- AttrVarParam Attr = 0x4B
- AttrVirtuality Attr = 0x4C
- AttrVtableElemLoc Attr = 0x4D
- AttrAllocated Attr = 0x4E
- AttrAssociated Attr = 0x4F
- AttrDataLocation Attr = 0x50
- AttrStride Attr = 0x51
- AttrEntrypc Attr = 0x52
- AttrUseUTF8 Attr = 0x53
- AttrExtension Attr = 0x54
- AttrRanges Attr = 0x55
- AttrTrampoline Attr = 0x56
- AttrCallColumn Attr = 0x57
- AttrCallFile Attr = 0x58
- AttrCallLine Attr = 0x59
- AttrDescription Attr = 0x5A
-)
-
-var attrNames = [...]string{
- AttrSibling: "Sibling",
- AttrLocation: "Location",
- AttrName: "Name",
- AttrOrdering: "Ordering",
- AttrByteSize: "ByteSize",
- AttrBitOffset: "BitOffset",
- AttrBitSize: "BitSize",
- AttrStmtList: "StmtList",
- AttrLowpc: "Lowpc",
- AttrHighpc: "Highpc",
- AttrLanguage: "Language",
- AttrDiscr: "Discr",
- AttrDiscrValue: "DiscrValue",
- AttrVisibility: "Visibility",
- AttrImport: "Import",
- AttrStringLength: "StringLength",
- AttrCommonRef: "CommonRef",
- AttrCompDir: "CompDir",
- AttrConstValue: "ConstValue",
- AttrContainingType: "ContainingType",
- AttrDefaultValue: "DefaultValue",
- AttrInline: "Inline",
- AttrIsOptional: "IsOptional",
- AttrLowerBound: "LowerBound",
- AttrProducer: "Producer",
- AttrPrototyped: "Prototyped",
- AttrReturnAddr: "ReturnAddr",
- AttrStartScope: "StartScope",
- AttrStrideSize: "StrideSize",
- AttrUpperBound: "UpperBound",
- AttrAbstractOrigin: "AbstractOrigin",
- AttrAccessibility: "Accessibility",
- AttrAddrClass: "AddrClass",
- AttrArtificial: "Artificial",
- AttrBaseTypes: "BaseTypes",
- AttrCalling: "Calling",
- AttrCount: "Count",
- AttrDataMemberLoc: "DataMemberLoc",
- AttrDeclColumn: "DeclColumn",
- AttrDeclFile: "DeclFile",
- AttrDeclLine: "DeclLine",
- AttrDeclaration: "Declaration",
- AttrDiscrList: "DiscrList",
- AttrEncoding: "Encoding",
- AttrExternal: "External",
- AttrFrameBase: "FrameBase",
- AttrFriend: "Friend",
- AttrIdentifierCase: "IdentifierCase",
- AttrMacroInfo: "MacroInfo",
- AttrNamelistItem: "NamelistItem",
- AttrPriority: "Priority",
- AttrSegment: "Segment",
- AttrSpecification: "Specification",
- AttrStaticLink: "StaticLink",
- AttrType: "Type",
- AttrUseLocation: "UseLocation",
- AttrVarParam: "VarParam",
- AttrVirtuality: "Virtuality",
- AttrVtableElemLoc: "VtableElemLoc",
- AttrAllocated: "Allocated",
- AttrAssociated: "Associated",
- AttrDataLocation: "DataLocation",
- AttrStride: "Stride",
- AttrEntrypc: "Entrypc",
- AttrUseUTF8: "UseUTF8",
- AttrExtension: "Extension",
- AttrRanges: "Ranges",
- AttrTrampoline: "Trampoline",
- AttrCallColumn: "CallColumn",
- AttrCallFile: "CallFile",
- AttrCallLine: "CallLine",
- AttrDescription: "Description",
-}
-
-func (a Attr) String() string {
- if int(a) < len(attrNames) {
- s := attrNames[a]
- if s != "" {
- return s
- }
- }
- return strconv.Itoa(int(a))
-}
-
-func (a Attr) GoString() string {
- if int(a) < len(attrNames) {
- s := attrNames[a]
- if s != "" {
- return "dwarf.Attr" + s
- }
- }
- return "dwarf.Attr(" + strconv.FormatInt(int64(a), 10) + ")"
-}
-
-// A format is a DWARF data encoding format.
-type format uint32
-
-const (
- // value formats
- formAddr format = 0x01
- formDwarfBlock2 format = 0x03
- formDwarfBlock4 format = 0x04
- formData2 format = 0x05
- formData4 format = 0x06
- formData8 format = 0x07
- formString format = 0x08
- formDwarfBlock format = 0x09
- formDwarfBlock1 format = 0x0A
- formData1 format = 0x0B
- formFlag format = 0x0C
- formSdata format = 0x0D
- formStrp format = 0x0E
- formUdata format = 0x0F
- formRefAddr format = 0x10
- formRef1 format = 0x11
- formRef2 format = 0x12
- formRef4 format = 0x13
- formRef8 format = 0x14
- formRefUdata format = 0x15
- formIndirect format = 0x16
- // The following are new in DWARF 4.
- formSecOffset format = 0x17
- formExprloc format = 0x18
- formFlagPresent format = 0x19
- formRefSig8 format = 0x20
- // Extensions for multi-file compression (.dwz)
- // http://www.dwarfstd.org/ShowIssue.php?issue=120604.1
- formGnuRefAlt format = 0x1f20
- formGnuStrpAlt format = 0x1f21
-)
-
-// A Tag is the classification (the type) of an Entry.
-type Tag uint32
-
-const (
- TagArrayType Tag = 0x01
- TagClassType Tag = 0x02
- TagEntryPoint Tag = 0x03
- TagEnumerationType Tag = 0x04
- TagFormalParameter Tag = 0x05
- TagImportedDeclaration Tag = 0x08
- TagLabel Tag = 0x0A
- TagLexDwarfBlock Tag = 0x0B
- TagMember Tag = 0x0D
- TagPointerType Tag = 0x0F
- TagReferenceType Tag = 0x10
- TagCompileUnit Tag = 0x11
- TagStringType Tag = 0x12
- TagStructType Tag = 0x13
- TagSubroutineType Tag = 0x15
- TagTypedef Tag = 0x16
- TagUnionType Tag = 0x17
- TagUnspecifiedParameters Tag = 0x18
- TagVariant Tag = 0x19
- TagCommonDwarfBlock Tag = 0x1A
- TagCommonInclusion Tag = 0x1B
- TagInheritance Tag = 0x1C
- TagInlinedSubroutine Tag = 0x1D
- TagModule Tag = 0x1E
- TagPtrToMemberType Tag = 0x1F
- TagSetType Tag = 0x20
- TagSubrangeType Tag = 0x21
- TagWithStmt Tag = 0x22
- TagAccessDeclaration Tag = 0x23
- TagBaseType Tag = 0x24
- TagCatchDwarfBlock Tag = 0x25
- TagConstType Tag = 0x26
- TagConstant Tag = 0x27
- TagEnumerator Tag = 0x28
- TagFileType Tag = 0x29
- TagFriend Tag = 0x2A
- TagNamelist Tag = 0x2B
- TagNamelistItem Tag = 0x2C
- TagPackedType Tag = 0x2D
- TagSubprogram Tag = 0x2E
- TagTemplateTypeParameter Tag = 0x2F
- TagTemplateValueParameter Tag = 0x30
- TagThrownType Tag = 0x31
- TagTryDwarfBlock Tag = 0x32
- TagVariantPart Tag = 0x33
- TagVariable Tag = 0x34
- TagVolatileType Tag = 0x35
- // The following are new in DWARF 3.
- TagDwarfProcedure Tag = 0x36
- TagRestrictType Tag = 0x37
- TagInterfaceType Tag = 0x38
- TagNamespace Tag = 0x39
- TagImportedModule Tag = 0x3A
- TagUnspecifiedType Tag = 0x3B
- TagPartialUnit Tag = 0x3C
- TagImportedUnit Tag = 0x3D
- TagMutableType Tag = 0x3E // Later removed from DWARF.
- TagCondition Tag = 0x3F
- TagSharedType Tag = 0x40
- // The following are new in DWARF 4.
- TagTypeUnit Tag = 0x41
- TagRvalueReferenceType Tag = 0x42
- TagTemplateAlias Tag = 0x43
-)
-
-var tagNames = [...]string{
- TagArrayType: "ArrayType",
- TagClassType: "ClassType",
- TagEntryPoint: "EntryPoint",
- TagEnumerationType: "EnumerationType",
- TagFormalParameter: "FormalParameter",
- TagImportedDeclaration: "ImportedDeclaration",
- TagLabel: "Label",
- TagLexDwarfBlock: "LexDwarfBlock",
- TagMember: "Member",
- TagPointerType: "PointerType",
- TagReferenceType: "ReferenceType",
- TagCompileUnit: "CompileUnit",
- TagStringType: "StringType",
- TagStructType: "StructType",
- TagSubroutineType: "SubroutineType",
- TagTypedef: "Typedef",
- TagUnionType: "UnionType",
- TagUnspecifiedParameters: "UnspecifiedParameters",
- TagVariant: "Variant",
- TagCommonDwarfBlock: "CommonDwarfBlock",
- TagCommonInclusion: "CommonInclusion",
- TagInheritance: "Inheritance",
- TagInlinedSubroutine: "InlinedSubroutine",
- TagModule: "Module",
- TagPtrToMemberType: "PtrToMemberType",
- TagSetType: "SetType",
- TagSubrangeType: "SubrangeType",
- TagWithStmt: "WithStmt",
- TagAccessDeclaration: "AccessDeclaration",
- TagBaseType: "BaseType",
- TagCatchDwarfBlock: "CatchDwarfBlock",
- TagConstType: "ConstType",
- TagConstant: "Constant",
- TagEnumerator: "Enumerator",
- TagFileType: "FileType",
- TagFriend: "Friend",
- TagNamelist: "Namelist",
- TagNamelistItem: "NamelistItem",
- TagPackedType: "PackedType",
- TagSubprogram: "Subprogram",
- TagTemplateTypeParameter: "TemplateTypeParameter",
- TagTemplateValueParameter: "TemplateValueParameter",
- TagThrownType: "ThrownType",
- TagTryDwarfBlock: "TryDwarfBlock",
- TagVariantPart: "VariantPart",
- TagVariable: "Variable",
- TagVolatileType: "VolatileType",
- TagDwarfProcedure: "DwarfProcedure",
- TagRestrictType: "RestrictType",
- TagInterfaceType: "InterfaceType",
- TagNamespace: "Namespace",
- TagImportedModule: "ImportedModule",
- TagUnspecifiedType: "UnspecifiedType",
- TagPartialUnit: "PartialUnit",
- TagImportedUnit: "ImportedUnit",
- TagMutableType: "MutableType",
- TagCondition: "Condition",
- TagSharedType: "SharedType",
- TagTypeUnit: "TypeUnit",
- TagRvalueReferenceType: "RvalueReferenceType",
- TagTemplateAlias: "TemplateAlias",
-}
-
-func (t Tag) String() string {
- if int(t) < len(tagNames) {
- s := tagNames[t]
- if s != "" {
- return s
- }
- }
- return strconv.Itoa(int(t))
-}
-
-func (t Tag) GoString() string {
- if int(t) < len(tagNames) {
- s := tagNames[t]
- if s != "" {
- return "dwarf.Tag" + s
- }
- }
- return "dwarf.Tag(" + strconv.FormatInt(int64(t), 10) + ")"
-}
-
-// Location expression operators.
-// The debug info encodes value locations like 8(R3)
-// as a sequence of these op codes.
-// This package does not implement full expressions;
-// the opPlusUconst operator is expected by the type parser.
-const (
- opAddr = 0x03 /* 1 op, const addr */
- opDeref = 0x06
- opConst1u = 0x08 /* 1 op, 1 byte const */
- opConst1s = 0x09 /* " signed */
- opConst2u = 0x0A /* 1 op, 2 byte const */
- opConst2s = 0x0B /* " signed */
- opConst4u = 0x0C /* 1 op, 4 byte const */
- opConst4s = 0x0D /* " signed */
- opConst8u = 0x0E /* 1 op, 8 byte const */
- opConst8s = 0x0F /* " signed */
- opConstu = 0x10 /* 1 op, LEB128 const */
- opConsts = 0x11 /* " signed */
- opDup = 0x12
- opDrop = 0x13
- opOver = 0x14
- opPick = 0x15 /* 1 op, 1 byte stack index */
- opSwap = 0x16
- opRot = 0x17
- opXderef = 0x18
- opAbs = 0x19
- opAnd = 0x1A
- opDiv = 0x1B
- opMinus = 0x1C
- opMod = 0x1D
- opMul = 0x1E
- opNeg = 0x1F
- opNot = 0x20
- opOr = 0x21
- opPlus = 0x22
- opPlusUconst = 0x23 /* 1 op, ULEB128 addend */
- opShl = 0x24
- opShr = 0x25
- opShra = 0x26
- opXor = 0x27
- opSkip = 0x2F /* 1 op, signed 2-byte constant */
- opBra = 0x28 /* 1 op, signed 2-byte constant */
- opEq = 0x29
- opGe = 0x2A
- opGt = 0x2B
- opLe = 0x2C
- opLt = 0x2D
- opNe = 0x2E
- opLit0 = 0x30
- /* OpLitN = OpLit0 + N for N = 0..31 */
- opReg0 = 0x50
- /* OpRegN = OpReg0 + N for N = 0..31 */
- opBreg0 = 0x70 /* 1 op, signed LEB128 constant */
- /* OpBregN = OpBreg0 + N for N = 0..31 */
- opRegx = 0x90 /* 1 op, ULEB128 register */
- opFbreg = 0x91 /* 1 op, SLEB128 offset */
- opBregx = 0x92 /* 2 op, ULEB128 reg; SLEB128 off */
- opPiece = 0x93 /* 1 op, ULEB128 size of piece */
- opDerefSize = 0x94 /* 1-byte size of data retrieved */
- opXderefSize = 0x95 /* 1-byte size of data retrieved */
- opNop = 0x96
- /* next four new in Dwarf v3 */
- opPushObjAddr = 0x97
- opCall2 = 0x98 /* 2-byte offset of DIE */
- opCall4 = 0x99 /* 4-byte offset of DIE */
- opCallRef = 0x9A /* 4- or 8- byte offset of DIE */
- /* 0xE0-0xFF reserved for user-specific */
-)
-
-// Basic type encodings -- the value for AttrEncoding in a TagBaseType Entry.
-const (
- encAddress = 0x01
- encBoolean = 0x02
- encComplexFloat = 0x03
- encFloat = 0x04
- encSigned = 0x05
- encSignedChar = 0x06
- encUnsigned = 0x07
- encUnsignedChar = 0x08
- encImaginaryFloat = 0x09
-)
diff --git a/src/pkg/debug/dwarf/entry.go b/src/pkg/debug/dwarf/entry.go
deleted file mode 100644
index 665c6840d..000000000
--- a/src/pkg/debug/dwarf/entry.go
+++ /dev/null
@@ -1,401 +0,0 @@
-// 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.
-
-// DWARF debug information entry parser.
-// An entry is a sequence of data items of a given format.
-// The first word in the entry is an index into what DWARF
-// calls the ``abbreviation table.'' An abbreviation is really
-// just a type descriptor: it's an array of attribute tag/value format pairs.
-
-package dwarf
-
-import (
- "errors"
- "strconv"
-)
-
-// a single entry's description: a sequence of attributes
-type abbrev struct {
- tag Tag
- children bool
- field []afield
-}
-
-type afield struct {
- attr Attr
- fmt format
-}
-
-// a map from entry format ids to their descriptions
-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) {
- if m, ok := d.abbrevCache[off]; ok {
- return m, nil
- }
-
- data := d.abbrev
- if off > uint32(len(data)) {
- data = nil
- } else {
- data = data[off:]
- }
- b := makeBuf(d, unknownFormat{}, "abbrev", 0, data)
-
- // Error handling is simplified by the buf getters
- // returning an endless stream of 0s after an error.
- m := make(abbrevTable)
- for {
- // Table ends with id == 0.
- id := uint32(b.uint())
- if id == 0 {
- break
- }
-
- // Walk over attributes, counting.
- n := 0
- b1 := b // Read from copy of b.
- b1.uint()
- b1.uint8()
- for {
- tag := b1.uint()
- fmt := b1.uint()
- if tag == 0 && fmt == 0 {
- break
- }
- n++
- }
- if b1.err != nil {
- return nil, b1.err
- }
-
- // Walk over attributes again, this time writing them down.
- var a abbrev
- a.tag = Tag(b.uint())
- a.children = b.uint8() != 0
- a.field = make([]afield, n)
- for i := range a.field {
- a.field[i].attr = Attr(b.uint())
- a.field[i].fmt = format(b.uint())
- }
- b.uint()
- b.uint()
-
- m[id] = a
- }
- if b.err != nil {
- return nil, b.err
- }
- d.abbrevCache[off] = m
- return m, nil
-}
-
-// An entry is a sequence of attribute/value pairs.
-type Entry struct {
- Offset Offset // offset of Entry in DWARF info
- Tag Tag // tag (kind of Entry)
- Children bool // whether Entry is followed by children
- Field []Field
-}
-
-// A Field is a single attribute/value pair in an Entry.
-type Field struct {
- Attr Attr
- Val interface{}
-}
-
-// Val returns the value associated with attribute Attr in Entry,
-// or nil if there is no such attribute.
-//
-// A common idiom is to merge the check for nil return with
-// the check that the value has the expected dynamic type, as in:
-// v, ok := e.Val(AttrSibling).(int64);
-//
-func (e *Entry) Val(a Attr) interface{} {
- for _, f := range e.Field {
- if f.Attr == a {
- return f.Val
- }
- }
- return nil
-}
-
-// An Offset represents the location of an Entry within the DWARF info.
-// (See Reader.Seek.)
-type Offset uint32
-
-// Entry reads a single entry from buf, decoding
-// according to the given abbreviation table.
-func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry {
- off := b.off
- id := uint32(b.uint())
- if id == 0 {
- return &Entry{}
- }
- a, ok := atab[id]
- if !ok {
- b.error("unknown abbreviation table index")
- return nil
- }
- e := &Entry{
- Offset: off,
- Tag: a.tag,
- Children: a.children,
- Field: make([]Field, len(a.field)),
- }
- for i := range e.Field {
- e.Field[i].Attr = a.field[i].attr
- fmt := a.field[i].fmt
- if fmt == formIndirect {
- fmt = format(b.uint())
- }
- var val interface{}
- switch fmt {
- default:
- b.error("unknown entry attr format 0x" + strconv.FormatInt(int64(fmt), 16))
-
- // address
- case formAddr:
- val = b.addr()
-
- // block
- case formDwarfBlock1:
- val = b.bytes(int(b.uint8()))
- case formDwarfBlock2:
- val = b.bytes(int(b.uint16()))
- case formDwarfBlock4:
- val = b.bytes(int(b.uint32()))
- case formDwarfBlock:
- val = b.bytes(int(b.uint()))
-
- // constant
- case formData1:
- val = int64(b.uint8())
- case formData2:
- val = int64(b.uint16())
- case formData4:
- val = int64(b.uint32())
- case formData8:
- val = int64(b.uint64())
- case formSdata:
- val = int64(b.int())
- case formUdata:
- val = int64(b.uint())
-
- // flag
- case formFlag:
- val = b.uint8() == 1
- // New in DWARF 4.
- case formFlagPresent:
- // The attribute is implicitly indicated as present, and no value is
- // encoded in the debugging information entry itself.
- val = true
-
- // reference to other entry
- case formRefAddr:
- vers := b.format.version()
- if vers == 0 {
- b.error("unknown version for DW_FORM_ref_addr")
- } else if vers == 2 {
- val = Offset(b.addr())
- } else {
- is64, known := b.format.dwarf64()
- if !known {
- b.error("unknown size for DW_FORM_ref_addr")
- } else if is64 {
- val = Offset(b.uint64())
- } else {
- val = Offset(b.uint32())
- }
- }
- case formRef1:
- val = Offset(b.uint8()) + ubase
- case formRef2:
- val = Offset(b.uint16()) + ubase
- case formRef4:
- val = Offset(b.uint32()) + ubase
- case formRef8:
- val = Offset(b.uint64()) + ubase
- case formRefUdata:
- val = Offset(b.uint()) + ubase
-
- // string
- case formString:
- val = b.string()
- case formStrp:
- off := b.uint32() // offset into .debug_str
- if b.err != nil {
- return nil
- }
- b1 := makeBuf(b.dwarf, unknownFormat{}, "str", 0, b.dwarf.str)
- b1.skip(int(off))
- val = b1.string()
- if b1.err != nil {
- b.err = b1.err
- return nil
- }
-
- // lineptr, loclistptr, macptr, rangelistptr
- // New in DWARF 4, but clang can generate them with -gdwarf-2.
- // Section reference, replacing use of formData4 and formData8.
- case formSecOffset, formGnuRefAlt, formGnuStrpAlt:
- is64, known := b.format.dwarf64()
- if !known {
- b.error("unknown size for form 0x" + strconv.FormatInt(int64(fmt), 16))
- } else if is64 {
- val = int64(b.uint64())
- } else {
- val = int64(b.uint32())
- }
-
- // exprloc
- // New in DWARF 4.
- case formExprloc:
- val = b.bytes(int(b.uint()))
-
- // reference
- // New in DWARF 4.
- case formRefSig8:
- // 64-bit type signature.
- val = b.uint64()
- }
- e.Field[i].Val = val
- }
- if b.err != nil {
- return nil
- }
- return e
-}
-
-// A Reader allows reading Entry structures from a DWARF ``info'' section.
-// The Entry structures are arranged in a tree. The Reader's Next function
-// return successive entries from a pre-order traversal of the tree.
-// If an entry has children, its Children field will be true, and the children
-// follow, terminated by an Entry with Tag 0.
-type Reader struct {
- b buf
- d *Data
- err error
- unit int
- lastChildren bool // .Children of last entry returned by Next
- lastSibling Offset // .Val(AttrSibling) of last entry returned by Next
-}
-
-// Reader returns a new Reader for Data.
-// The reader is positioned at byte offset 0 in the DWARF ``info'' section.
-func (d *Data) Reader() *Reader {
- r := &Reader{d: d}
- r.Seek(0)
- return r
-}
-
-// Seek positions the Reader at offset off in the encoded entry stream.
-// Offset 0 can be used to denote the first entry.
-func (r *Reader) Seek(off Offset) {
- d := r.d
- r.err = nil
- r.lastChildren = false
- if off == 0 {
- if len(d.unit) == 0 {
- return
- }
- u := &d.unit[0]
- r.unit = 0
- r.b = makeBuf(r.d, u, "info", u.off, u.data)
- return
- }
-
- // TODO(rsc): binary search (maybe a new package)
- var i int
- var u *unit
- for i = range d.unit {
- u = &d.unit[i]
- if u.off <= off && off < u.off+Offset(len(u.data)) {
- r.unit = i
- r.b = makeBuf(r.d, u, "info", off, u.data[off-u.off:])
- return
- }
- }
- r.err = errors.New("offset out of range")
-}
-
-// maybeNextUnit advances to the next unit if this one is finished.
-func (r *Reader) maybeNextUnit() {
- for len(r.b.data) == 0 && r.unit+1 < len(r.d.unit) {
- r.unit++
- u := &r.d.unit[r.unit]
- r.b = makeBuf(r.d, u, "info", u.off, u.data)
- }
-}
-
-// Next reads the next entry from the encoded entry stream.
-// It returns nil, nil when it reaches the end of the section.
-// It returns an error if the current offset is invalid or the data at the
-// offset cannot be decoded as a valid Entry.
-func (r *Reader) Next() (*Entry, error) {
- if r.err != nil {
- return nil, r.err
- }
- r.maybeNextUnit()
- if len(r.b.data) == 0 {
- return nil, nil
- }
- u := &r.d.unit[r.unit]
- e := r.b.entry(u.atable, u.base)
- if r.b.err != nil {
- r.err = r.b.err
- return nil, r.err
- }
- if e != nil {
- r.lastChildren = e.Children
- if r.lastChildren {
- r.lastSibling, _ = e.Val(AttrSibling).(Offset)
- }
- } else {
- r.lastChildren = false
- }
- return e, nil
-}
-
-// SkipChildren skips over the child entries associated with
-// the last Entry returned by Next. If that Entry did not have
-// children or Next has not been called, SkipChildren is a no-op.
-func (r *Reader) SkipChildren() {
- if r.err != nil || !r.lastChildren {
- return
- }
-
- // If the last entry had a sibling attribute,
- // that attribute gives the offset of the next
- // sibling, so we can avoid decoding the
- // child subtrees.
- if r.lastSibling >= r.b.off {
- r.Seek(r.lastSibling)
- return
- }
-
- for {
- e, err := r.Next()
- if err != nil || e == nil || e.Tag == 0 {
- break
- }
- if e.Children {
- r.SkipChildren()
- }
- }
-}
-
-// clone returns a copy of the reader. This is used by the typeReader
-// interface.
-func (r *Reader) clone() typeReader {
- return r.d.Reader()
-}
-
-// offset returns the current buffer offset. This is used by the
-// typeReader interface.
-func (r *Reader) offset() Offset {
- return r.b.off
-}
diff --git a/src/pkg/debug/dwarf/open.go b/src/pkg/debug/dwarf/open.go
deleted file mode 100644
index c1b3f37ac..000000000
--- a/src/pkg/debug/dwarf/open.go
+++ /dev/null
@@ -1,87 +0,0 @@
-// 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 provides access to DWARF debugging information loaded from
-// executable files, as defined in the DWARF 2.0 Standard at
-// http://dwarfstd.org/doc/dwarf-2.0.0.pdf
-package dwarf
-
-import "encoding/binary"
-
-// Data represents the DWARF debugging information
-// loaded from an executable file (for example, an ELF or Mach-O executable).
-type Data struct {
- // raw data
- abbrev []byte
- aranges []byte
- frame []byte
- info []byte
- line []byte
- pubnames []byte
- ranges []byte
- str []byte
-
- // parsed data
- abbrevCache map[uint32]abbrevTable
- order binary.ByteOrder
- typeCache map[Offset]Type
- typeSigs map[uint64]*typeUnit
- unit []unit
-}
-
-// New returns a new Data object initialized from the given parameters.
-// Rather than calling this function directly, clients should typically use
-// the DWARF method of the File type of the appropriate package debug/elf,
-// debug/macho, or debug/pe.
-//
-// The []byte arguments are the data from the corresponding debug section
-// in the object file; for example, for an ELF object, abbrev is the contents of
-// the ".debug_abbrev" section.
-func New(abbrev, aranges, frame, info, line, pubnames, ranges, str []byte) (*Data, error) {
- d := &Data{
- abbrev: abbrev,
- aranges: aranges,
- frame: frame,
- info: info,
- line: line,
- pubnames: pubnames,
- ranges: ranges,
- str: str,
- abbrevCache: make(map[uint32]abbrevTable),
- typeCache: make(map[Offset]Type),
- typeSigs: make(map[uint64]*typeUnit),
- }
-
- // Sniff .debug_info to figure out byte order.
- // bytes 4:6 are the version, a tiny 16-bit number (1, 2, 3).
- if len(d.info) < 6 {
- return nil, DecodeError{"info", Offset(len(d.info)), "too short"}
- }
- x, y := d.info[4], d.info[5]
- switch {
- case x == 0 && y == 0:
- return nil, DecodeError{"info", 4, "unsupported version 0"}
- case x == 0:
- d.order = binary.BigEndian
- case y == 0:
- d.order = binary.LittleEndian
- default:
- return nil, DecodeError{"info", 4, "cannot determine byte order"}
- }
-
- u, err := d.parseUnits()
- if err != nil {
- return nil, err
- }
- d.unit = u
- return d, nil
-}
-
-// AddTypes will add one .debug_types section to the DWARF data. A
-// typical object with DWARF version 4 debug info will have multiple
-// .debug_types sections. The name is used for error reporting only,
-// and serves to distinguish one .debug_types section from another.
-func (d *Data) AddTypes(name string, types []byte) error {
- return d.parseTypes(name, types)
-}
diff --git a/src/pkg/debug/dwarf/testdata/typedef.c b/src/pkg/debug/dwarf/testdata/typedef.c
deleted file mode 100644
index f05f01564..000000000
--- a/src/pkg/debug/dwarf/testdata/typedef.c
+++ /dev/null
@@ -1,85 +0,0 @@
-// 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.
-
-/*
-Linux ELF:
-gcc -gdwarf-2 -m64 -c typedef.c && gcc -gdwarf-2 -m64 -o typedef.elf typedef.o
-
-OS X Mach-O:
-gcc -gdwarf-2 -m64 -c typedef.c -o typedef.macho
-*/
-#include <complex.h>
-
-typedef volatile int* t_ptr_volatile_int;
-typedef const char *t_ptr_const_char;
-typedef long t_long;
-typedef unsigned short t_ushort;
-typedef int t_func_int_of_float_double(float, double);
-typedef int (*t_ptr_func_int_of_float_double)(float, double);
-typedef int (*t_ptr_func_int_of_float_complex)(float complex);
-typedef int (*t_ptr_func_int_of_double_complex)(double complex);
-typedef int (*t_ptr_func_int_of_long_double_complex)(long double complex);
-typedef int *t_func_ptr_int_of_char_schar_uchar(char, signed char, unsigned char);
-typedef void t_func_void_of_char(char);
-typedef void t_func_void_of_void(void);
-typedef void t_func_void_of_ptr_char_dots(char*, ...);
-typedef struct my_struct {
- volatile int vi;
- char x : 1;
- int y : 4;
- int z[0];
- long long array[40];
- int zz[0];
-} t_my_struct;
-typedef struct my_struct1 {
- int zz [1];
-} t_my_struct1;
-typedef union my_union {
- volatile int vi;
- char x : 1;
- int y : 4;
- long long array[40];
-} t_my_union;
-typedef enum my_enum {
- e1 = 1,
- e2 = 2,
- e3 = -5,
- e4 = 1000000000000000LL,
-} t_my_enum;
-
-typedef struct list t_my_list;
-struct list {
- short val;
- t_my_list *next;
-};
-
-typedef struct tree {
- struct tree *left, *right;
- unsigned long long val;
-} t_my_tree;
-
-t_ptr_volatile_int *a2;
-t_ptr_const_char **a3a;
-t_long *a4;
-t_ushort *a5;
-t_func_int_of_float_double *a6;
-t_ptr_func_int_of_float_double *a7;
-t_func_ptr_int_of_char_schar_uchar *a8;
-t_func_void_of_char *a9;
-t_func_void_of_void *a10;
-t_func_void_of_ptr_char_dots *a11;
-t_my_struct *a12;
-t_my_struct1 *a12a;
-t_my_union *a12b;
-t_my_enum *a13;
-t_my_list *a14;
-t_my_tree *a15;
-t_ptr_func_int_of_float_complex *a16;
-t_ptr_func_int_of_double_complex *a17;
-t_ptr_func_int_of_long_double_complex *a18;
-
-int main()
-{
- return 0;
-}
diff --git a/src/pkg/debug/dwarf/testdata/typedef.elf b/src/pkg/debug/dwarf/testdata/typedef.elf
deleted file mode 100755
index b2062d2c4..000000000
--- a/src/pkg/debug/dwarf/testdata/typedef.elf
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/dwarf/testdata/typedef.elf4 b/src/pkg/debug/dwarf/testdata/typedef.elf4
deleted file mode 100644
index 3d5a5a1b1..000000000
--- a/src/pkg/debug/dwarf/testdata/typedef.elf4
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/dwarf/testdata/typedef.macho b/src/pkg/debug/dwarf/testdata/typedef.macho
deleted file mode 100644
index f75afcccb..000000000
--- a/src/pkg/debug/dwarf/testdata/typedef.macho
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/dwarf/type.go b/src/pkg/debug/dwarf/type.go
deleted file mode 100644
index 68866d0b7..000000000
--- a/src/pkg/debug/dwarf/type.go
+++ /dev/null
@@ -1,659 +0,0 @@
-// 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.
-
-// DWARF type information structures.
-// The format is heavily biased toward C, but for simplicity
-// the String methods use a pseudo-Go syntax.
-
-package dwarf
-
-import "strconv"
-
-// A Type conventionally represents a pointer to any of the
-// specific Type structures (CharType, StructType, etc.).
-type Type interface {
- Common() *CommonType
- String() string
- Size() int64
-}
-
-// A CommonType holds fields common to multiple types.
-// If a field is not known or not applicable for a given type,
-// the zero value is used.
-type CommonType struct {
- ByteSize int64 // size of value of this type, in bytes
- Name string // name that can be used to refer to type
-}
-
-func (c *CommonType) Common() *CommonType { return c }
-
-func (c *CommonType) Size() int64 { return c.ByteSize }
-
-// Basic types
-
-// A BasicType holds fields common to all basic types.
-type BasicType struct {
- CommonType
- BitSize int64
- BitOffset int64
-}
-
-func (b *BasicType) Basic() *BasicType { return b }
-
-func (t *BasicType) String() string {
- if t.Name != "" {
- return t.Name
- }
- return "?"
-}
-
-// A CharType represents a signed character type.
-type CharType struct {
- BasicType
-}
-
-// A UcharType represents an unsigned character type.
-type UcharType struct {
- BasicType
-}
-
-// An IntType represents a signed integer type.
-type IntType struct {
- BasicType
-}
-
-// A UintType represents an unsigned integer type.
-type UintType struct {
- BasicType
-}
-
-// A FloatType represents a floating point type.
-type FloatType struct {
- BasicType
-}
-
-// A ComplexType represents a complex floating point type.
-type ComplexType struct {
- BasicType
-}
-
-// A BoolType represents a boolean type.
-type BoolType struct {
- BasicType
-}
-
-// An AddrType represents a machine address type.
-type AddrType struct {
- BasicType
-}
-
-// qualifiers
-
-// A QualType represents a type that has the C/C++ "const", "restrict", or "volatile" qualifier.
-type QualType struct {
- CommonType
- Qual string
- Type Type
-}
-
-func (t *QualType) String() string { return t.Qual + " " + t.Type.String() }
-
-func (t *QualType) Size() int64 { return t.Type.Size() }
-
-// An ArrayType represents a fixed size array type.
-type ArrayType struct {
- CommonType
- Type Type
- StrideBitSize int64 // if > 0, number of bits to hold each element
- Count int64 // if == -1, an incomplete array, like char x[].
-}
-
-func (t *ArrayType) String() string {
- return "[" + strconv.FormatInt(t.Count, 10) + "]" + t.Type.String()
-}
-
-func (t *ArrayType) Size() int64 { return t.Count * t.Type.Size() }
-
-// A VoidType represents the C void type.
-type VoidType struct {
- CommonType
-}
-
-func (t *VoidType) String() string { return "void" }
-
-// A PtrType represents a pointer type.
-type PtrType struct {
- CommonType
- Type Type
-}
-
-func (t *PtrType) String() string { return "*" + t.Type.String() }
-
-// A StructType represents a struct, union, or C++ class type.
-type StructType struct {
- CommonType
- StructName string
- Kind string // "struct", "union", or "class".
- Field []*StructField
- Incomplete bool // if true, struct, union, class is declared but not defined
-}
-
-// A StructField represents a field in a struct, union, or C++ class type.
-type StructField struct {
- Name string
- Type Type
- ByteOffset int64
- ByteSize int64
- BitOffset int64 // within the ByteSize bytes at ByteOffset
- BitSize int64 // zero if not a bit field
-}
-
-func (t *StructType) String() string {
- if t.StructName != "" {
- return t.Kind + " " + t.StructName
- }
- return t.Defn()
-}
-
-func (t *StructType) Defn() string {
- s := t.Kind
- if t.StructName != "" {
- s += " " + t.StructName
- }
- if t.Incomplete {
- s += " /*incomplete*/"
- return s
- }
- s += " {"
- for i, f := range t.Field {
- if i > 0 {
- s += "; "
- }
- s += f.Name + " " + f.Type.String()
- s += "@" + strconv.FormatInt(f.ByteOffset, 10)
- if f.BitSize > 0 {
- s += " : " + strconv.FormatInt(f.BitSize, 10)
- s += "@" + strconv.FormatInt(f.BitOffset, 10)
- }
- }
- s += "}"
- return s
-}
-
-// An EnumType represents an enumerated type.
-// The only indication of its native integer type is its ByteSize
-// (inside CommonType).
-type EnumType struct {
- CommonType
- EnumName string
- Val []*EnumValue
-}
-
-// An EnumValue represents a single enumeration value.
-type EnumValue struct {
- Name string
- Val int64
-}
-
-func (t *EnumType) String() string {
- s := "enum"
- if t.EnumName != "" {
- s += " " + t.EnumName
- }
- s += " {"
- for i, v := range t.Val {
- if i > 0 {
- s += "; "
- }
- s += v.Name + "=" + strconv.FormatInt(v.Val, 10)
- }
- s += "}"
- return s
-}
-
-// A FuncType represents a function type.
-type FuncType struct {
- CommonType
- ReturnType Type
- ParamType []Type
-}
-
-func (t *FuncType) String() string {
- s := "func("
- for i, t := range t.ParamType {
- if i > 0 {
- s += ", "
- }
- s += t.String()
- }
- s += ")"
- if t.ReturnType != nil {
- s += " " + t.ReturnType.String()
- }
- return s
-}
-
-// A DotDotDotType represents the variadic ... function parameter.
-type DotDotDotType struct {
- CommonType
-}
-
-func (t *DotDotDotType) String() string { return "..." }
-
-// A TypedefType represents a named type.
-type TypedefType struct {
- CommonType
- Type Type
-}
-
-func (t *TypedefType) String() string { return t.Name }
-
-func (t *TypedefType) Size() int64 { return t.Type.Size() }
-
-// typeReader is used to read from either the info section or the
-// types section.
-type typeReader interface {
- Seek(Offset)
- Next() (*Entry, error)
- clone() typeReader
- offset() Offset
-}
-
-// 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)
-}
-
-// 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) {
- if t, ok := typeCache[off]; ok {
- return t, nil
- }
- r.Seek(off)
- e, err := r.Next()
- if err != nil {
- return nil, err
- }
- if e == nil || e.Offset != off {
- return nil, DecodeError{name, off, "no type at offset"}
- }
-
- // Parse type from Entry.
- // Must always set typeCache[off] before calling
- // d.Type recursively, to handle circular types correctly.
- var typ Type
-
- nextDepth := 0
-
- // Get next child; set err if error happens.
- next := func() *Entry {
- if !e.Children {
- return nil
- }
- // Only return direct children.
- // Skip over composite entries that happen to be nested
- // inside this one. Most DWARF generators wouldn't generate
- // such a thing, but clang does.
- // See golang.org/issue/6472.
- for {
- kid, err1 := r.Next()
- if err1 != nil {
- err = err1
- return nil
- }
- if kid == nil {
- err = DecodeError{name, r.offset(), "unexpected end of DWARF entries"}
- return nil
- }
- if kid.Tag == 0 {
- if nextDepth > 0 {
- nextDepth--
- continue
- }
- return nil
- }
- if kid.Children {
- nextDepth++
- }
- if nextDepth > 0 {
- continue
- }
- return kid
- }
- }
-
- // Get Type referred to by Entry's AttrType field.
- // Set err if error happens. Not having a type is an error.
- typeOf := func(e *Entry) Type {
- tval := e.Val(AttrType)
- var t Type
- switch toff := tval.(type) {
- case Offset:
- if t, err = d.readType(name, r.clone(), toff, typeCache); err != nil {
- return nil
- }
- case uint64:
- if t, err = d.sigToType(toff); err != nil {
- return nil
- }
- default:
- // It appears that no Type means "void".
- return new(VoidType)
- }
- return t
- }
-
- switch e.Tag {
- case TagArrayType:
- // Multi-dimensional array. (DWARF v2 §5.4)
- // Attributes:
- // AttrType:subtype [required]
- // AttrStrideSize: size in bits of each element of the array
- // AttrByteSize: size of entire array
- // Children:
- // TagSubrangeType or TagEnumerationType giving one dimension.
- // dimensions are in left to right order.
- t := new(ArrayType)
- typ = t
- typeCache[off] = t
- if t.Type = typeOf(e); err != nil {
- goto Error
- }
- t.StrideBitSize, _ = e.Val(AttrStrideSize).(int64)
-
- // Accumulate dimensions,
- ndim := 0
- for kid := next(); kid != nil; kid = next() {
- // TODO(rsc): Can also be TagEnumerationType
- // but haven't seen that in the wild yet.
- switch kid.Tag {
- case TagSubrangeType:
- max, ok := kid.Val(AttrUpperBound).(int64)
- if !ok {
- max = -2 // Count == -1, as in x[].
- }
- if ndim == 0 {
- t.Count = max + 1
- } else {
- // Multidimensional array.
- // Create new array type underneath this one.
- t.Type = &ArrayType{Type: t.Type, Count: max + 1}
- }
- ndim++
- case TagEnumerationType:
- err = DecodeError{name, kid.Offset, "cannot handle enumeration type as array bound"}
- goto Error
- }
- }
- if ndim == 0 {
- // LLVM generates this for x[].
- t.Count = -1
- }
-
- case TagBaseType:
- // Basic type. (DWARF v2 §5.1)
- // Attributes:
- // AttrName: name of base type in programming language of the compilation unit [required]
- // AttrEncoding: encoding value for type (encFloat etc) [required]
- // AttrByteSize: size of type in bytes [required]
- // AttrBitOffset: for sub-byte types, size in bits
- // AttrBitSize: for sub-byte types, bit offset of high order bit in the AttrByteSize bytes
- name, _ := e.Val(AttrName).(string)
- enc, ok := e.Val(AttrEncoding).(int64)
- if !ok {
- err = DecodeError{name, e.Offset, "missing encoding attribute for " + name}
- goto Error
- }
- switch enc {
- default:
- err = DecodeError{name, e.Offset, "unrecognized encoding attribute value"}
- goto Error
-
- case encAddress:
- typ = new(AddrType)
- case encBoolean:
- typ = new(BoolType)
- case encComplexFloat:
- typ = new(ComplexType)
- case encFloat:
- typ = new(FloatType)
- case encSigned:
- typ = new(IntType)
- case encUnsigned:
- typ = new(UintType)
- case encSignedChar:
- typ = new(CharType)
- case encUnsignedChar:
- typ = new(UcharType)
- }
- typeCache[off] = typ
- t := typ.(interface {
- Basic() *BasicType
- }).Basic()
- t.Name = name
- t.BitSize, _ = e.Val(AttrBitSize).(int64)
- t.BitOffset, _ = e.Val(AttrBitOffset).(int64)
-
- case TagClassType, TagStructType, TagUnionType:
- // Structure, union, or class type. (DWARF v2 §5.5)
- // Attributes:
- // AttrName: name of struct, union, or class
- // AttrByteSize: byte size [required]
- // AttrDeclaration: if true, struct/union/class is incomplete
- // Children:
- // TagMember to describe one member.
- // AttrName: name of member [required]
- // AttrType: type of member [required]
- // AttrByteSize: size in bytes
- // AttrBitOffset: bit offset within bytes for bit fields
- // AttrBitSize: bit size for bit fields
- // AttrDataMemberLoc: location within struct [required for struct, class]
- // There is much more to handle C++, all ignored for now.
- t := new(StructType)
- typ = t
- typeCache[off] = t
- switch e.Tag {
- case TagClassType:
- t.Kind = "class"
- case TagStructType:
- t.Kind = "struct"
- case TagUnionType:
- t.Kind = "union"
- }
- t.StructName, _ = e.Val(AttrName).(string)
- t.Incomplete = e.Val(AttrDeclaration) != nil
- t.Field = make([]*StructField, 0, 8)
- var lastFieldType Type
- var lastFieldBitOffset int64
- for kid := next(); kid != nil; kid = next() {
- if kid.Tag == TagMember {
- f := new(StructField)
- if f.Type = typeOf(kid); err != nil {
- goto Error
- }
- switch loc := kid.Val(AttrDataMemberLoc).(type) {
- case []byte:
- // TODO: Should have original compilation
- // unit here, not unknownFormat.
- b := makeBuf(d, unknownFormat{}, "location", 0, loc)
- if b.uint8() != opPlusUconst {
- err = DecodeError{name, kid.Offset, "unexpected opcode"}
- goto Error
- }
- f.ByteOffset = int64(b.uint())
- if b.err != nil {
- err = b.err
- goto Error
- }
- case int64:
- f.ByteOffset = loc
- }
-
- haveBitOffset := false
- f.Name, _ = kid.Val(AttrName).(string)
- f.ByteSize, _ = kid.Val(AttrByteSize).(int64)
- f.BitOffset, haveBitOffset = kid.Val(AttrBitOffset).(int64)
- f.BitSize, _ = kid.Val(AttrBitSize).(int64)
- t.Field = append(t.Field, f)
-
- bito := f.BitOffset
- if !haveBitOffset {
- bito = f.ByteOffset * 8
- }
- if bito == lastFieldBitOffset && t.Kind != "union" {
- // Last field was zero width. Fix array length.
- // (DWARF writes out 0-length arrays as if they were 1-length arrays.)
- zeroArray(lastFieldType)
- }
- lastFieldType = f.Type
- lastFieldBitOffset = bito
- }
- }
- if t.Kind != "union" {
- b, ok := e.Val(AttrByteSize).(int64)
- if ok && b*8 == lastFieldBitOffset {
- // Final field must be zero width. Fix array length.
- zeroArray(lastFieldType)
- }
- }
-
- case TagConstType, TagVolatileType, TagRestrictType:
- // Type modifier (DWARF v2 §5.2)
- // Attributes:
- // AttrType: subtype
- t := new(QualType)
- typ = t
- typeCache[off] = t
- if t.Type = typeOf(e); err != nil {
- goto Error
- }
- switch e.Tag {
- case TagConstType:
- t.Qual = "const"
- case TagRestrictType:
- t.Qual = "restrict"
- case TagVolatileType:
- t.Qual = "volatile"
- }
-
- case TagEnumerationType:
- // Enumeration type (DWARF v2 §5.6)
- // Attributes:
- // AttrName: enum name if any
- // AttrByteSize: bytes required to represent largest value
- // Children:
- // TagEnumerator:
- // AttrName: name of constant
- // AttrConstValue: value of constant
- t := new(EnumType)
- typ = t
- typeCache[off] = t
- t.EnumName, _ = e.Val(AttrName).(string)
- t.Val = make([]*EnumValue, 0, 8)
- for kid := next(); kid != nil; kid = next() {
- if kid.Tag == TagEnumerator {
- f := new(EnumValue)
- f.Name, _ = kid.Val(AttrName).(string)
- f.Val, _ = kid.Val(AttrConstValue).(int64)
- n := len(t.Val)
- if n >= cap(t.Val) {
- val := make([]*EnumValue, n, n*2)
- copy(val, t.Val)
- t.Val = val
- }
- t.Val = t.Val[0 : n+1]
- t.Val[n] = f
- }
- }
-
- case TagPointerType:
- // Type modifier (DWARF v2 §5.2)
- // Attributes:
- // AttrType: subtype [not required! void* has no AttrType]
- // AttrAddrClass: address class [ignored]
- t := new(PtrType)
- typ = t
- typeCache[off] = t
- if e.Val(AttrType) == nil {
- t.Type = &VoidType{}
- break
- }
- t.Type = typeOf(e)
-
- case TagSubroutineType:
- // Subroutine type. (DWARF v2 §5.7)
- // Attributes:
- // AttrType: type of return value if any
- // AttrName: possible name of type [ignored]
- // AttrPrototyped: whether used ANSI C prototype [ignored]
- // Children:
- // TagFormalParameter: typed parameter
- // AttrType: type of parameter
- // TagUnspecifiedParameter: final ...
- t := new(FuncType)
- typ = t
- typeCache[off] = t
- if t.ReturnType = typeOf(e); err != nil {
- goto Error
- }
- t.ParamType = make([]Type, 0, 8)
- for kid := next(); kid != nil; kid = next() {
- var tkid Type
- switch kid.Tag {
- default:
- continue
- case TagFormalParameter:
- if tkid = typeOf(kid); err != nil {
- goto Error
- }
- case TagUnspecifiedParameters:
- tkid = &DotDotDotType{}
- }
- t.ParamType = append(t.ParamType, tkid)
- }
-
- case TagTypedef:
- // Typedef (DWARF v2 §5.3)
- // Attributes:
- // AttrName: name [required]
- // AttrType: type definition [required]
- t := new(TypedefType)
- typ = t
- typeCache[off] = t
- t.Name, _ = e.Val(AttrName).(string)
- t.Type = typeOf(e)
- }
-
- if err != nil {
- goto Error
- }
-
- {
- b, ok := e.Val(AttrByteSize).(int64)
- if !ok {
- b = -1
- }
- typ.Common().ByteSize = b
- }
- return typ, nil
-
-Error:
- // If the parse fails, take the type out of the cache
- // so that the next call with this offset doesn't hit
- // the cache and return success.
- delete(typeCache, off)
- return nil, err
-}
-
-func zeroArray(t Type) {
- for {
- at, ok := t.(*ArrayType)
- if !ok {
- break
- }
- at.Count = 0
- t = at.Type
- }
-}
diff --git a/src/pkg/debug/dwarf/type_test.go b/src/pkg/debug/dwarf/type_test.go
deleted file mode 100644
index 2cb85e74b..000000000
--- a/src/pkg/debug/dwarf/type_test.go
+++ /dev/null
@@ -1,122 +0,0 @@
-// 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"
- "debug/elf"
- "debug/macho"
- "testing"
-)
-
-var typedefTests = map[string]string{
- "t_ptr_volatile_int": "*volatile int",
- "t_ptr_const_char": "*const char",
- "t_long": "long int",
- "t_ushort": "short unsigned int",
- "t_func_int_of_float_double": "func(float, double) int",
- "t_ptr_func_int_of_float_double": "*func(float, double) int",
- "t_ptr_func_int_of_float_complex": "*func(complex float) int",
- "t_ptr_func_int_of_double_complex": "*func(complex double) int",
- "t_ptr_func_int_of_long_double_complex": "*func(complex long double) int",
- "t_func_ptr_int_of_char_schar_uchar": "func(char, signed char, unsigned char) *int",
- "t_func_void_of_char": "func(char) void",
- "t_func_void_of_void": "func() void",
- "t_func_void_of_ptr_char_dots": "func(*char, ...) void",
- "t_my_struct": "struct my_struct {vi volatile int@0; x char@4 : 1@7; y int@4 : 4@27; z [0]int@8; array [40]long long int@8; zz [0]int@328}",
- "t_my_struct1": "struct my_struct1 {zz [1]int@0}",
- "t_my_union": "union my_union {vi volatile int@0; x char@0 : 1@7; y int@0 : 4@28; array [40]long long int@0}",
- "t_my_enum": "enum my_enum {e1=1; e2=2; e3=-5; e4=1000000000000000}",
- "t_my_list": "struct list {val short int@0; next *t_my_list@8}",
- "t_my_tree": "struct tree {left *struct tree@0; right *struct tree@8; val long long unsigned int@16}",
-}
-
-// As Apple converts gcc to a clang-based front end
-// they keep breaking the DWARF output. This map lists the
-// conversion from real answer to Apple answer.
-var machoBug = map[string]string{
- "func(*char, ...) void": "func(*char) void",
- "enum my_enum {e1=1; e2=2; e3=-5; e4=1000000000000000}": "enum my_enum {e1=1; e2=2; e3=-5; e4=-1530494976}",
-}
-
-func elfData(t *testing.T, name string) *Data {
- f, err := elf.Open(name)
- if err != nil {
- t.Fatal(err)
- }
-
- d, err := f.DWARF()
- if err != nil {
- t.Fatal(err)
- }
- return d
-}
-
-func machoData(t *testing.T, name string) *Data {
- f, err := macho.Open(name)
- if err != nil {
- t.Fatal(err)
- }
-
- d, err := f.DWARF()
- if err != nil {
- t.Fatal(err)
- }
- return d
-}
-
-func TestTypedefsELF(t *testing.T) { testTypedefs(t, elfData(t, "testdata/typedef.elf"), "elf") }
-
-func TestTypedefsMachO(t *testing.T) {
- testTypedefs(t, machoData(t, "testdata/typedef.macho"), "macho")
-}
-
-func TestTypedefsELFDwarf4(t *testing.T) { testTypedefs(t, elfData(t, "testdata/typedef.elf4"), "elf") }
-
-func testTypedefs(t *testing.T, d *Data, kind string) {
- 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 == TagTypedef {
- typ, err := d.Type(e.Offset)
- if err != nil {
- t.Fatal("d.Type:", err)
- }
- t1 := typ.(*TypedefType)
- var typstr string
- if ts, ok := t1.Type.(*StructType); ok {
- typstr = ts.Defn()
- } else {
- typstr = t1.Type.String()
- }
-
- if want, ok := typedefTests[t1.Name]; ok {
- if seen[t1.Name] {
- t.Errorf("multiple definitions for %s", t1.Name)
- }
- seen[t1.Name] = true
- if typstr != want && (kind != "macho" || typstr != machoBug[want]) {
- t.Errorf("%s:\n\thave %s\n\twant %s", t1.Name, typstr, want)
- }
- }
- }
- if e.Tag != TagCompileUnit {
- r.SkipChildren()
- }
- }
-
- for k := range typedefTests {
- if !seen[k] {
- t.Errorf("missing %s", k)
- }
- }
-}
diff --git a/src/pkg/debug/dwarf/typeunit.go b/src/pkg/debug/dwarf/typeunit.go
deleted file mode 100644
index 3fd1c9973..000000000
--- a/src/pkg/debug/dwarf/typeunit.go
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2012 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
-
-import (
- "fmt"
- "strconv"
-)
-
-// Parse the type units stored in a DWARF4 .debug_types section. Each
-// type unit defines a single primary type and an 8-byte signature.
-// Other sections may then use formRefSig8 to refer to the type.
-
-// The typeUnit format is a single type with a signature. It holds
-// the same data as a compilation unit.
-type typeUnit struct {
- unit
- toff Offset // Offset to signature type within data.
- name string // Name of .debug_type section.
- cache Type // Cache the type, nil to start.
-}
-
-// Parse a .debug_types section.
-func (d *Data) parseTypes(name string, types []byte) error {
- b := makeBuf(d, unknownFormat{}, name, 0, types)
- for len(b.data) > 0 {
- base := b.off
- dwarf64 := false
- n := b.uint32()
- if n == 0xffffffff {
- n64 := b.uint64()
- if n64 != uint64(uint32(n64)) {
- b.error("type unit length overflow")
- return b.err
- }
- n = uint32(n64)
- dwarf64 = true
- }
- hdroff := b.off
- vers := b.uint16()
- if vers != 4 {
- b.error("unsupported DWARF version " + strconv.Itoa(int(vers)))
- return b.err
- }
- var ao uint32
- if !dwarf64 {
- ao = b.uint32()
- } else {
- ao64 := b.uint64()
- if ao64 != uint64(uint32(ao64)) {
- b.error("type unit abbrev offset overflow")
- return b.err
- }
- ao = uint32(ao64)
- }
- atable, err := d.parseAbbrev(ao)
- if err != nil {
- return err
- }
- asize := b.uint8()
- sig := b.uint64()
-
- var toff uint32
- if !dwarf64 {
- toff = b.uint32()
- } else {
- to64 := b.uint64()
- if to64 != uint64(uint32(to64)) {
- b.error("type unit type offset overflow")
- return b.err
- }
- toff = uint32(to64)
- }
-
- boff := b.off
- d.typeSigs[sig] = &typeUnit{
- unit: unit{
- base: base,
- off: boff,
- data: b.bytes(int(Offset(n) - (b.off - hdroff))),
- atable: atable,
- asize: int(asize),
- vers: int(vers),
- is64: dwarf64,
- },
- toff: Offset(toff),
- name: name,
- }
- if b.err != nil {
- return b.err
- }
- }
- return nil
-}
-
-// Return the type for a type signature.
-func (d *Data) sigToType(sig uint64) (Type, error) {
- tu := d.typeSigs[sig]
- if tu == nil {
- return nil, fmt.Errorf("no type unit with signature %v", sig)
- }
- if tu.cache != nil {
- return tu.cache, nil
- }
-
- 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))
- if err != nil {
- return nil, err
- }
-
- tu.cache = t
- return t, nil
-}
-
-// typeUnitReader is a typeReader for a tagTypeUnit.
-type typeUnitReader struct {
- d *Data
- tu *typeUnit
- b buf
- err error
-}
-
-// Seek to a new position in the type unit.
-func (tur *typeUnitReader) Seek(off Offset) {
- tur.err = nil
- doff := off - tur.tu.off
- if doff < 0 || doff >= Offset(len(tur.tu.data)) {
- tur.err = fmt.Errorf("%s: offset %d out of range; max %d", tur.tu.name, doff, len(tur.tu.data))
- return
- }
- tur.b = makeBuf(tur.d, tur.tu, tur.tu.name, off, tur.tu.data[doff:])
-}
-
-// Next reads the next Entry from the type unit.
-func (tur *typeUnitReader) Next() (*Entry, error) {
- if tur.err != nil {
- return nil, tur.err
- }
- if len(tur.tu.data) == 0 {
- return nil, nil
- }
- e := tur.b.entry(tur.tu.atable, tur.tu.base)
- if tur.b.err != nil {
- tur.err = tur.b.err
- return nil, tur.err
- }
- return e, nil
-}
-
-// clone returns a new reader for the type unit.
-func (tur *typeUnitReader) clone() typeReader {
- return &typeUnitReader{
- d: tur.d,
- tu: tur.tu,
- b: makeBuf(tur.d, tur.tu, tur.tu.name, tur.tu.off, tur.tu.data),
- }
-}
-
-// offset returns the current offset.
-func (tur *typeUnitReader) offset() Offset {
- return tur.b.off
-}
diff --git a/src/pkg/debug/dwarf/unit.go b/src/pkg/debug/dwarf/unit.go
deleted file mode 100644
index 0fbc8e082..000000000
--- a/src/pkg/debug/dwarf/unit.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// 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
-
-import "strconv"
-
-// DWARF debug info is split into a sequence of compilation units.
-// Each unit has its own abbreviation table and address size.
-
-type unit struct {
- base Offset // byte offset of header within the aggregate info
- off Offset // byte offset of data within the aggregate info
- data []byte
- atable abbrevTable
- asize int
- vers int
- is64 bool // True for 64-bit DWARF format
-}
-
-// Implement the dataFormat interface.
-
-func (u *unit) version() int {
- return u.vers
-}
-
-func (u *unit) dwarf64() (bool, bool) {
- return u.is64, true
-}
-
-func (u *unit) addrsize() int {
- return u.asize
-}
-
-func (d *Data) parseUnits() ([]unit, error) {
- // Count units.
- nunit := 0
- b := makeBuf(d, unknownFormat{}, "info", 0, d.info)
- for len(b.data) > 0 {
- len := b.uint32()
- if len == 0xffffffff {
- len64 := b.uint64()
- if len64 != uint64(uint32(len64)) {
- b.error("unit length overflow")
- break
- }
- len = uint32(len64)
- }
- b.skip(int(len))
- nunit++
- }
- if b.err != nil {
- return nil, b.err
- }
-
- // Again, this time writing them down.
- b = makeBuf(d, unknownFormat{}, "info", 0, d.info)
- units := make([]unit, nunit)
- for i := range units {
- u := &units[i]
- u.base = b.off
- n := b.uint32()
- if n == 0xffffffff {
- u.is64 = true
- n = uint32(b.uint64())
- }
- vers := b.uint16()
- if vers != 2 && vers != 3 && vers != 4 {
- b.error("unsupported DWARF version " + strconv.Itoa(int(vers)))
- break
- }
- u.vers = int(vers)
- atable, err := d.parseAbbrev(b.uint32())
- if err != nil {
- if b.err == nil {
- b.err = err
- }
- break
- }
- u.atable = atable
- u.asize = int(b.uint8())
- u.off = b.off
- u.data = b.bytes(int(n - (2 + 4 + 1)))
- }
- if b.err != nil {
- return nil, b.err
- }
- return units, nil
-}