summaryrefslogtreecommitdiff
path: root/src/pkg/debug
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/debug')
-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
-rw-r--r--src/pkg/debug/elf/elf.go1521
-rw-r--r--src/pkg/debug/elf/elf_test.go49
-rw-r--r--src/pkg/debug/elf/file.go881
-rw-r--r--src/pkg/debug/elf/file_test.go339
-rwxr-xr-xsrc/pkg/debug/elf/testdata/gcc-386-freebsd-execbin5742 -> 0 bytes
-rwxr-xr-xsrc/pkg/debug/elf/testdata/gcc-amd64-linux-execbin8844 -> 0 bytes
-rw-r--r--src/pkg/debug/elf/testdata/gcc-amd64-openbsd-debug-with-rela.objbin6544 -> 0 bytes
-rw-r--r--src/pkg/debug/elf/testdata/go-relocation-test-clang-x86.objbin1900 -> 0 bytes
-rw-r--r--src/pkg/debug/elf/testdata/go-relocation-test-gcc424-x86-64.objbin3088 -> 0 bytes
-rw-r--r--src/pkg/debug/elf/testdata/go-relocation-test-gcc441-x86-64.objbin2936 -> 0 bytes
-rw-r--r--src/pkg/debug/elf/testdata/go-relocation-test-gcc441-x86.objbin1884 -> 0 bytes
-rw-r--r--src/pkg/debug/elf/testdata/hello-world-core.gzbin12678 -> 0 bytes
-rw-r--r--src/pkg/debug/elf/testdata/hello.c7
-rw-r--r--src/pkg/debug/gosym/pclinetest.asm58
-rw-r--r--src/pkg/debug/gosym/pclinetest.h9
-rw-r--r--src/pkg/debug/gosym/pclntab.go453
-rw-r--r--src/pkg/debug/gosym/pclntab_test.go274
-rw-r--r--src/pkg/debug/gosym/symtab.go710
-rw-r--r--src/pkg/debug/macho/fat.go146
-rw-r--r--src/pkg/debug/macho/file.go524
-rw-r--r--src/pkg/debug/macho/file_test.go210
-rw-r--r--src/pkg/debug/macho/macho.go316
-rw-r--r--src/pkg/debug/macho/testdata/fat-gcc-386-amd64-darwin-execbin28992 -> 0 bytes
-rwxr-xr-xsrc/pkg/debug/macho/testdata/gcc-386-darwin-execbin12588 -> 0 bytes
-rwxr-xr-xsrc/pkg/debug/macho/testdata/gcc-amd64-darwin-execbin8512 -> 0 bytes
-rw-r--r--src/pkg/debug/macho/testdata/gcc-amd64-darwin-exec-debugbin4540 -> 0 bytes
-rw-r--r--src/pkg/debug/macho/testdata/hello.c8
-rw-r--r--src/pkg/debug/pe/file.go390
-rw-r--r--src/pkg/debug/pe/file_test.go236
-rw-r--r--src/pkg/debug/pe/pe.go134
-rw-r--r--src/pkg/debug/pe/testdata/gcc-386-mingw-execbin29941 -> 0 bytes
-rw-r--r--src/pkg/debug/pe/testdata/gcc-386-mingw-objbin2372 -> 0 bytes
-rw-r--r--src/pkg/debug/pe/testdata/gcc-amd64-mingw-execbin37376 -> 0 bytes
-rw-r--r--src/pkg/debug/pe/testdata/gcc-amd64-mingw-objbin736 -> 0 bytes
-rw-r--r--src/pkg/debug/pe/testdata/hello.c8
-rw-r--r--src/pkg/debug/plan9obj/file.go325
-rw-r--r--src/pkg/debug/plan9obj/file_test.go81
-rw-r--r--src/pkg/debug/plan9obj/plan9obj.go36
-rwxr-xr-xsrc/pkg/debug/plan9obj/testdata/386-plan9-execbin37232 -> 0 bytes
-rwxr-xr-xsrc/pkg/debug/plan9obj/testdata/amd64-plan9-execbin34279 -> 0 bytes
-rw-r--r--src/pkg/debug/plan9obj/testdata/hello.c8
53 files changed, 0 insertions, 8968 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
-}
diff --git a/src/pkg/debug/elf/elf.go b/src/pkg/debug/elf/elf.go
deleted file mode 100644
index d622dae2a..000000000
--- a/src/pkg/debug/elf/elf.go
+++ /dev/null
@@ -1,1521 +0,0 @@
-/*
- * ELF constants and data structures
- *
- * Derived from:
- * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.1 2005/12/30 22:13:58 marcel Exp $
- * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.1 2005/12/30 22:13:58 marcel Exp $
- * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.1 2005/12/30 22:13:58 marcel Exp $
- * $FreeBSD: src/sys/alpha/include/elf.h,v 1.14 2003/09/25 01:10:22 peter Exp $
- * $FreeBSD: src/sys/amd64/include/elf.h,v 1.18 2004/08/03 08:21:48 dfr Exp $
- * $FreeBSD: src/sys/arm/include/elf.h,v 1.5.2.1 2006/06/30 21:42:52 cognet Exp $
- * $FreeBSD: src/sys/i386/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $
- * $FreeBSD: src/sys/powerpc/include/elf.h,v 1.7 2004/11/02 09:47:01 ssouhlal Exp $
- * $FreeBSD: src/sys/sparc64/include/elf.h,v 1.12 2003/09/25 01:10:26 peter Exp $
- *
- * Copyright (c) 1996-1998 John D. Polstra. All rights reserved.
- * Copyright (c) 2001 David E. O'Brien
- * Portions Copyright 2009 The Go Authors. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-package elf
-
-import "strconv"
-
-/*
- * Constants
- */
-
-// Indexes into the Header.Ident array.
-const (
- EI_CLASS = 4 /* Class of machine. */
- EI_DATA = 5 /* Data format. */
- EI_VERSION = 6 /* ELF format version. */
- EI_OSABI = 7 /* Operating system / ABI identification */
- EI_ABIVERSION = 8 /* ABI version */
- EI_PAD = 9 /* Start of padding (per SVR4 ABI). */
- EI_NIDENT = 16 /* Size of e_ident array. */
-)
-
-// Initial magic number for ELF files.
-const ELFMAG = "\177ELF"
-
-// Version is found in Header.Ident[EI_VERSION] and Header.Version.
-type Version byte
-
-const (
- EV_NONE Version = 0
- EV_CURRENT Version = 1
-)
-
-var versionStrings = []intName{
- {0, "EV_NONE"},
- {1, "EV_CURRENT"},
-}
-
-func (i Version) String() string { return stringName(uint32(i), versionStrings, false) }
-func (i Version) GoString() string { return stringName(uint32(i), versionStrings, true) }
-
-// Class is found in Header.Ident[EI_CLASS] and Header.Class.
-type Class byte
-
-const (
- ELFCLASSNONE Class = 0 /* Unknown class. */
- ELFCLASS32 Class = 1 /* 32-bit architecture. */
- ELFCLASS64 Class = 2 /* 64-bit architecture. */
-)
-
-var classStrings = []intName{
- {0, "ELFCLASSNONE"},
- {1, "ELFCLASS32"},
- {2, "ELFCLASS64"},
-}
-
-func (i Class) String() string { return stringName(uint32(i), classStrings, false) }
-func (i Class) GoString() string { return stringName(uint32(i), classStrings, true) }
-
-// Data is found in Header.Ident[EI_DATA] and Header.Data.
-type Data byte
-
-const (
- ELFDATANONE Data = 0 /* Unknown data format. */
- ELFDATA2LSB Data = 1 /* 2's complement little-endian. */
- ELFDATA2MSB Data = 2 /* 2's complement big-endian. */
-)
-
-var dataStrings = []intName{
- {0, "ELFDATANONE"},
- {1, "ELFDATA2LSB"},
- {2, "ELFDATA2MSB"},
-}
-
-func (i Data) String() string { return stringName(uint32(i), dataStrings, false) }
-func (i Data) GoString() string { return stringName(uint32(i), dataStrings, true) }
-
-// OSABI is found in Header.Ident[EI_OSABI] and Header.OSABI.
-type OSABI byte
-
-const (
- ELFOSABI_NONE OSABI = 0 /* UNIX System V ABI */
- ELFOSABI_HPUX OSABI = 1 /* HP-UX operating system */
- ELFOSABI_NETBSD OSABI = 2 /* NetBSD */
- ELFOSABI_LINUX OSABI = 3 /* GNU/Linux */
- ELFOSABI_HURD OSABI = 4 /* GNU/Hurd */
- ELFOSABI_86OPEN OSABI = 5 /* 86Open common IA32 ABI */
- ELFOSABI_SOLARIS OSABI = 6 /* Solaris */
- ELFOSABI_AIX OSABI = 7 /* AIX */
- ELFOSABI_IRIX OSABI = 8 /* IRIX */
- ELFOSABI_FREEBSD OSABI = 9 /* FreeBSD */
- ELFOSABI_TRU64 OSABI = 10 /* TRU64 UNIX */
- ELFOSABI_MODESTO OSABI = 11 /* Novell Modesto */
- ELFOSABI_OPENBSD OSABI = 12 /* OpenBSD */
- ELFOSABI_OPENVMS OSABI = 13 /* Open VMS */
- ELFOSABI_NSK OSABI = 14 /* HP Non-Stop Kernel */
- ELFOSABI_ARM OSABI = 97 /* ARM */
- ELFOSABI_STANDALONE OSABI = 255 /* Standalone (embedded) application */
-)
-
-var osabiStrings = []intName{
- {0, "ELFOSABI_NONE"},
- {1, "ELFOSABI_HPUX"},
- {2, "ELFOSABI_NETBSD"},
- {3, "ELFOSABI_LINUX"},
- {4, "ELFOSABI_HURD"},
- {5, "ELFOSABI_86OPEN"},
- {6, "ELFOSABI_SOLARIS"},
- {7, "ELFOSABI_AIX"},
- {8, "ELFOSABI_IRIX"},
- {9, "ELFOSABI_FREEBSD"},
- {10, "ELFOSABI_TRU64"},
- {11, "ELFOSABI_MODESTO"},
- {12, "ELFOSABI_OPENBSD"},
- {13, "ELFOSABI_OPENVMS"},
- {14, "ELFOSABI_NSK"},
- {97, "ELFOSABI_ARM"},
- {255, "ELFOSABI_STANDALONE"},
-}
-
-func (i OSABI) String() string { return stringName(uint32(i), osabiStrings, false) }
-func (i OSABI) GoString() string { return stringName(uint32(i), osabiStrings, true) }
-
-// Type is found in Header.Type.
-type Type uint16
-
-const (
- ET_NONE Type = 0 /* Unknown type. */
- ET_REL Type = 1 /* Relocatable. */
- ET_EXEC Type = 2 /* Executable. */
- ET_DYN Type = 3 /* Shared object. */
- ET_CORE Type = 4 /* Core file. */
- ET_LOOS Type = 0xfe00 /* First operating system specific. */
- ET_HIOS Type = 0xfeff /* Last operating system-specific. */
- ET_LOPROC Type = 0xff00 /* First processor-specific. */
- ET_HIPROC Type = 0xffff /* Last processor-specific. */
-)
-
-var typeStrings = []intName{
- {0, "ET_NONE"},
- {1, "ET_REL"},
- {2, "ET_EXEC"},
- {3, "ET_DYN"},
- {4, "ET_CORE"},
- {0xfe00, "ET_LOOS"},
- {0xfeff, "ET_HIOS"},
- {0xff00, "ET_LOPROC"},
- {0xffff, "ET_HIPROC"},
-}
-
-func (i Type) String() string { return stringName(uint32(i), typeStrings, false) }
-func (i Type) GoString() string { return stringName(uint32(i), typeStrings, true) }
-
-// Machine is found in Header.Machine.
-type Machine uint16
-
-const (
- EM_NONE Machine = 0 /* Unknown machine. */
- EM_M32 Machine = 1 /* AT&T WE32100. */
- EM_SPARC Machine = 2 /* Sun SPARC. */
- EM_386 Machine = 3 /* Intel i386. */
- EM_68K Machine = 4 /* Motorola 68000. */
- EM_88K Machine = 5 /* Motorola 88000. */
- EM_860 Machine = 7 /* Intel i860. */
- EM_MIPS Machine = 8 /* MIPS R3000 Big-Endian only. */
- EM_S370 Machine = 9 /* IBM System/370. */
- EM_MIPS_RS3_LE Machine = 10 /* MIPS R3000 Little-Endian. */
- EM_PARISC Machine = 15 /* HP PA-RISC. */
- EM_VPP500 Machine = 17 /* Fujitsu VPP500. */
- EM_SPARC32PLUS Machine = 18 /* SPARC v8plus. */
- EM_960 Machine = 19 /* Intel 80960. */
- EM_PPC Machine = 20 /* PowerPC 32-bit. */
- EM_PPC64 Machine = 21 /* PowerPC 64-bit. */
- EM_S390 Machine = 22 /* IBM System/390. */
- EM_V800 Machine = 36 /* NEC V800. */
- EM_FR20 Machine = 37 /* Fujitsu FR20. */
- EM_RH32 Machine = 38 /* TRW RH-32. */
- EM_RCE Machine = 39 /* Motorola RCE. */
- EM_ARM Machine = 40 /* ARM. */
- EM_SH Machine = 42 /* Hitachi SH. */
- EM_SPARCV9 Machine = 43 /* SPARC v9 64-bit. */
- EM_TRICORE Machine = 44 /* Siemens TriCore embedded processor. */
- EM_ARC Machine = 45 /* Argonaut RISC Core. */
- EM_H8_300 Machine = 46 /* Hitachi H8/300. */
- EM_H8_300H Machine = 47 /* Hitachi H8/300H. */
- EM_H8S Machine = 48 /* Hitachi H8S. */
- EM_H8_500 Machine = 49 /* Hitachi H8/500. */
- EM_IA_64 Machine = 50 /* Intel IA-64 Processor. */
- EM_MIPS_X Machine = 51 /* Stanford MIPS-X. */
- EM_COLDFIRE Machine = 52 /* Motorola ColdFire. */
- EM_68HC12 Machine = 53 /* Motorola M68HC12. */
- EM_MMA Machine = 54 /* Fujitsu MMA. */
- EM_PCP Machine = 55 /* Siemens PCP. */
- EM_NCPU Machine = 56 /* Sony nCPU. */
- EM_NDR1 Machine = 57 /* Denso NDR1 microprocessor. */
- EM_STARCORE Machine = 58 /* Motorola Star*Core processor. */
- EM_ME16 Machine = 59 /* Toyota ME16 processor. */
- EM_ST100 Machine = 60 /* STMicroelectronics ST100 processor. */
- EM_TINYJ Machine = 61 /* Advanced Logic Corp. TinyJ processor. */
- EM_X86_64 Machine = 62 /* Advanced Micro Devices x86-64 */
-
- /* Non-standard or deprecated. */
- EM_486 Machine = 6 /* Intel i486. */
- EM_MIPS_RS4_BE Machine = 10 /* MIPS R4000 Big-Endian */
- EM_ALPHA_STD Machine = 41 /* Digital Alpha (standard value). */
- EM_ALPHA Machine = 0x9026 /* Alpha (written in the absence of an ABI) */
-)
-
-var machineStrings = []intName{
- {0, "EM_NONE"},
- {1, "EM_M32"},
- {2, "EM_SPARC"},
- {3, "EM_386"},
- {4, "EM_68K"},
- {5, "EM_88K"},
- {7, "EM_860"},
- {8, "EM_MIPS"},
- {9, "EM_S370"},
- {10, "EM_MIPS_RS3_LE"},
- {15, "EM_PARISC"},
- {17, "EM_VPP500"},
- {18, "EM_SPARC32PLUS"},
- {19, "EM_960"},
- {20, "EM_PPC"},
- {21, "EM_PPC64"},
- {22, "EM_S390"},
- {36, "EM_V800"},
- {37, "EM_FR20"},
- {38, "EM_RH32"},
- {39, "EM_RCE"},
- {40, "EM_ARM"},
- {42, "EM_SH"},
- {43, "EM_SPARCV9"},
- {44, "EM_TRICORE"},
- {45, "EM_ARC"},
- {46, "EM_H8_300"},
- {47, "EM_H8_300H"},
- {48, "EM_H8S"},
- {49, "EM_H8_500"},
- {50, "EM_IA_64"},
- {51, "EM_MIPS_X"},
- {52, "EM_COLDFIRE"},
- {53, "EM_68HC12"},
- {54, "EM_MMA"},
- {55, "EM_PCP"},
- {56, "EM_NCPU"},
- {57, "EM_NDR1"},
- {58, "EM_STARCORE"},
- {59, "EM_ME16"},
- {60, "EM_ST100"},
- {61, "EM_TINYJ"},
- {62, "EM_X86_64"},
-
- /* Non-standard or deprecated. */
- {6, "EM_486"},
- {10, "EM_MIPS_RS4_BE"},
- {41, "EM_ALPHA_STD"},
- {0x9026, "EM_ALPHA"},
-}
-
-func (i Machine) String() string { return stringName(uint32(i), machineStrings, false) }
-func (i Machine) GoString() string { return stringName(uint32(i), machineStrings, true) }
-
-// Special section indices.
-type SectionIndex int
-
-const (
- SHN_UNDEF SectionIndex = 0 /* Undefined, missing, irrelevant. */
- SHN_LORESERVE SectionIndex = 0xff00 /* First of reserved range. */
- SHN_LOPROC SectionIndex = 0xff00 /* First processor-specific. */
- SHN_HIPROC SectionIndex = 0xff1f /* Last processor-specific. */
- SHN_LOOS SectionIndex = 0xff20 /* First operating system-specific. */
- SHN_HIOS SectionIndex = 0xff3f /* Last operating system-specific. */
- SHN_ABS SectionIndex = 0xfff1 /* Absolute values. */
- SHN_COMMON SectionIndex = 0xfff2 /* Common data. */
- SHN_XINDEX SectionIndex = 0xffff /* Escape -- index stored elsewhere. */
- SHN_HIRESERVE SectionIndex = 0xffff /* Last of reserved range. */
-)
-
-var shnStrings = []intName{
- {0, "SHN_UNDEF"},
- {0xff00, "SHN_LOPROC"},
- {0xff20, "SHN_LOOS"},
- {0xfff1, "SHN_ABS"},
- {0xfff2, "SHN_COMMON"},
- {0xffff, "SHN_XINDEX"},
-}
-
-func (i SectionIndex) String() string { return stringName(uint32(i), shnStrings, false) }
-func (i SectionIndex) GoString() string { return stringName(uint32(i), shnStrings, true) }
-
-// Section type.
-type SectionType uint32
-
-const (
- SHT_NULL SectionType = 0 /* inactive */
- SHT_PROGBITS SectionType = 1 /* program defined information */
- SHT_SYMTAB SectionType = 2 /* symbol table section */
- SHT_STRTAB SectionType = 3 /* string table section */
- SHT_RELA SectionType = 4 /* relocation section with addends */
- SHT_HASH SectionType = 5 /* symbol hash table section */
- SHT_DYNAMIC SectionType = 6 /* dynamic section */
- SHT_NOTE SectionType = 7 /* note section */
- SHT_NOBITS SectionType = 8 /* no space section */
- SHT_REL SectionType = 9 /* relocation section - no addends */
- SHT_SHLIB SectionType = 10 /* reserved - purpose unknown */
- SHT_DYNSYM SectionType = 11 /* dynamic symbol table section */
- SHT_INIT_ARRAY SectionType = 14 /* Initialization function pointers. */
- SHT_FINI_ARRAY SectionType = 15 /* Termination function pointers. */
- SHT_PREINIT_ARRAY SectionType = 16 /* Pre-initialization function ptrs. */
- SHT_GROUP SectionType = 17 /* Section group. */
- SHT_SYMTAB_SHNDX SectionType = 18 /* Section indexes (see SHN_XINDEX). */
- SHT_LOOS SectionType = 0x60000000 /* First of OS specific semantics */
- SHT_GNU_ATTRIBUTES SectionType = 0x6ffffff5 /* GNU object attributes */
- SHT_GNU_HASH SectionType = 0x6ffffff6 /* GNU hash table */
- SHT_GNU_LIBLIST SectionType = 0x6ffffff7 /* GNU prelink library list */
- SHT_GNU_VERDEF SectionType = 0x6ffffffd /* GNU version definition section */
- SHT_GNU_VERNEED SectionType = 0x6ffffffe /* GNU version needs section */
- SHT_GNU_VERSYM SectionType = 0x6fffffff /* GNU version symbol table */
- SHT_HIOS SectionType = 0x6fffffff /* Last of OS specific semantics */
- SHT_LOPROC SectionType = 0x70000000 /* reserved range for processor */
- SHT_HIPROC SectionType = 0x7fffffff /* specific section header types */
- SHT_LOUSER SectionType = 0x80000000 /* reserved range for application */
- SHT_HIUSER SectionType = 0xffffffff /* specific indexes */
-)
-
-var shtStrings = []intName{
- {0, "SHT_NULL"},
- {1, "SHT_PROGBITS"},
- {2, "SHT_SYMTAB"},
- {3, "SHT_STRTAB"},
- {4, "SHT_RELA"},
- {5, "SHT_HASH"},
- {6, "SHT_DYNAMIC"},
- {7, "SHT_NOTE"},
- {8, "SHT_NOBITS"},
- {9, "SHT_REL"},
- {10, "SHT_SHLIB"},
- {11, "SHT_DYNSYM"},
- {14, "SHT_INIT_ARRAY"},
- {15, "SHT_FINI_ARRAY"},
- {16, "SHT_PREINIT_ARRAY"},
- {17, "SHT_GROUP"},
- {18, "SHT_SYMTAB_SHNDX"},
- {0x60000000, "SHT_LOOS"},
- {0x6ffffff5, "SHT_GNU_ATTRIBUTES"},
- {0x6ffffff6, "SHT_GNU_HASH"},
- {0x6ffffff7, "SHT_GNU_LIBLIST"},
- {0x6ffffffd, "SHT_GNU_VERDEF"},
- {0x6ffffffe, "SHT_GNU_VERNEED"},
- {0x6fffffff, "SHT_GNU_VERSYM"},
- {0x70000000, "SHT_LOPROC"},
- {0x7fffffff, "SHT_HIPROC"},
- {0x80000000, "SHT_LOUSER"},
- {0xffffffff, "SHT_HIUSER"},
-}
-
-func (i SectionType) String() string { return stringName(uint32(i), shtStrings, false) }
-func (i SectionType) GoString() string { return stringName(uint32(i), shtStrings, true) }
-
-// Section flags.
-type SectionFlag uint32
-
-const (
- SHF_WRITE SectionFlag = 0x1 /* Section contains writable data. */
- SHF_ALLOC SectionFlag = 0x2 /* Section occupies memory. */
- SHF_EXECINSTR SectionFlag = 0x4 /* Section contains instructions. */
- SHF_MERGE SectionFlag = 0x10 /* Section may be merged. */
- SHF_STRINGS SectionFlag = 0x20 /* Section contains strings. */
- SHF_INFO_LINK SectionFlag = 0x40 /* sh_info holds section index. */
- SHF_LINK_ORDER SectionFlag = 0x80 /* Special ordering requirements. */
- SHF_OS_NONCONFORMING SectionFlag = 0x100 /* OS-specific processing required. */
- SHF_GROUP SectionFlag = 0x200 /* Member of section group. */
- SHF_TLS SectionFlag = 0x400 /* Section contains TLS data. */
- SHF_MASKOS SectionFlag = 0x0ff00000 /* OS-specific semantics. */
- SHF_MASKPROC SectionFlag = 0xf0000000 /* Processor-specific semantics. */
-)
-
-var shfStrings = []intName{
- {0x1, "SHF_WRITE"},
- {0x2, "SHF_ALLOC"},
- {0x4, "SHF_EXECINSTR"},
- {0x10, "SHF_MERGE"},
- {0x20, "SHF_STRINGS"},
- {0x40, "SHF_INFO_LINK"},
- {0x80, "SHF_LINK_ORDER"},
- {0x100, "SHF_OS_NONCONFORMING"},
- {0x200, "SHF_GROUP"},
- {0x400, "SHF_TLS"},
-}
-
-func (i SectionFlag) String() string { return flagName(uint32(i), shfStrings, false) }
-func (i SectionFlag) GoString() string { return flagName(uint32(i), shfStrings, true) }
-
-// Prog.Type
-type ProgType int
-
-const (
- PT_NULL ProgType = 0 /* Unused entry. */
- PT_LOAD ProgType = 1 /* Loadable segment. */
- PT_DYNAMIC ProgType = 2 /* Dynamic linking information segment. */
- PT_INTERP ProgType = 3 /* Pathname of interpreter. */
- PT_NOTE ProgType = 4 /* Auxiliary information. */
- PT_SHLIB ProgType = 5 /* Reserved (not used). */
- PT_PHDR ProgType = 6 /* Location of program header itself. */
- PT_TLS ProgType = 7 /* Thread local storage segment */
- PT_LOOS ProgType = 0x60000000 /* First OS-specific. */
- PT_HIOS ProgType = 0x6fffffff /* Last OS-specific. */
- PT_LOPROC ProgType = 0x70000000 /* First processor-specific type. */
- PT_HIPROC ProgType = 0x7fffffff /* Last processor-specific type. */
-)
-
-var ptStrings = []intName{
- {0, "PT_NULL"},
- {1, "PT_LOAD"},
- {2, "PT_DYNAMIC"},
- {3, "PT_INTERP"},
- {4, "PT_NOTE"},
- {5, "PT_SHLIB"},
- {6, "PT_PHDR"},
- {7, "PT_TLS"},
- {0x60000000, "PT_LOOS"},
- {0x6fffffff, "PT_HIOS"},
- {0x70000000, "PT_LOPROC"},
- {0x7fffffff, "PT_HIPROC"},
-}
-
-func (i ProgType) String() string { return stringName(uint32(i), ptStrings, false) }
-func (i ProgType) GoString() string { return stringName(uint32(i), ptStrings, true) }
-
-// Prog.Flag
-type ProgFlag uint32
-
-const (
- PF_X ProgFlag = 0x1 /* Executable. */
- PF_W ProgFlag = 0x2 /* Writable. */
- PF_R ProgFlag = 0x4 /* Readable. */
- PF_MASKOS ProgFlag = 0x0ff00000 /* Operating system-specific. */
- PF_MASKPROC ProgFlag = 0xf0000000 /* Processor-specific. */
-)
-
-var pfStrings = []intName{
- {0x1, "PF_X"},
- {0x2, "PF_W"},
- {0x4, "PF_R"},
-}
-
-func (i ProgFlag) String() string { return flagName(uint32(i), pfStrings, false) }
-func (i ProgFlag) GoString() string { return flagName(uint32(i), pfStrings, true) }
-
-// Dyn.Tag
-type DynTag int
-
-const (
- DT_NULL DynTag = 0 /* Terminating entry. */
- DT_NEEDED DynTag = 1 /* String table offset of a needed shared library. */
- DT_PLTRELSZ DynTag = 2 /* Total size in bytes of PLT relocations. */
- DT_PLTGOT DynTag = 3 /* Processor-dependent address. */
- DT_HASH DynTag = 4 /* Address of symbol hash table. */
- DT_STRTAB DynTag = 5 /* Address of string table. */
- DT_SYMTAB DynTag = 6 /* Address of symbol table. */
- DT_RELA DynTag = 7 /* Address of ElfNN_Rela relocations. */
- DT_RELASZ DynTag = 8 /* Total size of ElfNN_Rela relocations. */
- DT_RELAENT DynTag = 9 /* Size of each ElfNN_Rela relocation entry. */
- DT_STRSZ DynTag = 10 /* Size of string table. */
- DT_SYMENT DynTag = 11 /* Size of each symbol table entry. */
- DT_INIT DynTag = 12 /* Address of initialization function. */
- DT_FINI DynTag = 13 /* Address of finalization function. */
- DT_SONAME DynTag = 14 /* String table offset of shared object name. */
- DT_RPATH DynTag = 15 /* String table offset of library path. [sup] */
- DT_SYMBOLIC DynTag = 16 /* Indicates "symbolic" linking. [sup] */
- DT_REL DynTag = 17 /* Address of ElfNN_Rel relocations. */
- DT_RELSZ DynTag = 18 /* Total size of ElfNN_Rel relocations. */
- DT_RELENT DynTag = 19 /* Size of each ElfNN_Rel relocation. */
- DT_PLTREL DynTag = 20 /* Type of relocation used for PLT. */
- DT_DEBUG DynTag = 21 /* Reserved (not used). */
- DT_TEXTREL DynTag = 22 /* Indicates there may be relocations in non-writable segments. [sup] */
- DT_JMPREL DynTag = 23 /* Address of PLT relocations. */
- DT_BIND_NOW DynTag = 24 /* [sup] */
- DT_INIT_ARRAY DynTag = 25 /* Address of the array of pointers to initialization functions */
- DT_FINI_ARRAY DynTag = 26 /* Address of the array of pointers to termination functions */
- DT_INIT_ARRAYSZ DynTag = 27 /* Size in bytes of the array of initialization functions. */
- DT_FINI_ARRAYSZ DynTag = 28 /* Size in bytes of the array of termination functions. */
- DT_RUNPATH DynTag = 29 /* String table offset of a null-terminated library search path string. */
- DT_FLAGS DynTag = 30 /* Object specific flag values. */
- DT_ENCODING DynTag = 32 /* Values greater than or equal to DT_ENCODING
- and less than DT_LOOS follow the rules for
- the interpretation of the d_un union
- as follows: even == 'd_ptr', even == 'd_val'
- or none */
- DT_PREINIT_ARRAY DynTag = 32 /* Address of the array of pointers to pre-initialization functions. */
- DT_PREINIT_ARRAYSZ DynTag = 33 /* Size in bytes of the array of pre-initialization functions. */
- DT_LOOS DynTag = 0x6000000d /* First OS-specific */
- DT_HIOS DynTag = 0x6ffff000 /* Last OS-specific */
- DT_VERSYM DynTag = 0x6ffffff0
- DT_VERNEED DynTag = 0x6ffffffe
- DT_VERNEEDNUM DynTag = 0x6fffffff
- DT_LOPROC DynTag = 0x70000000 /* First processor-specific type. */
- DT_HIPROC DynTag = 0x7fffffff /* Last processor-specific type. */
-)
-
-var dtStrings = []intName{
- {0, "DT_NULL"},
- {1, "DT_NEEDED"},
- {2, "DT_PLTRELSZ"},
- {3, "DT_PLTGOT"},
- {4, "DT_HASH"},
- {5, "DT_STRTAB"},
- {6, "DT_SYMTAB"},
- {7, "DT_RELA"},
- {8, "DT_RELASZ"},
- {9, "DT_RELAENT"},
- {10, "DT_STRSZ"},
- {11, "DT_SYMENT"},
- {12, "DT_INIT"},
- {13, "DT_FINI"},
- {14, "DT_SONAME"},
- {15, "DT_RPATH"},
- {16, "DT_SYMBOLIC"},
- {17, "DT_REL"},
- {18, "DT_RELSZ"},
- {19, "DT_RELENT"},
- {20, "DT_PLTREL"},
- {21, "DT_DEBUG"},
- {22, "DT_TEXTREL"},
- {23, "DT_JMPREL"},
- {24, "DT_BIND_NOW"},
- {25, "DT_INIT_ARRAY"},
- {26, "DT_FINI_ARRAY"},
- {27, "DT_INIT_ARRAYSZ"},
- {28, "DT_FINI_ARRAYSZ"},
- {29, "DT_RUNPATH"},
- {30, "DT_FLAGS"},
- {32, "DT_ENCODING"},
- {32, "DT_PREINIT_ARRAY"},
- {33, "DT_PREINIT_ARRAYSZ"},
- {0x6000000d, "DT_LOOS"},
- {0x6ffff000, "DT_HIOS"},
- {0x6ffffff0, "DT_VERSYM"},
- {0x6ffffffe, "DT_VERNEED"},
- {0x6fffffff, "DT_VERNEEDNUM"},
- {0x70000000, "DT_LOPROC"},
- {0x7fffffff, "DT_HIPROC"},
-}
-
-func (i DynTag) String() string { return stringName(uint32(i), dtStrings, false) }
-func (i DynTag) GoString() string { return stringName(uint32(i), dtStrings, true) }
-
-// DT_FLAGS values.
-type DynFlag int
-
-const (
- DF_ORIGIN DynFlag = 0x0001 /* Indicates that the object being loaded may
- make reference to the
- $ORIGIN substitution string */
- DF_SYMBOLIC DynFlag = 0x0002 /* Indicates "symbolic" linking. */
- DF_TEXTREL DynFlag = 0x0004 /* Indicates there may be relocations in non-writable segments. */
- DF_BIND_NOW DynFlag = 0x0008 /* Indicates that the dynamic linker should
- process all relocations for the object
- containing this entry before transferring
- control to the program. */
- DF_STATIC_TLS DynFlag = 0x0010 /* Indicates that the shared object or
- executable contains code using a static
- thread-local storage scheme. */
-)
-
-var dflagStrings = []intName{
- {0x0001, "DF_ORIGIN"},
- {0x0002, "DF_SYMBOLIC"},
- {0x0004, "DF_TEXTREL"},
- {0x0008, "DF_BIND_NOW"},
- {0x0010, "DF_STATIC_TLS"},
-}
-
-func (i DynFlag) String() string { return flagName(uint32(i), dflagStrings, false) }
-func (i DynFlag) GoString() string { return flagName(uint32(i), dflagStrings, true) }
-
-// NType values; used in core files.
-type NType int
-
-const (
- NT_PRSTATUS NType = 1 /* Process status. */
- NT_FPREGSET NType = 2 /* Floating point registers. */
- NT_PRPSINFO NType = 3 /* Process state info. */
-)
-
-var ntypeStrings = []intName{
- {1, "NT_PRSTATUS"},
- {2, "NT_FPREGSET"},
- {3, "NT_PRPSINFO"},
-}
-
-func (i NType) String() string { return stringName(uint32(i), ntypeStrings, false) }
-func (i NType) GoString() string { return stringName(uint32(i), ntypeStrings, true) }
-
-/* Symbol Binding - ELFNN_ST_BIND - st_info */
-type SymBind int
-
-const (
- STB_LOCAL SymBind = 0 /* Local symbol */
- STB_GLOBAL SymBind = 1 /* Global symbol */
- STB_WEAK SymBind = 2 /* like global - lower precedence */
- STB_LOOS SymBind = 10 /* Reserved range for operating system */
- STB_HIOS SymBind = 12 /* specific semantics. */
- STB_LOPROC SymBind = 13 /* reserved range for processor */
- STB_HIPROC SymBind = 15 /* specific semantics. */
-)
-
-var stbStrings = []intName{
- {0, "STB_LOCAL"},
- {1, "STB_GLOBAL"},
- {2, "STB_WEAK"},
- {10, "STB_LOOS"},
- {12, "STB_HIOS"},
- {13, "STB_LOPROC"},
- {15, "STB_HIPROC"},
-}
-
-func (i SymBind) String() string { return stringName(uint32(i), stbStrings, false) }
-func (i SymBind) GoString() string { return stringName(uint32(i), stbStrings, true) }
-
-/* Symbol type - ELFNN_ST_TYPE - st_info */
-type SymType int
-
-const (
- STT_NOTYPE SymType = 0 /* Unspecified type. */
- STT_OBJECT SymType = 1 /* Data object. */
- STT_FUNC SymType = 2 /* Function. */
- STT_SECTION SymType = 3 /* Section. */
- STT_FILE SymType = 4 /* Source file. */
- STT_COMMON SymType = 5 /* Uninitialized common block. */
- STT_TLS SymType = 6 /* TLS object. */
- STT_LOOS SymType = 10 /* Reserved range for operating system */
- STT_HIOS SymType = 12 /* specific semantics. */
- STT_LOPROC SymType = 13 /* reserved range for processor */
- STT_HIPROC SymType = 15 /* specific semantics. */
-)
-
-var sttStrings = []intName{
- {0, "STT_NOTYPE"},
- {1, "STT_OBJECT"},
- {2, "STT_FUNC"},
- {3, "STT_SECTION"},
- {4, "STT_FILE"},
- {5, "STT_COMMON"},
- {6, "STT_TLS"},
- {10, "STT_LOOS"},
- {12, "STT_HIOS"},
- {13, "STT_LOPROC"},
- {15, "STT_HIPROC"},
-}
-
-func (i SymType) String() string { return stringName(uint32(i), sttStrings, false) }
-func (i SymType) GoString() string { return stringName(uint32(i), sttStrings, true) }
-
-/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */
-type SymVis int
-
-const (
- STV_DEFAULT SymVis = 0x0 /* Default visibility (see binding). */
- STV_INTERNAL SymVis = 0x1 /* Special meaning in relocatable objects. */
- STV_HIDDEN SymVis = 0x2 /* Not visible. */
- STV_PROTECTED SymVis = 0x3 /* Visible but not preemptible. */
-)
-
-var stvStrings = []intName{
- {0x0, "STV_DEFAULT"},
- {0x1, "STV_INTERNAL"},
- {0x2, "STV_HIDDEN"},
- {0x3, "STV_PROTECTED"},
-}
-
-func (i SymVis) String() string { return stringName(uint32(i), stvStrings, false) }
-func (i SymVis) GoString() string { return stringName(uint32(i), stvStrings, true) }
-
-/*
- * Relocation types.
- */
-
-// Relocation types for x86-64.
-type R_X86_64 int
-
-const (
- R_X86_64_NONE R_X86_64 = 0 /* No relocation. */
- R_X86_64_64 R_X86_64 = 1 /* Add 64 bit symbol value. */
- R_X86_64_PC32 R_X86_64 = 2 /* PC-relative 32 bit signed sym value. */
- R_X86_64_GOT32 R_X86_64 = 3 /* PC-relative 32 bit GOT offset. */
- R_X86_64_PLT32 R_X86_64 = 4 /* PC-relative 32 bit PLT offset. */
- R_X86_64_COPY R_X86_64 = 5 /* Copy data from shared object. */
- R_X86_64_GLOB_DAT R_X86_64 = 6 /* Set GOT entry to data address. */
- R_X86_64_JMP_SLOT R_X86_64 = 7 /* Set GOT entry to code address. */
- R_X86_64_RELATIVE R_X86_64 = 8 /* Add load address of shared object. */
- R_X86_64_GOTPCREL R_X86_64 = 9 /* Add 32 bit signed pcrel offset to GOT. */
- R_X86_64_32 R_X86_64 = 10 /* Add 32 bit zero extended symbol value */
- R_X86_64_32S R_X86_64 = 11 /* Add 32 bit sign extended symbol value */
- R_X86_64_16 R_X86_64 = 12 /* Add 16 bit zero extended symbol value */
- R_X86_64_PC16 R_X86_64 = 13 /* Add 16 bit signed extended pc relative symbol value */
- R_X86_64_8 R_X86_64 = 14 /* Add 8 bit zero extended symbol value */
- R_X86_64_PC8 R_X86_64 = 15 /* Add 8 bit signed extended pc relative symbol value */
- R_X86_64_DTPMOD64 R_X86_64 = 16 /* ID of module containing symbol */
- R_X86_64_DTPOFF64 R_X86_64 = 17 /* Offset in TLS block */
- R_X86_64_TPOFF64 R_X86_64 = 18 /* Offset in static TLS block */
- R_X86_64_TLSGD R_X86_64 = 19 /* PC relative offset to GD GOT entry */
- R_X86_64_TLSLD R_X86_64 = 20 /* PC relative offset to LD GOT entry */
- R_X86_64_DTPOFF32 R_X86_64 = 21 /* Offset in TLS block */
- R_X86_64_GOTTPOFF R_X86_64 = 22 /* PC relative offset to IE GOT entry */
- R_X86_64_TPOFF32 R_X86_64 = 23 /* Offset in static TLS block */
-)
-
-var rx86_64Strings = []intName{
- {0, "R_X86_64_NONE"},
- {1, "R_X86_64_64"},
- {2, "R_X86_64_PC32"},
- {3, "R_X86_64_GOT32"},
- {4, "R_X86_64_PLT32"},
- {5, "R_X86_64_COPY"},
- {6, "R_X86_64_GLOB_DAT"},
- {7, "R_X86_64_JMP_SLOT"},
- {8, "R_X86_64_RELATIVE"},
- {9, "R_X86_64_GOTPCREL"},
- {10, "R_X86_64_32"},
- {11, "R_X86_64_32S"},
- {12, "R_X86_64_16"},
- {13, "R_X86_64_PC16"},
- {14, "R_X86_64_8"},
- {15, "R_X86_64_PC8"},
- {16, "R_X86_64_DTPMOD64"},
- {17, "R_X86_64_DTPOFF64"},
- {18, "R_X86_64_TPOFF64"},
- {19, "R_X86_64_TLSGD"},
- {20, "R_X86_64_TLSLD"},
- {21, "R_X86_64_DTPOFF32"},
- {22, "R_X86_64_GOTTPOFF"},
- {23, "R_X86_64_TPOFF32"},
-}
-
-func (i R_X86_64) String() string { return stringName(uint32(i), rx86_64Strings, false) }
-func (i R_X86_64) GoString() string { return stringName(uint32(i), rx86_64Strings, true) }
-
-// Relocation types for Alpha.
-type R_ALPHA int
-
-const (
- R_ALPHA_NONE R_ALPHA = 0 /* No reloc */
- R_ALPHA_REFLONG R_ALPHA = 1 /* Direct 32 bit */
- R_ALPHA_REFQUAD R_ALPHA = 2 /* Direct 64 bit */
- R_ALPHA_GPREL32 R_ALPHA = 3 /* GP relative 32 bit */
- R_ALPHA_LITERAL R_ALPHA = 4 /* GP relative 16 bit w/optimization */
- R_ALPHA_LITUSE R_ALPHA = 5 /* Optimization hint for LITERAL */
- R_ALPHA_GPDISP R_ALPHA = 6 /* Add displacement to GP */
- R_ALPHA_BRADDR R_ALPHA = 7 /* PC+4 relative 23 bit shifted */
- R_ALPHA_HINT R_ALPHA = 8 /* PC+4 relative 16 bit shifted */
- R_ALPHA_SREL16 R_ALPHA = 9 /* PC relative 16 bit */
- R_ALPHA_SREL32 R_ALPHA = 10 /* PC relative 32 bit */
- R_ALPHA_SREL64 R_ALPHA = 11 /* PC relative 64 bit */
- R_ALPHA_OP_PUSH R_ALPHA = 12 /* OP stack push */
- R_ALPHA_OP_STORE R_ALPHA = 13 /* OP stack pop and store */
- R_ALPHA_OP_PSUB R_ALPHA = 14 /* OP stack subtract */
- R_ALPHA_OP_PRSHIFT R_ALPHA = 15 /* OP stack right shift */
- R_ALPHA_GPVALUE R_ALPHA = 16
- R_ALPHA_GPRELHIGH R_ALPHA = 17
- R_ALPHA_GPRELLOW R_ALPHA = 18
- R_ALPHA_IMMED_GP_16 R_ALPHA = 19
- R_ALPHA_IMMED_GP_HI32 R_ALPHA = 20
- R_ALPHA_IMMED_SCN_HI32 R_ALPHA = 21
- R_ALPHA_IMMED_BR_HI32 R_ALPHA = 22
- R_ALPHA_IMMED_LO32 R_ALPHA = 23
- R_ALPHA_COPY R_ALPHA = 24 /* Copy symbol at runtime */
- R_ALPHA_GLOB_DAT R_ALPHA = 25 /* Create GOT entry */
- R_ALPHA_JMP_SLOT R_ALPHA = 26 /* Create PLT entry */
- R_ALPHA_RELATIVE R_ALPHA = 27 /* Adjust by program base */
-)
-
-var ralphaStrings = []intName{
- {0, "R_ALPHA_NONE"},
- {1, "R_ALPHA_REFLONG"},
- {2, "R_ALPHA_REFQUAD"},
- {3, "R_ALPHA_GPREL32"},
- {4, "R_ALPHA_LITERAL"},
- {5, "R_ALPHA_LITUSE"},
- {6, "R_ALPHA_GPDISP"},
- {7, "R_ALPHA_BRADDR"},
- {8, "R_ALPHA_HINT"},
- {9, "R_ALPHA_SREL16"},
- {10, "R_ALPHA_SREL32"},
- {11, "R_ALPHA_SREL64"},
- {12, "R_ALPHA_OP_PUSH"},
- {13, "R_ALPHA_OP_STORE"},
- {14, "R_ALPHA_OP_PSUB"},
- {15, "R_ALPHA_OP_PRSHIFT"},
- {16, "R_ALPHA_GPVALUE"},
- {17, "R_ALPHA_GPRELHIGH"},
- {18, "R_ALPHA_GPRELLOW"},
- {19, "R_ALPHA_IMMED_GP_16"},
- {20, "R_ALPHA_IMMED_GP_HI32"},
- {21, "R_ALPHA_IMMED_SCN_HI32"},
- {22, "R_ALPHA_IMMED_BR_HI32"},
- {23, "R_ALPHA_IMMED_LO32"},
- {24, "R_ALPHA_COPY"},
- {25, "R_ALPHA_GLOB_DAT"},
- {26, "R_ALPHA_JMP_SLOT"},
- {27, "R_ALPHA_RELATIVE"},
-}
-
-func (i R_ALPHA) String() string { return stringName(uint32(i), ralphaStrings, false) }
-func (i R_ALPHA) GoString() string { return stringName(uint32(i), ralphaStrings, true) }
-
-// Relocation types for ARM.
-type R_ARM int
-
-const (
- R_ARM_NONE R_ARM = 0 /* No relocation. */
- R_ARM_PC24 R_ARM = 1
- R_ARM_ABS32 R_ARM = 2
- R_ARM_REL32 R_ARM = 3
- R_ARM_PC13 R_ARM = 4
- R_ARM_ABS16 R_ARM = 5
- R_ARM_ABS12 R_ARM = 6
- R_ARM_THM_ABS5 R_ARM = 7
- R_ARM_ABS8 R_ARM = 8
- R_ARM_SBREL32 R_ARM = 9
- R_ARM_THM_PC22 R_ARM = 10
- R_ARM_THM_PC8 R_ARM = 11
- R_ARM_AMP_VCALL9 R_ARM = 12
- R_ARM_SWI24 R_ARM = 13
- R_ARM_THM_SWI8 R_ARM = 14
- R_ARM_XPC25 R_ARM = 15
- R_ARM_THM_XPC22 R_ARM = 16
- R_ARM_COPY R_ARM = 20 /* Copy data from shared object. */
- R_ARM_GLOB_DAT R_ARM = 21 /* Set GOT entry to data address. */
- R_ARM_JUMP_SLOT R_ARM = 22 /* Set GOT entry to code address. */
- R_ARM_RELATIVE R_ARM = 23 /* Add load address of shared object. */
- R_ARM_GOTOFF R_ARM = 24 /* Add GOT-relative symbol address. */
- R_ARM_GOTPC R_ARM = 25 /* Add PC-relative GOT table address. */
- R_ARM_GOT32 R_ARM = 26 /* Add PC-relative GOT offset. */
- R_ARM_PLT32 R_ARM = 27 /* Add PC-relative PLT offset. */
- R_ARM_GNU_VTENTRY R_ARM = 100
- R_ARM_GNU_VTINHERIT R_ARM = 101
- R_ARM_RSBREL32 R_ARM = 250
- R_ARM_THM_RPC22 R_ARM = 251
- R_ARM_RREL32 R_ARM = 252
- R_ARM_RABS32 R_ARM = 253
- R_ARM_RPC24 R_ARM = 254
- R_ARM_RBASE R_ARM = 255
-)
-
-var rarmStrings = []intName{
- {0, "R_ARM_NONE"},
- {1, "R_ARM_PC24"},
- {2, "R_ARM_ABS32"},
- {3, "R_ARM_REL32"},
- {4, "R_ARM_PC13"},
- {5, "R_ARM_ABS16"},
- {6, "R_ARM_ABS12"},
- {7, "R_ARM_THM_ABS5"},
- {8, "R_ARM_ABS8"},
- {9, "R_ARM_SBREL32"},
- {10, "R_ARM_THM_PC22"},
- {11, "R_ARM_THM_PC8"},
- {12, "R_ARM_AMP_VCALL9"},
- {13, "R_ARM_SWI24"},
- {14, "R_ARM_THM_SWI8"},
- {15, "R_ARM_XPC25"},
- {16, "R_ARM_THM_XPC22"},
- {20, "R_ARM_COPY"},
- {21, "R_ARM_GLOB_DAT"},
- {22, "R_ARM_JUMP_SLOT"},
- {23, "R_ARM_RELATIVE"},
- {24, "R_ARM_GOTOFF"},
- {25, "R_ARM_GOTPC"},
- {26, "R_ARM_GOT32"},
- {27, "R_ARM_PLT32"},
- {100, "R_ARM_GNU_VTENTRY"},
- {101, "R_ARM_GNU_VTINHERIT"},
- {250, "R_ARM_RSBREL32"},
- {251, "R_ARM_THM_RPC22"},
- {252, "R_ARM_RREL32"},
- {253, "R_ARM_RABS32"},
- {254, "R_ARM_RPC24"},
- {255, "R_ARM_RBASE"},
-}
-
-func (i R_ARM) String() string { return stringName(uint32(i), rarmStrings, false) }
-func (i R_ARM) GoString() string { return stringName(uint32(i), rarmStrings, true) }
-
-// Relocation types for 386.
-type R_386 int
-
-const (
- R_386_NONE R_386 = 0 /* No relocation. */
- R_386_32 R_386 = 1 /* Add symbol value. */
- R_386_PC32 R_386 = 2 /* Add PC-relative symbol value. */
- R_386_GOT32 R_386 = 3 /* Add PC-relative GOT offset. */
- R_386_PLT32 R_386 = 4 /* Add PC-relative PLT offset. */
- R_386_COPY R_386 = 5 /* Copy data from shared object. */
- R_386_GLOB_DAT R_386 = 6 /* Set GOT entry to data address. */
- R_386_JMP_SLOT R_386 = 7 /* Set GOT entry to code address. */
- R_386_RELATIVE R_386 = 8 /* Add load address of shared object. */
- R_386_GOTOFF R_386 = 9 /* Add GOT-relative symbol address. */
- R_386_GOTPC R_386 = 10 /* Add PC-relative GOT table address. */
- R_386_TLS_TPOFF R_386 = 14 /* Negative offset in static TLS block */
- R_386_TLS_IE R_386 = 15 /* Absolute address of GOT for -ve static TLS */
- R_386_TLS_GOTIE R_386 = 16 /* GOT entry for negative static TLS block */
- R_386_TLS_LE R_386 = 17 /* Negative offset relative to static TLS */
- R_386_TLS_GD R_386 = 18 /* 32 bit offset to GOT (index,off) pair */
- R_386_TLS_LDM R_386 = 19 /* 32 bit offset to GOT (index,zero) pair */
- R_386_TLS_GD_32 R_386 = 24 /* 32 bit offset to GOT (index,off) pair */
- R_386_TLS_GD_PUSH R_386 = 25 /* pushl instruction for Sun ABI GD sequence */
- R_386_TLS_GD_CALL R_386 = 26 /* call instruction for Sun ABI GD sequence */
- R_386_TLS_GD_POP R_386 = 27 /* popl instruction for Sun ABI GD sequence */
- R_386_TLS_LDM_32 R_386 = 28 /* 32 bit offset to GOT (index,zero) pair */
- R_386_TLS_LDM_PUSH R_386 = 29 /* pushl instruction for Sun ABI LD sequence */
- R_386_TLS_LDM_CALL R_386 = 30 /* call instruction for Sun ABI LD sequence */
- R_386_TLS_LDM_POP R_386 = 31 /* popl instruction for Sun ABI LD sequence */
- R_386_TLS_LDO_32 R_386 = 32 /* 32 bit offset from start of TLS block */
- R_386_TLS_IE_32 R_386 = 33 /* 32 bit offset to GOT static TLS offset entry */
- R_386_TLS_LE_32 R_386 = 34 /* 32 bit offset within static TLS block */
- R_386_TLS_DTPMOD32 R_386 = 35 /* GOT entry containing TLS index */
- R_386_TLS_DTPOFF32 R_386 = 36 /* GOT entry containing TLS offset */
- R_386_TLS_TPOFF32 R_386 = 37 /* GOT entry of -ve static TLS offset */
-)
-
-var r386Strings = []intName{
- {0, "R_386_NONE"},
- {1, "R_386_32"},
- {2, "R_386_PC32"},
- {3, "R_386_GOT32"},
- {4, "R_386_PLT32"},
- {5, "R_386_COPY"},
- {6, "R_386_GLOB_DAT"},
- {7, "R_386_JMP_SLOT"},
- {8, "R_386_RELATIVE"},
- {9, "R_386_GOTOFF"},
- {10, "R_386_GOTPC"},
- {14, "R_386_TLS_TPOFF"},
- {15, "R_386_TLS_IE"},
- {16, "R_386_TLS_GOTIE"},
- {17, "R_386_TLS_LE"},
- {18, "R_386_TLS_GD"},
- {19, "R_386_TLS_LDM"},
- {24, "R_386_TLS_GD_32"},
- {25, "R_386_TLS_GD_PUSH"},
- {26, "R_386_TLS_GD_CALL"},
- {27, "R_386_TLS_GD_POP"},
- {28, "R_386_TLS_LDM_32"},
- {29, "R_386_TLS_LDM_PUSH"},
- {30, "R_386_TLS_LDM_CALL"},
- {31, "R_386_TLS_LDM_POP"},
- {32, "R_386_TLS_LDO_32"},
- {33, "R_386_TLS_IE_32"},
- {34, "R_386_TLS_LE_32"},
- {35, "R_386_TLS_DTPMOD32"},
- {36, "R_386_TLS_DTPOFF32"},
- {37, "R_386_TLS_TPOFF32"},
-}
-
-func (i R_386) String() string { return stringName(uint32(i), r386Strings, false) }
-func (i R_386) GoString() string { return stringName(uint32(i), r386Strings, true) }
-
-// Relocation types for PowerPC.
-type R_PPC int
-
-const (
- R_PPC_NONE R_PPC = 0 /* No relocation. */
- R_PPC_ADDR32 R_PPC = 1
- R_PPC_ADDR24 R_PPC = 2
- R_PPC_ADDR16 R_PPC = 3
- R_PPC_ADDR16_LO R_PPC = 4
- R_PPC_ADDR16_HI R_PPC = 5
- R_PPC_ADDR16_HA R_PPC = 6
- R_PPC_ADDR14 R_PPC = 7
- R_PPC_ADDR14_BRTAKEN R_PPC = 8
- R_PPC_ADDR14_BRNTAKEN R_PPC = 9
- R_PPC_REL24 R_PPC = 10
- R_PPC_REL14 R_PPC = 11
- R_PPC_REL14_BRTAKEN R_PPC = 12
- R_PPC_REL14_BRNTAKEN R_PPC = 13
- R_PPC_GOT16 R_PPC = 14
- R_PPC_GOT16_LO R_PPC = 15
- R_PPC_GOT16_HI R_PPC = 16
- R_PPC_GOT16_HA R_PPC = 17
- R_PPC_PLTREL24 R_PPC = 18
- R_PPC_COPY R_PPC = 19
- R_PPC_GLOB_DAT R_PPC = 20
- R_PPC_JMP_SLOT R_PPC = 21
- R_PPC_RELATIVE R_PPC = 22
- R_PPC_LOCAL24PC R_PPC = 23
- R_PPC_UADDR32 R_PPC = 24
- R_PPC_UADDR16 R_PPC = 25
- R_PPC_REL32 R_PPC = 26
- R_PPC_PLT32 R_PPC = 27
- R_PPC_PLTREL32 R_PPC = 28
- R_PPC_PLT16_LO R_PPC = 29
- R_PPC_PLT16_HI R_PPC = 30
- R_PPC_PLT16_HA R_PPC = 31
- R_PPC_SDAREL16 R_PPC = 32
- R_PPC_SECTOFF R_PPC = 33
- R_PPC_SECTOFF_LO R_PPC = 34
- R_PPC_SECTOFF_HI R_PPC = 35
- R_PPC_SECTOFF_HA R_PPC = 36
- R_PPC_TLS R_PPC = 67
- R_PPC_DTPMOD32 R_PPC = 68
- R_PPC_TPREL16 R_PPC = 69
- R_PPC_TPREL16_LO R_PPC = 70
- R_PPC_TPREL16_HI R_PPC = 71
- R_PPC_TPREL16_HA R_PPC = 72
- R_PPC_TPREL32 R_PPC = 73
- R_PPC_DTPREL16 R_PPC = 74
- R_PPC_DTPREL16_LO R_PPC = 75
- R_PPC_DTPREL16_HI R_PPC = 76
- R_PPC_DTPREL16_HA R_PPC = 77
- R_PPC_DTPREL32 R_PPC = 78
- R_PPC_GOT_TLSGD16 R_PPC = 79
- R_PPC_GOT_TLSGD16_LO R_PPC = 80
- R_PPC_GOT_TLSGD16_HI R_PPC = 81
- R_PPC_GOT_TLSGD16_HA R_PPC = 82
- R_PPC_GOT_TLSLD16 R_PPC = 83
- R_PPC_GOT_TLSLD16_LO R_PPC = 84
- R_PPC_GOT_TLSLD16_HI R_PPC = 85
- R_PPC_GOT_TLSLD16_HA R_PPC = 86
- R_PPC_GOT_TPREL16 R_PPC = 87
- R_PPC_GOT_TPREL16_LO R_PPC = 88
- R_PPC_GOT_TPREL16_HI R_PPC = 89
- R_PPC_GOT_TPREL16_HA R_PPC = 90
- R_PPC_EMB_NADDR32 R_PPC = 101
- R_PPC_EMB_NADDR16 R_PPC = 102
- R_PPC_EMB_NADDR16_LO R_PPC = 103
- R_PPC_EMB_NADDR16_HI R_PPC = 104
- R_PPC_EMB_NADDR16_HA R_PPC = 105
- R_PPC_EMB_SDAI16 R_PPC = 106
- R_PPC_EMB_SDA2I16 R_PPC = 107
- R_PPC_EMB_SDA2REL R_PPC = 108
- R_PPC_EMB_SDA21 R_PPC = 109
- R_PPC_EMB_MRKREF R_PPC = 110
- R_PPC_EMB_RELSEC16 R_PPC = 111
- R_PPC_EMB_RELST_LO R_PPC = 112
- R_PPC_EMB_RELST_HI R_PPC = 113
- R_PPC_EMB_RELST_HA R_PPC = 114
- R_PPC_EMB_BIT_FLD R_PPC = 115
- R_PPC_EMB_RELSDA R_PPC = 116
-)
-
-var rppcStrings = []intName{
- {0, "R_PPC_NONE"},
- {1, "R_PPC_ADDR32"},
- {2, "R_PPC_ADDR24"},
- {3, "R_PPC_ADDR16"},
- {4, "R_PPC_ADDR16_LO"},
- {5, "R_PPC_ADDR16_HI"},
- {6, "R_PPC_ADDR16_HA"},
- {7, "R_PPC_ADDR14"},
- {8, "R_PPC_ADDR14_BRTAKEN"},
- {9, "R_PPC_ADDR14_BRNTAKEN"},
- {10, "R_PPC_REL24"},
- {11, "R_PPC_REL14"},
- {12, "R_PPC_REL14_BRTAKEN"},
- {13, "R_PPC_REL14_BRNTAKEN"},
- {14, "R_PPC_GOT16"},
- {15, "R_PPC_GOT16_LO"},
- {16, "R_PPC_GOT16_HI"},
- {17, "R_PPC_GOT16_HA"},
- {18, "R_PPC_PLTREL24"},
- {19, "R_PPC_COPY"},
- {20, "R_PPC_GLOB_DAT"},
- {21, "R_PPC_JMP_SLOT"},
- {22, "R_PPC_RELATIVE"},
- {23, "R_PPC_LOCAL24PC"},
- {24, "R_PPC_UADDR32"},
- {25, "R_PPC_UADDR16"},
- {26, "R_PPC_REL32"},
- {27, "R_PPC_PLT32"},
- {28, "R_PPC_PLTREL32"},
- {29, "R_PPC_PLT16_LO"},
- {30, "R_PPC_PLT16_HI"},
- {31, "R_PPC_PLT16_HA"},
- {32, "R_PPC_SDAREL16"},
- {33, "R_PPC_SECTOFF"},
- {34, "R_PPC_SECTOFF_LO"},
- {35, "R_PPC_SECTOFF_HI"},
- {36, "R_PPC_SECTOFF_HA"},
-
- {67, "R_PPC_TLS"},
- {68, "R_PPC_DTPMOD32"},
- {69, "R_PPC_TPREL16"},
- {70, "R_PPC_TPREL16_LO"},
- {71, "R_PPC_TPREL16_HI"},
- {72, "R_PPC_TPREL16_HA"},
- {73, "R_PPC_TPREL32"},
- {74, "R_PPC_DTPREL16"},
- {75, "R_PPC_DTPREL16_LO"},
- {76, "R_PPC_DTPREL16_HI"},
- {77, "R_PPC_DTPREL16_HA"},
- {78, "R_PPC_DTPREL32"},
- {79, "R_PPC_GOT_TLSGD16"},
- {80, "R_PPC_GOT_TLSGD16_LO"},
- {81, "R_PPC_GOT_TLSGD16_HI"},
- {82, "R_PPC_GOT_TLSGD16_HA"},
- {83, "R_PPC_GOT_TLSLD16"},
- {84, "R_PPC_GOT_TLSLD16_LO"},
- {85, "R_PPC_GOT_TLSLD16_HI"},
- {86, "R_PPC_GOT_TLSLD16_HA"},
- {87, "R_PPC_GOT_TPREL16"},
- {88, "R_PPC_GOT_TPREL16_LO"},
- {89, "R_PPC_GOT_TPREL16_HI"},
- {90, "R_PPC_GOT_TPREL16_HA"},
-
- {101, "R_PPC_EMB_NADDR32"},
- {102, "R_PPC_EMB_NADDR16"},
- {103, "R_PPC_EMB_NADDR16_LO"},
- {104, "R_PPC_EMB_NADDR16_HI"},
- {105, "R_PPC_EMB_NADDR16_HA"},
- {106, "R_PPC_EMB_SDAI16"},
- {107, "R_PPC_EMB_SDA2I16"},
- {108, "R_PPC_EMB_SDA2REL"},
- {109, "R_PPC_EMB_SDA21"},
- {110, "R_PPC_EMB_MRKREF"},
- {111, "R_PPC_EMB_RELSEC16"},
- {112, "R_PPC_EMB_RELST_LO"},
- {113, "R_PPC_EMB_RELST_HI"},
- {114, "R_PPC_EMB_RELST_HA"},
- {115, "R_PPC_EMB_BIT_FLD"},
- {116, "R_PPC_EMB_RELSDA"},
-}
-
-func (i R_PPC) String() string { return stringName(uint32(i), rppcStrings, false) }
-func (i R_PPC) GoString() string { return stringName(uint32(i), rppcStrings, true) }
-
-// Relocation types for SPARC.
-type R_SPARC int
-
-const (
- R_SPARC_NONE R_SPARC = 0
- R_SPARC_8 R_SPARC = 1
- R_SPARC_16 R_SPARC = 2
- R_SPARC_32 R_SPARC = 3
- R_SPARC_DISP8 R_SPARC = 4
- R_SPARC_DISP16 R_SPARC = 5
- R_SPARC_DISP32 R_SPARC = 6
- R_SPARC_WDISP30 R_SPARC = 7
- R_SPARC_WDISP22 R_SPARC = 8
- R_SPARC_HI22 R_SPARC = 9
- R_SPARC_22 R_SPARC = 10
- R_SPARC_13 R_SPARC = 11
- R_SPARC_LO10 R_SPARC = 12
- R_SPARC_GOT10 R_SPARC = 13
- R_SPARC_GOT13 R_SPARC = 14
- R_SPARC_GOT22 R_SPARC = 15
- R_SPARC_PC10 R_SPARC = 16
- R_SPARC_PC22 R_SPARC = 17
- R_SPARC_WPLT30 R_SPARC = 18
- R_SPARC_COPY R_SPARC = 19
- R_SPARC_GLOB_DAT R_SPARC = 20
- R_SPARC_JMP_SLOT R_SPARC = 21
- R_SPARC_RELATIVE R_SPARC = 22
- R_SPARC_UA32 R_SPARC = 23
- R_SPARC_PLT32 R_SPARC = 24
- R_SPARC_HIPLT22 R_SPARC = 25
- R_SPARC_LOPLT10 R_SPARC = 26
- R_SPARC_PCPLT32 R_SPARC = 27
- R_SPARC_PCPLT22 R_SPARC = 28
- R_SPARC_PCPLT10 R_SPARC = 29
- R_SPARC_10 R_SPARC = 30
- R_SPARC_11 R_SPARC = 31
- R_SPARC_64 R_SPARC = 32
- R_SPARC_OLO10 R_SPARC = 33
- R_SPARC_HH22 R_SPARC = 34
- R_SPARC_HM10 R_SPARC = 35
- R_SPARC_LM22 R_SPARC = 36
- R_SPARC_PC_HH22 R_SPARC = 37
- R_SPARC_PC_HM10 R_SPARC = 38
- R_SPARC_PC_LM22 R_SPARC = 39
- R_SPARC_WDISP16 R_SPARC = 40
- R_SPARC_WDISP19 R_SPARC = 41
- R_SPARC_GLOB_JMP R_SPARC = 42
- R_SPARC_7 R_SPARC = 43
- R_SPARC_5 R_SPARC = 44
- R_SPARC_6 R_SPARC = 45
- R_SPARC_DISP64 R_SPARC = 46
- R_SPARC_PLT64 R_SPARC = 47
- R_SPARC_HIX22 R_SPARC = 48
- R_SPARC_LOX10 R_SPARC = 49
- R_SPARC_H44 R_SPARC = 50
- R_SPARC_M44 R_SPARC = 51
- R_SPARC_L44 R_SPARC = 52
- R_SPARC_REGISTER R_SPARC = 53
- R_SPARC_UA64 R_SPARC = 54
- R_SPARC_UA16 R_SPARC = 55
-)
-
-var rsparcStrings = []intName{
- {0, "R_SPARC_NONE"},
- {1, "R_SPARC_8"},
- {2, "R_SPARC_16"},
- {3, "R_SPARC_32"},
- {4, "R_SPARC_DISP8"},
- {5, "R_SPARC_DISP16"},
- {6, "R_SPARC_DISP32"},
- {7, "R_SPARC_WDISP30"},
- {8, "R_SPARC_WDISP22"},
- {9, "R_SPARC_HI22"},
- {10, "R_SPARC_22"},
- {11, "R_SPARC_13"},
- {12, "R_SPARC_LO10"},
- {13, "R_SPARC_GOT10"},
- {14, "R_SPARC_GOT13"},
- {15, "R_SPARC_GOT22"},
- {16, "R_SPARC_PC10"},
- {17, "R_SPARC_PC22"},
- {18, "R_SPARC_WPLT30"},
- {19, "R_SPARC_COPY"},
- {20, "R_SPARC_GLOB_DAT"},
- {21, "R_SPARC_JMP_SLOT"},
- {22, "R_SPARC_RELATIVE"},
- {23, "R_SPARC_UA32"},
- {24, "R_SPARC_PLT32"},
- {25, "R_SPARC_HIPLT22"},
- {26, "R_SPARC_LOPLT10"},
- {27, "R_SPARC_PCPLT32"},
- {28, "R_SPARC_PCPLT22"},
- {29, "R_SPARC_PCPLT10"},
- {30, "R_SPARC_10"},
- {31, "R_SPARC_11"},
- {32, "R_SPARC_64"},
- {33, "R_SPARC_OLO10"},
- {34, "R_SPARC_HH22"},
- {35, "R_SPARC_HM10"},
- {36, "R_SPARC_LM22"},
- {37, "R_SPARC_PC_HH22"},
- {38, "R_SPARC_PC_HM10"},
- {39, "R_SPARC_PC_LM22"},
- {40, "R_SPARC_WDISP16"},
- {41, "R_SPARC_WDISP19"},
- {42, "R_SPARC_GLOB_JMP"},
- {43, "R_SPARC_7"},
- {44, "R_SPARC_5"},
- {45, "R_SPARC_6"},
- {46, "R_SPARC_DISP64"},
- {47, "R_SPARC_PLT64"},
- {48, "R_SPARC_HIX22"},
- {49, "R_SPARC_LOX10"},
- {50, "R_SPARC_H44"},
- {51, "R_SPARC_M44"},
- {52, "R_SPARC_L44"},
- {53, "R_SPARC_REGISTER"},
- {54, "R_SPARC_UA64"},
- {55, "R_SPARC_UA16"},
-}
-
-func (i R_SPARC) String() string { return stringName(uint32(i), rsparcStrings, false) }
-func (i R_SPARC) GoString() string { return stringName(uint32(i), rsparcStrings, true) }
-
-// Magic number for the elf trampoline, chosen wisely to be an immediate value.
-const ARM_MAGIC_TRAMP_NUMBER = 0x5c000003
-
-// ELF32 File header.
-type Header32 struct {
- Ident [EI_NIDENT]byte /* File identification. */
- Type uint16 /* File type. */
- Machine uint16 /* Machine architecture. */
- Version uint32 /* ELF format version. */
- Entry uint32 /* Entry point. */
- Phoff uint32 /* Program header file offset. */
- Shoff uint32 /* Section header file offset. */
- Flags uint32 /* Architecture-specific flags. */
- Ehsize uint16 /* Size of ELF header in bytes. */
- Phentsize uint16 /* Size of program header entry. */
- Phnum uint16 /* Number of program header entries. */
- Shentsize uint16 /* Size of section header entry. */
- Shnum uint16 /* Number of section header entries. */
- Shstrndx uint16 /* Section name strings section. */
-}
-
-// ELF32 Section header.
-type Section32 struct {
- Name uint32 /* Section name (index into the section header string table). */
- Type uint32 /* Section type. */
- Flags uint32 /* Section flags. */
- Addr uint32 /* Address in memory image. */
- Off uint32 /* Offset in file. */
- Size uint32 /* Size in bytes. */
- Link uint32 /* Index of a related section. */
- Info uint32 /* Depends on section type. */
- Addralign uint32 /* Alignment in bytes. */
- Entsize uint32 /* Size of each entry in section. */
-}
-
-// ELF32 Program header.
-type Prog32 struct {
- Type uint32 /* Entry type. */
- Off uint32 /* File offset of contents. */
- Vaddr uint32 /* Virtual address in memory image. */
- Paddr uint32 /* Physical address (not used). */
- Filesz uint32 /* Size of contents in file. */
- Memsz uint32 /* Size of contents in memory. */
- Flags uint32 /* Access permission flags. */
- Align uint32 /* Alignment in memory and file. */
-}
-
-// ELF32 Dynamic structure. The ".dynamic" section contains an array of them.
-type Dyn32 struct {
- Tag int32 /* Entry type. */
- Val uint32 /* Integer/Address value. */
-}
-
-/*
- * Relocation entries.
- */
-
-// ELF32 Relocations that don't need an addend field.
-type Rel32 struct {
- Off uint32 /* Location to be relocated. */
- Info uint32 /* Relocation type and symbol index. */
-}
-
-// ELF32 Relocations that need an addend field.
-type Rela32 struct {
- Off uint32 /* Location to be relocated. */
- Info uint32 /* Relocation type and symbol index. */
- Addend int32 /* Addend. */
-}
-
-func R_SYM32(info uint32) uint32 { return uint32(info >> 8) }
-func R_TYPE32(info uint32) uint32 { return uint32(info & 0xff) }
-func R_INFO32(sym, typ uint32) uint32 { return sym<<8 | typ }
-
-// ELF32 Symbol.
-type Sym32 struct {
- Name uint32
- Value uint32
- Size uint32
- Info uint8
- Other uint8
- Shndx uint16
-}
-
-const Sym32Size = 16
-
-func ST_BIND(info uint8) SymBind { return SymBind(info >> 4) }
-func ST_TYPE(info uint8) SymType { return SymType(info & 0xF) }
-func ST_INFO(bind SymBind, typ SymType) uint8 {
- return uint8(bind)<<4 | uint8(typ)&0xf
-}
-func ST_VISIBILITY(other uint8) SymVis { return SymVis(other & 3) }
-
-/*
- * ELF64
- */
-
-// ELF64 file header.
-type Header64 struct {
- Ident [EI_NIDENT]byte /* File identification. */
- Type uint16 /* File type. */
- Machine uint16 /* Machine architecture. */
- Version uint32 /* ELF format version. */
- Entry uint64 /* Entry point. */
- Phoff uint64 /* Program header file offset. */
- Shoff uint64 /* Section header file offset. */
- Flags uint32 /* Architecture-specific flags. */
- Ehsize uint16 /* Size of ELF header in bytes. */
- Phentsize uint16 /* Size of program header entry. */
- Phnum uint16 /* Number of program header entries. */
- Shentsize uint16 /* Size of section header entry. */
- Shnum uint16 /* Number of section header entries. */
- Shstrndx uint16 /* Section name strings section. */
-}
-
-// ELF64 Section header.
-type Section64 struct {
- Name uint32 /* Section name (index into the section header string table). */
- Type uint32 /* Section type. */
- Flags uint64 /* Section flags. */
- Addr uint64 /* Address in memory image. */
- Off uint64 /* Offset in file. */
- Size uint64 /* Size in bytes. */
- Link uint32 /* Index of a related section. */
- Info uint32 /* Depends on section type. */
- Addralign uint64 /* Alignment in bytes. */
- Entsize uint64 /* Size of each entry in section. */
-}
-
-// ELF64 Program header.
-type Prog64 struct {
- Type uint32 /* Entry type. */
- Flags uint32 /* Access permission flags. */
- Off uint64 /* File offset of contents. */
- Vaddr uint64 /* Virtual address in memory image. */
- Paddr uint64 /* Physical address (not used). */
- Filesz uint64 /* Size of contents in file. */
- Memsz uint64 /* Size of contents in memory. */
- Align uint64 /* Alignment in memory and file. */
-}
-
-// ELF64 Dynamic structure. The ".dynamic" section contains an array of them.
-type Dyn64 struct {
- Tag int64 /* Entry type. */
- Val uint64 /* Integer/address value */
-}
-
-/*
- * Relocation entries.
- */
-
-/* ELF64 relocations that don't need an addend field. */
-type Rel64 struct {
- Off uint64 /* Location to be relocated. */
- Info uint64 /* Relocation type and symbol index. */
-}
-
-/* ELF64 relocations that need an addend field. */
-type Rela64 struct {
- Off uint64 /* Location to be relocated. */
- Info uint64 /* Relocation type and symbol index. */
- Addend int64 /* Addend. */
-}
-
-func R_SYM64(info uint64) uint32 { return uint32(info >> 32) }
-func R_TYPE64(info uint64) uint32 { return uint32(info) }
-func R_INFO(sym, typ uint32) uint64 { return uint64(sym)<<32 | uint64(typ) }
-
-// ELF64 symbol table entries.
-type Sym64 struct {
- Name uint32 /* String table index of name. */
- Info uint8 /* Type and binding information. */
- Other uint8 /* Reserved (not used). */
- Shndx uint16 /* Section index of symbol. */
- Value uint64 /* Symbol value. */
- Size uint64 /* Size of associated object. */
-}
-
-const Sym64Size = 24
-
-type intName struct {
- i uint32
- s string
-}
-
-func stringName(i uint32, names []intName, goSyntax bool) string {
- for _, n := range names {
- if n.i == i {
- if goSyntax {
- return "elf." + n.s
- }
- return n.s
- }
- }
-
- // second pass - look for smaller to add with.
- // assume sorted already
- for j := len(names) - 1; j >= 0; j-- {
- n := names[j]
- if n.i < i {
- s := n.s
- if goSyntax {
- s = "elf." + s
- }
- return s + "+" + strconv.FormatUint(uint64(i-n.i), 10)
- }
- }
-
- return strconv.FormatUint(uint64(i), 10)
-}
-
-func flagName(i uint32, names []intName, goSyntax bool) string {
- s := ""
- for _, n := range names {
- if n.i&i == n.i {
- if len(s) > 0 {
- s += "+"
- }
- if goSyntax {
- s += "elf."
- }
- s += n.s
- i -= n.i
- }
- }
- if len(s) == 0 {
- return "0x" + strconv.FormatUint(uint64(i), 16)
- }
- if i != 0 {
- s += "+0x" + strconv.FormatUint(uint64(i), 16)
- }
- return s
-}
diff --git a/src/pkg/debug/elf/elf_test.go b/src/pkg/debug/elf/elf_test.go
deleted file mode 100644
index e3c51bb71..000000000
--- a/src/pkg/debug/elf/elf_test.go
+++ /dev/null
@@ -1,49 +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 elf
-
-import (
- "fmt"
- "testing"
-)
-
-type nameTest struct {
- val interface{}
- str string
-}
-
-var nameTests = []nameTest{
- {ELFOSABI_LINUX, "ELFOSABI_LINUX"},
- {ET_EXEC, "ET_EXEC"},
- {EM_860, "EM_860"},
- {SHN_LOPROC, "SHN_LOPROC"},
- {SHT_PROGBITS, "SHT_PROGBITS"},
- {SHF_MERGE + SHF_TLS, "SHF_MERGE+SHF_TLS"},
- {PT_LOAD, "PT_LOAD"},
- {PF_W + PF_R + 0x50, "PF_W+PF_R+0x50"},
- {DT_SYMBOLIC, "DT_SYMBOLIC"},
- {DF_BIND_NOW, "DF_BIND_NOW"},
- {NT_FPREGSET, "NT_FPREGSET"},
- {STB_GLOBAL, "STB_GLOBAL"},
- {STT_COMMON, "STT_COMMON"},
- {STV_HIDDEN, "STV_HIDDEN"},
- {R_X86_64_PC32, "R_X86_64_PC32"},
- {R_ALPHA_OP_PUSH, "R_ALPHA_OP_PUSH"},
- {R_ARM_THM_ABS5, "R_ARM_THM_ABS5"},
- {R_386_GOT32, "R_386_GOT32"},
- {R_PPC_GOT16_HI, "R_PPC_GOT16_HI"},
- {R_SPARC_GOT22, "R_SPARC_GOT22"},
- {ET_LOOS + 5, "ET_LOOS+5"},
- {ProgFlag(0x50), "0x50"},
-}
-
-func TestNames(t *testing.T) {
- for i, tt := range nameTests {
- s := fmt.Sprint(tt.val)
- if s != tt.str {
- t.Errorf("#%d: Sprint(%d) = %q, want %q", i, tt.val, s, tt.str)
- }
- }
-}
diff --git a/src/pkg/debug/elf/file.go b/src/pkg/debug/elf/file.go
deleted file mode 100644
index 423932fe0..000000000
--- a/src/pkg/debug/elf/file.go
+++ /dev/null
@@ -1,881 +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 elf implements access to ELF object files.
-package elf
-
-import (
- "bytes"
- "debug/dwarf"
- "encoding/binary"
- "errors"
- "fmt"
- "io"
- "os"
-)
-
-// TODO: error reporting detail
-
-/*
- * Internal ELF representation
- */
-
-// A FileHeader represents an ELF file header.
-type FileHeader struct {
- Class Class
- Data Data
- Version Version
- OSABI OSABI
- ABIVersion uint8
- ByteOrder binary.ByteOrder
- Type Type
- Machine Machine
- Entry uint64
-}
-
-// A File represents an open ELF file.
-type File struct {
- FileHeader
- Sections []*Section
- Progs []*Prog
- closer io.Closer
- gnuNeed []verneed
- gnuVersym []byte
-}
-
-// A SectionHeader represents a single ELF section header.
-type SectionHeader struct {
- Name string
- Type SectionType
- Flags SectionFlag
- Addr uint64
- Offset uint64
- Size uint64
- Link uint32
- Info uint32
- Addralign uint64
- Entsize uint64
-}
-
-// A Section represents a single section in an ELF file.
-type Section struct {
- SectionHeader
-
- // Embed ReaderAt for ReadAt method.
- // Do not embed SectionReader directly
- // to avoid having Read and Seek.
- // If a client wants Read and Seek it must use
- // Open() to avoid fighting over the seek offset
- // with other clients.
- io.ReaderAt
- sr *io.SectionReader
-}
-
-// Data reads and returns the contents of the ELF section.
-func (s *Section) Data() ([]byte, error) {
- dat := make([]byte, s.sr.Size())
- n, err := s.sr.ReadAt(dat, 0)
- if n == len(dat) {
- err = nil
- }
- return dat[0:n], err
-}
-
-// stringTable reads and returns the string table given by the
-// specified link value.
-func (f *File) stringTable(link uint32) ([]byte, error) {
- if link <= 0 || link >= uint32(len(f.Sections)) {
- return nil, errors.New("section has invalid string table link")
- }
- return f.Sections[link].Data()
-}
-
-// Open returns a new ReadSeeker reading the ELF section.
-func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
-
-// A ProgHeader represents a single ELF program header.
-type ProgHeader struct {
- Type ProgType
- Flags ProgFlag
- Off uint64
- Vaddr uint64
- Paddr uint64
- Filesz uint64
- Memsz uint64
- Align uint64
-}
-
-// A Prog represents a single ELF program header in an ELF binary.
-type Prog struct {
- ProgHeader
-
- // Embed ReaderAt for ReadAt method.
- // Do not embed SectionReader directly
- // to avoid having Read and Seek.
- // If a client wants Read and Seek it must use
- // Open() to avoid fighting over the seek offset
- // with other clients.
- io.ReaderAt
- sr *io.SectionReader
-}
-
-// Open returns a new ReadSeeker reading the ELF program body.
-func (p *Prog) Open() io.ReadSeeker { return io.NewSectionReader(p.sr, 0, 1<<63-1) }
-
-// A Symbol represents an entry in an ELF symbol table section.
-type Symbol struct {
- Name string
- Info, Other byte
- Section SectionIndex
- Value, Size uint64
-}
-
-/*
- * ELF reader
- */
-
-type FormatError struct {
- off int64
- msg string
- val interface{}
-}
-
-func (e *FormatError) Error() string {
- msg := e.msg
- if e.val != nil {
- msg += fmt.Sprintf(" '%v' ", e.val)
- }
- msg += fmt.Sprintf("in record at byte %#x", e.off)
- return msg
-}
-
-// Open opens the named file using os.Open and prepares it for use as an ELF binary.
-func Open(name string) (*File, error) {
- f, err := os.Open(name)
- if err != nil {
- return nil, err
- }
- ff, err := NewFile(f)
- if err != nil {
- f.Close()
- return nil, err
- }
- ff.closer = f
- return ff, nil
-}
-
-// Close closes the File.
-// If the File was created using NewFile directly instead of Open,
-// Close has no effect.
-func (f *File) Close() error {
- var err error
- if f.closer != nil {
- err = f.closer.Close()
- f.closer = nil
- }
- return err
-}
-
-// SectionByType returns the first section in f with the
-// given type, or nil if there is no such section.
-func (f *File) SectionByType(typ SectionType) *Section {
- for _, s := range f.Sections {
- if s.Type == typ {
- return s
- }
- }
- return nil
-}
-
-// NewFile creates a new File for accessing an ELF binary in an underlying reader.
-// The ELF binary is expected to start at position 0 in the ReaderAt.
-func NewFile(r io.ReaderAt) (*File, error) {
- sr := io.NewSectionReader(r, 0, 1<<63-1)
- // Read and decode ELF identifier
- var ident [16]uint8
- if _, err := r.ReadAt(ident[0:], 0); err != nil {
- return nil, err
- }
- if ident[0] != '\x7f' || ident[1] != 'E' || ident[2] != 'L' || ident[3] != 'F' {
- return nil, &FormatError{0, "bad magic number", ident[0:4]}
- }
-
- f := new(File)
- f.Class = Class(ident[EI_CLASS])
- switch f.Class {
- case ELFCLASS32:
- case ELFCLASS64:
- // ok
- default:
- return nil, &FormatError{0, "unknown ELF class", f.Class}
- }
-
- f.Data = Data(ident[EI_DATA])
- switch f.Data {
- case ELFDATA2LSB:
- f.ByteOrder = binary.LittleEndian
- case ELFDATA2MSB:
- f.ByteOrder = binary.BigEndian
- default:
- return nil, &FormatError{0, "unknown ELF data encoding", f.Data}
- }
-
- f.Version = Version(ident[EI_VERSION])
- if f.Version != EV_CURRENT {
- return nil, &FormatError{0, "unknown ELF version", f.Version}
- }
-
- f.OSABI = OSABI(ident[EI_OSABI])
- f.ABIVersion = ident[EI_ABIVERSION]
-
- // Read ELF file header
- var phoff int64
- var phentsize, phnum int
- var shoff int64
- var shentsize, shnum, shstrndx int
- shstrndx = -1
- switch f.Class {
- case ELFCLASS32:
- hdr := new(Header32)
- sr.Seek(0, os.SEEK_SET)
- if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
- return nil, err
- }
- f.Type = Type(hdr.Type)
- f.Machine = Machine(hdr.Machine)
- f.Entry = uint64(hdr.Entry)
- if v := Version(hdr.Version); v != f.Version {
- return nil, &FormatError{0, "mismatched ELF version", v}
- }
- phoff = int64(hdr.Phoff)
- phentsize = int(hdr.Phentsize)
- phnum = int(hdr.Phnum)
- shoff = int64(hdr.Shoff)
- shentsize = int(hdr.Shentsize)
- shnum = int(hdr.Shnum)
- shstrndx = int(hdr.Shstrndx)
- case ELFCLASS64:
- hdr := new(Header64)
- sr.Seek(0, os.SEEK_SET)
- if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
- return nil, err
- }
- f.Type = Type(hdr.Type)
- f.Machine = Machine(hdr.Machine)
- f.Entry = uint64(hdr.Entry)
- if v := Version(hdr.Version); v != f.Version {
- return nil, &FormatError{0, "mismatched ELF version", v}
- }
- phoff = int64(hdr.Phoff)
- phentsize = int(hdr.Phentsize)
- phnum = int(hdr.Phnum)
- shoff = int64(hdr.Shoff)
- shentsize = int(hdr.Shentsize)
- shnum = int(hdr.Shnum)
- shstrndx = int(hdr.Shstrndx)
- }
-
- if shnum > 0 && shoff > 0 && (shstrndx < 0 || shstrndx >= shnum) {
- return nil, &FormatError{0, "invalid ELF shstrndx", shstrndx}
- }
-
- // Read program headers
- f.Progs = make([]*Prog, phnum)
- for i := 0; i < phnum; i++ {
- off := phoff + int64(i)*int64(phentsize)
- sr.Seek(off, os.SEEK_SET)
- p := new(Prog)
- switch f.Class {
- case ELFCLASS32:
- ph := new(Prog32)
- if err := binary.Read(sr, f.ByteOrder, ph); err != nil {
- return nil, err
- }
- p.ProgHeader = ProgHeader{
- Type: ProgType(ph.Type),
- Flags: ProgFlag(ph.Flags),
- Off: uint64(ph.Off),
- Vaddr: uint64(ph.Vaddr),
- Paddr: uint64(ph.Paddr),
- Filesz: uint64(ph.Filesz),
- Memsz: uint64(ph.Memsz),
- Align: uint64(ph.Align),
- }
- case ELFCLASS64:
- ph := new(Prog64)
- if err := binary.Read(sr, f.ByteOrder, ph); err != nil {
- return nil, err
- }
- p.ProgHeader = ProgHeader{
- Type: ProgType(ph.Type),
- Flags: ProgFlag(ph.Flags),
- Off: uint64(ph.Off),
- Vaddr: uint64(ph.Vaddr),
- Paddr: uint64(ph.Paddr),
- Filesz: uint64(ph.Filesz),
- Memsz: uint64(ph.Memsz),
- Align: uint64(ph.Align),
- }
- }
- p.sr = io.NewSectionReader(r, int64(p.Off), int64(p.Filesz))
- p.ReaderAt = p.sr
- f.Progs[i] = p
- }
-
- // Read section headers
- f.Sections = make([]*Section, shnum)
- names := make([]uint32, shnum)
- for i := 0; i < shnum; i++ {
- off := shoff + int64(i)*int64(shentsize)
- sr.Seek(off, os.SEEK_SET)
- s := new(Section)
- switch f.Class {
- case ELFCLASS32:
- sh := new(Section32)
- if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
- return nil, err
- }
- names[i] = sh.Name
- s.SectionHeader = SectionHeader{
- Type: SectionType(sh.Type),
- Flags: SectionFlag(sh.Flags),
- Addr: uint64(sh.Addr),
- Offset: uint64(sh.Off),
- Size: uint64(sh.Size),
- Link: uint32(sh.Link),
- Info: uint32(sh.Info),
- Addralign: uint64(sh.Addralign),
- Entsize: uint64(sh.Entsize),
- }
- case ELFCLASS64:
- sh := new(Section64)
- if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
- return nil, err
- }
- names[i] = sh.Name
- s.SectionHeader = SectionHeader{
- Type: SectionType(sh.Type),
- Flags: SectionFlag(sh.Flags),
- Offset: uint64(sh.Off),
- Size: uint64(sh.Size),
- Addr: uint64(sh.Addr),
- Link: uint32(sh.Link),
- Info: uint32(sh.Info),
- Addralign: uint64(sh.Addralign),
- Entsize: uint64(sh.Entsize),
- }
- }
- s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.Size))
- s.ReaderAt = s.sr
- f.Sections[i] = s
- }
-
- if len(f.Sections) == 0 {
- return f, nil
- }
-
- // Load section header string table.
- shstrtab, err := f.Sections[shstrndx].Data()
- if err != nil {
- return nil, err
- }
- for i, s := range f.Sections {
- var ok bool
- s.Name, ok = getString(shstrtab, int(names[i]))
- if !ok {
- return nil, &FormatError{shoff + int64(i*shentsize), "bad section name index", names[i]}
- }
- }
-
- return f, nil
-}
-
-// getSymbols returns a slice of Symbols from parsing the symbol table
-// with the given type, along with the associated string table.
-func (f *File) getSymbols(typ SectionType) ([]Symbol, []byte, error) {
- switch f.Class {
- case ELFCLASS64:
- return f.getSymbols64(typ)
-
- case ELFCLASS32:
- return f.getSymbols32(typ)
- }
-
- return nil, nil, errors.New("not implemented")
-}
-
-func (f *File) getSymbols32(typ SectionType) ([]Symbol, []byte, error) {
- symtabSection := f.SectionByType(typ)
- if symtabSection == nil {
- return nil, nil, errors.New("no symbol section")
- }
-
- data, err := symtabSection.Data()
- if err != nil {
- return nil, nil, errors.New("cannot load symbol section")
- }
- symtab := bytes.NewReader(data)
- if symtab.Len()%Sym32Size != 0 {
- return nil, nil, errors.New("length of symbol section is not a multiple of SymSize")
- }
-
- strdata, err := f.stringTable(symtabSection.Link)
- if err != nil {
- return nil, nil, errors.New("cannot load string table section")
- }
-
- // The first entry is all zeros.
- var skip [Sym32Size]byte
- symtab.Read(skip[:])
-
- symbols := make([]Symbol, symtab.Len()/Sym32Size)
-
- i := 0
- var sym Sym32
- for symtab.Len() > 0 {
- binary.Read(symtab, f.ByteOrder, &sym)
- str, _ := getString(strdata, int(sym.Name))
- symbols[i].Name = str
- symbols[i].Info = sym.Info
- symbols[i].Other = sym.Other
- symbols[i].Section = SectionIndex(sym.Shndx)
- symbols[i].Value = uint64(sym.Value)
- symbols[i].Size = uint64(sym.Size)
- i++
- }
-
- return symbols, strdata, nil
-}
-
-func (f *File) getSymbols64(typ SectionType) ([]Symbol, []byte, error) {
- symtabSection := f.SectionByType(typ)
- if symtabSection == nil {
- return nil, nil, errors.New("no symbol section")
- }
-
- data, err := symtabSection.Data()
- if err != nil {
- return nil, nil, errors.New("cannot load symbol section")
- }
- symtab := bytes.NewReader(data)
- if symtab.Len()%Sym64Size != 0 {
- return nil, nil, errors.New("length of symbol section is not a multiple of Sym64Size")
- }
-
- strdata, err := f.stringTable(symtabSection.Link)
- if err != nil {
- return nil, nil, errors.New("cannot load string table section")
- }
-
- // The first entry is all zeros.
- var skip [Sym64Size]byte
- symtab.Read(skip[:])
-
- symbols := make([]Symbol, symtab.Len()/Sym64Size)
-
- i := 0
- var sym Sym64
- for symtab.Len() > 0 {
- binary.Read(symtab, f.ByteOrder, &sym)
- str, _ := getString(strdata, int(sym.Name))
- symbols[i].Name = str
- symbols[i].Info = sym.Info
- symbols[i].Other = sym.Other
- symbols[i].Section = SectionIndex(sym.Shndx)
- symbols[i].Value = sym.Value
- symbols[i].Size = sym.Size
- i++
- }
-
- return symbols, strdata, nil
-}
-
-// getString extracts a string from an ELF string table.
-func getString(section []byte, start int) (string, bool) {
- if start < 0 || start >= len(section) {
- return "", false
- }
-
- for end := start; end < len(section); end++ {
- if section[end] == 0 {
- return string(section[start:end]), true
- }
- }
- return "", false
-}
-
-// Section returns a section with the given name, or nil if no such
-// section exists.
-func (f *File) Section(name string) *Section {
- for _, s := range f.Sections {
- if s.Name == name {
- return s
- }
- }
- return nil
-}
-
-// applyRelocations applies relocations to dst. rels is a relocations section
-// in RELA format.
-func (f *File) applyRelocations(dst []byte, rels []byte) error {
- if f.Class == ELFCLASS64 && f.Machine == EM_X86_64 {
- return f.applyRelocationsAMD64(dst, rels)
- }
- if f.Class == ELFCLASS32 && f.Machine == EM_386 {
- return f.applyRelocations386(dst, rels)
- }
-
- return errors.New("not implemented")
-}
-
-func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
- // 24 is the size of Rela64.
- if len(rels)%24 != 0 {
- return errors.New("length of relocation section is not a multiple of 24")
- }
-
- symbols, _, err := f.getSymbols(SHT_SYMTAB)
- if err != nil {
- return err
- }
-
- b := bytes.NewReader(rels)
- var rela Rela64
-
- for b.Len() > 0 {
- binary.Read(b, f.ByteOrder, &rela)
- symNo := rela.Info >> 32
- t := R_X86_64(rela.Info & 0xffff)
-
- if symNo == 0 || symNo > uint64(len(symbols)) {
- continue
- }
- sym := &symbols[symNo-1]
- if SymType(sym.Info&0xf) != STT_SECTION {
- // We don't handle non-section relocations for now.
- continue
- }
-
- switch t {
- case R_X86_64_64:
- if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
- continue
- }
- f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend))
- case R_X86_64_32:
- if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
- continue
- }
- f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
- }
- }
-
- return nil
-}
-
-func (f *File) applyRelocations386(dst []byte, rels []byte) error {
- // 8 is the size of Rel32.
- if len(rels)%8 != 0 {
- return errors.New("length of relocation section is not a multiple of 8")
- }
-
- symbols, _, err := f.getSymbols(SHT_SYMTAB)
- if err != nil {
- return err
- }
-
- b := bytes.NewReader(rels)
- var rel Rel32
-
- for b.Len() > 0 {
- binary.Read(b, f.ByteOrder, &rel)
- symNo := rel.Info >> 8
- t := R_386(rel.Info & 0xff)
-
- if symNo == 0 || symNo > uint32(len(symbols)) {
- continue
- }
- sym := &symbols[symNo-1]
-
- if t == R_386_32 {
- if rel.Off+4 >= uint32(len(dst)) {
- continue
- }
- val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
- val += uint32(sym.Value)
- f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val)
- }
- }
-
- return nil
-}
-
-func (f *File) DWARF() (*dwarf.Data, error) {
- // There are many other DWARF sections, but these
- // are the required ones, and the debug/dwarf package
- // does not use the others, so don't bother loading them.
- var names = [...]string{"abbrev", "info", "str"}
- var dat [len(names)][]byte
- for i, name := range names {
- name = ".debug_" + name
- s := f.Section(name)
- if s == nil {
- continue
- }
- b, err := s.Data()
- if err != nil && uint64(len(b)) < s.Size {
- return nil, err
- }
- dat[i] = b
- }
-
- // If there's a relocation table for .debug_info, we have to process it
- // now otherwise the data in .debug_info is invalid for x86-64 objects.
- rela := f.Section(".rela.debug_info")
- if rela != nil && rela.Type == SHT_RELA && f.Machine == EM_X86_64 {
- data, err := rela.Data()
- if err != nil {
- return nil, err
- }
- err = f.applyRelocations(dat[1], data)
- if err != nil {
- return nil, err
- }
- }
-
- // When using clang we need to process relocations even for 386.
- rel := f.Section(".rel.debug_info")
- if rel != nil && rel.Type == SHT_REL && f.Machine == EM_386 {
- data, err := rel.Data()
- if err != nil {
- return nil, err
- }
- err = f.applyRelocations(dat[1], data)
- if err != nil {
- return nil, err
- }
- }
-
- abbrev, info, str := dat[0], dat[1], dat[2]
- d, err := dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str)
- if err != nil {
- return nil, err
- }
-
- // Look for DWARF4 .debug_types sections.
- for i, s := range f.Sections {
- if s.Name == ".debug_types" {
- b, err := s.Data()
- if err != nil && uint64(len(b)) < s.Size {
- return nil, err
- }
-
- for _, r := range f.Sections {
- if r.Type != SHT_RELA && r.Type != SHT_REL {
- continue
- }
- if int(r.Info) != i {
- continue
- }
- rd, err := r.Data()
- if err != nil {
- return nil, err
- }
- err = f.applyRelocations(b, rd)
- if err != nil {
- return nil, err
- }
- }
-
- err = d.AddTypes(fmt.Sprintf("types-%d", i), b)
- if err != nil {
- return nil, err
- }
- }
- }
-
- return d, nil
-}
-
-// Symbols returns the symbol table for f.
-//
-// For compatibility with Go 1.0, Symbols omits the null symbol at index 0.
-// After retrieving the symbols as symtab, an externally supplied index x
-// corresponds to symtab[x-1], not symtab[x].
-func (f *File) Symbols() ([]Symbol, error) {
- sym, _, err := f.getSymbols(SHT_SYMTAB)
- return sym, err
-}
-
-type ImportedSymbol struct {
- Name string
- Version string
- Library string
-}
-
-// ImportedSymbols returns the names of all symbols
-// referred to by the binary f that are expected to be
-// satisfied by other libraries at dynamic load time.
-// It does not return weak symbols.
-func (f *File) ImportedSymbols() ([]ImportedSymbol, error) {
- sym, str, err := f.getSymbols(SHT_DYNSYM)
- if err != nil {
- return nil, err
- }
- f.gnuVersionInit(str)
- var all []ImportedSymbol
- for i, s := range sym {
- if ST_BIND(s.Info) == STB_GLOBAL && s.Section == SHN_UNDEF {
- all = append(all, ImportedSymbol{Name: s.Name})
- f.gnuVersion(i, &all[len(all)-1])
- }
- }
- return all, nil
-}
-
-type verneed struct {
- File string
- Name string
-}
-
-// gnuVersionInit parses the GNU version tables
-// for use by calls to gnuVersion.
-func (f *File) gnuVersionInit(str []byte) {
- // Accumulate verneed information.
- vn := f.SectionByType(SHT_GNU_VERNEED)
- if vn == nil {
- return
- }
- d, _ := vn.Data()
-
- var need []verneed
- i := 0
- for {
- if i+16 > len(d) {
- break
- }
- vers := f.ByteOrder.Uint16(d[i : i+2])
- if vers != 1 {
- break
- }
- cnt := f.ByteOrder.Uint16(d[i+2 : i+4])
- fileoff := f.ByteOrder.Uint32(d[i+4 : i+8])
- aux := f.ByteOrder.Uint32(d[i+8 : i+12])
- next := f.ByteOrder.Uint32(d[i+12 : i+16])
- file, _ := getString(str, int(fileoff))
-
- var name string
- j := i + int(aux)
- for c := 0; c < int(cnt); c++ {
- if j+16 > len(d) {
- break
- }
- // hash := f.ByteOrder.Uint32(d[j:j+4])
- // flags := f.ByteOrder.Uint16(d[j+4:j+6])
- other := f.ByteOrder.Uint16(d[j+6 : j+8])
- nameoff := f.ByteOrder.Uint32(d[j+8 : j+12])
- next := f.ByteOrder.Uint32(d[j+12 : j+16])
- name, _ = getString(str, int(nameoff))
- ndx := int(other)
- if ndx >= len(need) {
- a := make([]verneed, 2*(ndx+1))
- copy(a, need)
- need = a
- }
-
- need[ndx] = verneed{file, name}
- if next == 0 {
- break
- }
- j += int(next)
- }
-
- if next == 0 {
- break
- }
- i += int(next)
- }
-
- // Versym parallels symbol table, indexing into verneed.
- vs := f.SectionByType(SHT_GNU_VERSYM)
- if vs == nil {
- return
- }
- d, _ = vs.Data()
-
- f.gnuNeed = need
- f.gnuVersym = d
-}
-
-// gnuVersion adds Library and Version information to sym,
-// which came from offset i of the symbol table.
-func (f *File) gnuVersion(i int, sym *ImportedSymbol) {
- // Each entry is two bytes.
- i = (i + 1) * 2
- if i >= len(f.gnuVersym) {
- return
- }
- j := int(f.ByteOrder.Uint16(f.gnuVersym[i:]))
- if j < 2 || j >= len(f.gnuNeed) {
- return
- }
- n := &f.gnuNeed[j]
- sym.Library = n.File
- sym.Version = n.Name
-}
-
-// ImportedLibraries returns the names of all libraries
-// referred to by the binary f that are expected to be
-// linked with the binary at dynamic link time.
-func (f *File) ImportedLibraries() ([]string, error) {
- return f.DynString(DT_NEEDED)
-}
-
-// DynString returns the strings listed for the given tag in the file's dynamic
-// section.
-//
-// The tag must be one that takes string values: DT_NEEDED, DT_SONAME, DT_RPATH, or
-// DT_RUNPATH.
-func (f *File) DynString(tag DynTag) ([]string, error) {
- switch tag {
- case DT_NEEDED, DT_SONAME, DT_RPATH, DT_RUNPATH:
- default:
- return nil, fmt.Errorf("non-string-valued tag %v", tag)
- }
- ds := f.SectionByType(SHT_DYNAMIC)
- if ds == nil {
- // not dynamic, so no libraries
- return nil, nil
- }
- d, err := ds.Data()
- if err != nil {
- return nil, err
- }
- str, err := f.stringTable(ds.Link)
- if err != nil {
- return nil, err
- }
- var all []string
- for len(d) > 0 {
- var t DynTag
- var v uint64
- switch f.Class {
- case ELFCLASS32:
- t = DynTag(f.ByteOrder.Uint32(d[0:4]))
- v = uint64(f.ByteOrder.Uint32(d[4:8]))
- d = d[8:]
- case ELFCLASS64:
- t = DynTag(f.ByteOrder.Uint64(d[0:8]))
- v = f.ByteOrder.Uint64(d[8:16])
- d = d[16:]
- }
- if t == tag {
- s, ok := getString(str, int(v))
- if ok {
- all = append(all, s)
- }
- }
- }
- return all, nil
-}
diff --git a/src/pkg/debug/elf/file_test.go b/src/pkg/debug/elf/file_test.go
deleted file mode 100644
index 7f88a54bc..000000000
--- a/src/pkg/debug/elf/file_test.go
+++ /dev/null
@@ -1,339 +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 elf
-
-import (
- "bytes"
- "compress/gzip"
- "debug/dwarf"
- "encoding/binary"
- "io"
- "net"
- "os"
- "path"
- "reflect"
- "runtime"
- "testing"
-)
-
-type fileTest struct {
- file string
- hdr FileHeader
- sections []SectionHeader
- progs []ProgHeader
- needed []string
-}
-
-var fileTests = []fileTest{
- {
- "testdata/gcc-386-freebsd-exec",
- FileHeader{ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_FREEBSD, 0, binary.LittleEndian, ET_EXEC, EM_386, 0x80483cc},
- []SectionHeader{
- {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
- {".interp", SHT_PROGBITS, SHF_ALLOC, 0x80480d4, 0xd4, 0x15, 0x0, 0x0, 0x1, 0x0},
- {".hash", SHT_HASH, SHF_ALLOC, 0x80480ec, 0xec, 0x90, 0x3, 0x0, 0x4, 0x4},
- {".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x804817c, 0x17c, 0x110, 0x4, 0x1, 0x4, 0x10},
- {".dynstr", SHT_STRTAB, SHF_ALLOC, 0x804828c, 0x28c, 0xbb, 0x0, 0x0, 0x1, 0x0},
- {".rel.plt", SHT_REL, SHF_ALLOC, 0x8048348, 0x348, 0x20, 0x3, 0x7, 0x4, 0x8},
- {".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x8048368, 0x368, 0x11, 0x0, 0x0, 0x4, 0x0},
- {".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804837c, 0x37c, 0x50, 0x0, 0x0, 0x4, 0x4},
- {".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x80483cc, 0x3cc, 0x180, 0x0, 0x0, 0x4, 0x0},
- {".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804854c, 0x54c, 0xc, 0x0, 0x0, 0x4, 0x0},
- {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x8048558, 0x558, 0xa3, 0x0, 0x0, 0x1, 0x0},
- {".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80495fc, 0x5fc, 0xc, 0x0, 0x0, 0x4, 0x0},
- {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x8049608, 0x608, 0x4, 0x0, 0x0, 0x4, 0x0},
- {".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x804960c, 0x60c, 0x98, 0x4, 0x0, 0x4, 0x8},
- {".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496a4, 0x6a4, 0x8, 0x0, 0x0, 0x4, 0x0},
- {".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496ac, 0x6ac, 0x8, 0x0, 0x0, 0x4, 0x0},
- {".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b4, 0x6b4, 0x4, 0x0, 0x0, 0x4, 0x0},
- {".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b8, 0x6b8, 0x1c, 0x0, 0x0, 0x4, 0x4},
- {".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x80496d4, 0x6d4, 0x20, 0x0, 0x0, 0x4, 0x0},
- {".comment", SHT_PROGBITS, 0x0, 0x0, 0x6d4, 0x12d, 0x0, 0x0, 0x1, 0x0},
- {".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x801, 0x20, 0x0, 0x0, 0x1, 0x0},
- {".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0x821, 0x1b, 0x0, 0x0, 0x1, 0x0},
- {".debug_info", SHT_PROGBITS, 0x0, 0x0, 0x83c, 0x11d, 0x0, 0x0, 0x1, 0x0},
- {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0x959, 0x41, 0x0, 0x0, 0x1, 0x0},
- {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x99a, 0x35, 0x0, 0x0, 0x1, 0x0},
- {".debug_frame", SHT_PROGBITS, 0x0, 0x0, 0x9d0, 0x30, 0x0, 0x0, 0x4, 0x0},
- {".debug_str", SHT_PROGBITS, 0x0, 0x0, 0xa00, 0xd, 0x0, 0x0, 0x1, 0x0},
- {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xa0d, 0xf8, 0x0, 0x0, 0x1, 0x0},
- {".symtab", SHT_SYMTAB, 0x0, 0x0, 0xfb8, 0x4b0, 0x1d, 0x38, 0x4, 0x10},
- {".strtab", SHT_STRTAB, 0x0, 0x0, 0x1468, 0x206, 0x0, 0x0, 0x1, 0x0},
- },
- []ProgHeader{
- {PT_PHDR, PF_R + PF_X, 0x34, 0x8048034, 0x8048034, 0xa0, 0xa0, 0x4},
- {PT_INTERP, PF_R, 0xd4, 0x80480d4, 0x80480d4, 0x15, 0x15, 0x1},
- {PT_LOAD, PF_R + PF_X, 0x0, 0x8048000, 0x8048000, 0x5fb, 0x5fb, 0x1000},
- {PT_LOAD, PF_R + PF_W, 0x5fc, 0x80495fc, 0x80495fc, 0xd8, 0xf8, 0x1000},
- {PT_DYNAMIC, PF_R + PF_W, 0x60c, 0x804960c, 0x804960c, 0x98, 0x98, 0x4},
- },
- []string{"libc.so.6"},
- },
- {
- "testdata/gcc-amd64-linux-exec",
- FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0, binary.LittleEndian, ET_EXEC, EM_X86_64, 0x4003e0},
- []SectionHeader{
- {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
- {".interp", SHT_PROGBITS, SHF_ALLOC, 0x400200, 0x200, 0x1c, 0x0, 0x0, 0x1, 0x0},
- {".note.ABI-tag", SHT_NOTE, SHF_ALLOC, 0x40021c, 0x21c, 0x20, 0x0, 0x0, 0x4, 0x0},
- {".hash", SHT_HASH, SHF_ALLOC, 0x400240, 0x240, 0x24, 0x5, 0x0, 0x8, 0x4},
- {".gnu.hash", SHT_LOOS + 268435446, SHF_ALLOC, 0x400268, 0x268, 0x1c, 0x5, 0x0, 0x8, 0x0},
- {".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x400288, 0x288, 0x60, 0x6, 0x1, 0x8, 0x18},
- {".dynstr", SHT_STRTAB, SHF_ALLOC, 0x4002e8, 0x2e8, 0x3d, 0x0, 0x0, 0x1, 0x0},
- {".gnu.version", SHT_HIOS, SHF_ALLOC, 0x400326, 0x326, 0x8, 0x5, 0x0, 0x2, 0x2},
- {".gnu.version_r", SHT_LOOS + 268435454, SHF_ALLOC, 0x400330, 0x330, 0x20, 0x6, 0x1, 0x8, 0x0},
- {".rela.dyn", SHT_RELA, SHF_ALLOC, 0x400350, 0x350, 0x18, 0x5, 0x0, 0x8, 0x18},
- {".rela.plt", SHT_RELA, SHF_ALLOC, 0x400368, 0x368, 0x30, 0x5, 0xc, 0x8, 0x18},
- {".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400398, 0x398, 0x18, 0x0, 0x0, 0x4, 0x0},
- {".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003b0, 0x3b0, 0x30, 0x0, 0x0, 0x4, 0x10},
- {".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003e0, 0x3e0, 0x1b4, 0x0, 0x0, 0x10, 0x0},
- {".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400594, 0x594, 0xe, 0x0, 0x0, 0x4, 0x0},
- {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x4005a4, 0x5a4, 0x11, 0x0, 0x0, 0x4, 0x0},
- {".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC, 0x4005b8, 0x5b8, 0x24, 0x0, 0x0, 0x4, 0x0},
- {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x4005e0, 0x5e0, 0xa4, 0x0, 0x0, 0x8, 0x0},
- {".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600688, 0x688, 0x10, 0x0, 0x0, 0x8, 0x0},
- {".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600698, 0x698, 0x10, 0x0, 0x0, 0x8, 0x0},
- {".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x6006a8, 0x6a8, 0x8, 0x0, 0x0, 0x8, 0x0},
- {".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x6006b0, 0x6b0, 0x1a0, 0x6, 0x0, 0x8, 0x10},
- {".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600850, 0x850, 0x8, 0x0, 0x0, 0x8, 0x8},
- {".got.plt", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600858, 0x858, 0x28, 0x0, 0x0, 0x8, 0x8},
- {".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600880, 0x880, 0x18, 0x0, 0x0, 0x8, 0x0},
- {".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x600898, 0x898, 0x8, 0x0, 0x0, 0x4, 0x0},
- {".comment", SHT_PROGBITS, 0x0, 0x0, 0x898, 0x126, 0x0, 0x0, 0x1, 0x0},
- {".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x9c0, 0x90, 0x0, 0x0, 0x10, 0x0},
- {".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0xa50, 0x25, 0x0, 0x0, 0x1, 0x0},
- {".debug_info", SHT_PROGBITS, 0x0, 0x0, 0xa75, 0x1a7, 0x0, 0x0, 0x1, 0x0},
- {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xc1c, 0x6f, 0x0, 0x0, 0x1, 0x0},
- {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0xc8b, 0x13f, 0x0, 0x0, 0x1, 0x0},
- {".debug_str", SHT_PROGBITS, SHF_MERGE + SHF_STRINGS, 0x0, 0xdca, 0xb1, 0x0, 0x0, 0x1, 0x1},
- {".debug_ranges", SHT_PROGBITS, 0x0, 0x0, 0xe80, 0x90, 0x0, 0x0, 0x10, 0x0},
- {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xf10, 0x149, 0x0, 0x0, 0x1, 0x0},
- {".symtab", SHT_SYMTAB, 0x0, 0x0, 0x19a0, 0x6f0, 0x24, 0x39, 0x8, 0x18},
- {".strtab", SHT_STRTAB, 0x0, 0x0, 0x2090, 0x1fc, 0x0, 0x0, 0x1, 0x0},
- },
- []ProgHeader{
- {PT_PHDR, PF_R + PF_X, 0x40, 0x400040, 0x400040, 0x1c0, 0x1c0, 0x8},
- {PT_INTERP, PF_R, 0x200, 0x400200, 0x400200, 0x1c, 0x1c, 1},
- {PT_LOAD, PF_R + PF_X, 0x0, 0x400000, 0x400000, 0x684, 0x684, 0x200000},
- {PT_LOAD, PF_R + PF_W, 0x688, 0x600688, 0x600688, 0x210, 0x218, 0x200000},
- {PT_DYNAMIC, PF_R + PF_W, 0x6b0, 0x6006b0, 0x6006b0, 0x1a0, 0x1a0, 0x8},
- {PT_NOTE, PF_R, 0x21c, 0x40021c, 0x40021c, 0x20, 0x20, 0x4},
- {PT_LOOS + 0x474E550, PF_R, 0x5b8, 0x4005b8, 0x4005b8, 0x24, 0x24, 0x4},
- {PT_LOOS + 0x474E551, PF_R + PF_W, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8},
- },
- []string{"libc.so.6"},
- },
- {
- "testdata/hello-world-core.gz",
- FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_CORE, EM_X86_64, 0x0},
- []SectionHeader{},
- []ProgHeader{
- {Type: PT_NOTE, Flags: 0x0, Off: 0x3f8, Vaddr: 0x0, Paddr: 0x0, Filesz: 0x8ac, Memsz: 0x0, Align: 0x0},
- {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x1000, Vaddr: 0x400000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1000, Align: 0x1000},
- {Type: PT_LOAD, Flags: PF_R, Off: 0x1000, Vaddr: 0x401000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
- {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x2000, Vaddr: 0x402000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
- {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3000, Vaddr: 0x7f54078b8000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1b5000, Align: 0x1000},
- {Type: PT_LOAD, Flags: 0x0, Off: 0x3000, Vaddr: 0x7f5407a6d000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1ff000, Align: 0x1000},
- {Type: PT_LOAD, Flags: PF_R, Off: 0x3000, Vaddr: 0x7f5407c6c000, Paddr: 0x0, Filesz: 0x4000, Memsz: 0x4000, Align: 0x1000},
- {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x7000, Vaddr: 0x7f5407c70000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000},
- {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x9000, Vaddr: 0x7f5407c72000, Paddr: 0x0, Filesz: 0x5000, Memsz: 0x5000, Align: 0x1000},
- {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0xe000, Vaddr: 0x7f5407c77000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x22000, Align: 0x1000},
- {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0xe000, Vaddr: 0x7f5407e81000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000},
- {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x11000, Vaddr: 0x7f5407e96000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000},
- {Type: PT_LOAD, Flags: PF_R, Off: 0x14000, Vaddr: 0x7f5407e99000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
- {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x15000, Vaddr: 0x7f5407e9a000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000},
- {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x17000, Vaddr: 0x7fff79972000, Paddr: 0x0, Filesz: 0x23000, Memsz: 0x23000, Align: 0x1000},
- {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3a000, Vaddr: 0x7fff799f8000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
- {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3b000, Vaddr: 0xffffffffff600000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
- },
- nil,
- },
-}
-
-func TestOpen(t *testing.T) {
- for i := range fileTests {
- tt := &fileTests[i]
-
- var f *File
- var err error
- if path.Ext(tt.file) == ".gz" {
- var r io.ReaderAt
- if r, err = decompress(tt.file); err == nil {
- f, err = NewFile(r)
- }
- } else {
- f, err = Open(tt.file)
- }
- defer f.Close()
- if err != nil {
- t.Errorf("cannot open file %s: %v", tt.file, err)
- continue
- }
- if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
- t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)
- continue
- }
- for i, s := range f.Sections {
- if i >= len(tt.sections) {
- break
- }
- sh := &tt.sections[i]
- if !reflect.DeepEqual(&s.SectionHeader, sh) {
- t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, &s.SectionHeader, sh)
- }
- }
- for i, p := range f.Progs {
- if i >= len(tt.progs) {
- break
- }
- ph := &tt.progs[i]
- if !reflect.DeepEqual(&p.ProgHeader, ph) {
- t.Errorf("open %s, program %d:\n\thave %#v\n\twant %#v\n", tt.file, i, &p.ProgHeader, ph)
- }
- }
- tn := len(tt.sections)
- fn := len(f.Sections)
- if tn != fn {
- t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
- }
- tn = len(tt.progs)
- fn = len(f.Progs)
- if tn != fn {
- t.Errorf("open %s: len(Progs) = %d, want %d", tt.file, fn, tn)
- }
- tl := tt.needed
- fl, err := f.ImportedLibraries()
- if err != nil {
- t.Error(err)
- }
- if !reflect.DeepEqual(tl, fl) {
- t.Errorf("open %s: DT_NEEDED = %v, want %v", tt.file, tl, fl)
- }
- }
-}
-
-// elf.NewFile requires io.ReaderAt, which compress/gzip cannot
-// provide. Decompress the file to a bytes.Reader.
-func decompress(gz string) (io.ReaderAt, error) {
- in, err := os.Open(gz)
- if err != nil {
- return nil, err
- }
- defer in.Close()
- r, err := gzip.NewReader(in)
- if err != nil {
- return nil, err
- }
- var out bytes.Buffer
- _, err = io.Copy(&out, r)
- return bytes.NewReader(out.Bytes()), err
-}
-
-type relocationTestEntry struct {
- entryNumber int
- entry *dwarf.Entry
-}
-
-type relocationTest struct {
- file string
- entries []relocationTestEntry
-}
-
-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)}}}},
- },
- },
- {
- "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)}}}},
- },
- },
- {
- "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)}}}},
- },
- },
- {
- "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"}}}},
- },
- },
- {
- "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}}}}},
- },
- },
-}
-
-func TestDWARFRelocations(t *testing.T) {
- for i, test := range relocationTests {
- f, err := Open(test.file)
- if err != nil {
- t.Error(err)
- continue
- }
- dwarf, err := f.DWARF()
- if err != nil {
- t.Error(err)
- continue
- }
- for _, testEntry := range test.entries {
- reader := dwarf.Reader()
- for j := 0; j < testEntry.entryNumber; j++ {
- entry, err := reader.Next()
- if entry == nil || err != nil {
- t.Errorf("Failed to skip to entry %d: %v", testEntry.entryNumber, err)
- continue
- }
- }
- entry, err := reader.Next()
- if err != nil {
- t.Error(err)
- continue
- }
- if !reflect.DeepEqual(testEntry.entry, entry) {
- t.Errorf("#%d/%d: mismatch: got:%#v want:%#v", i, testEntry.entryNumber, entry, testEntry.entry)
- continue
- }
- }
- }
-}
-
-func TestNoSectionOverlaps(t *testing.T) {
- // Ensure 6l outputs sections without overlaps.
- if runtime.GOOS != "linux" && runtime.GOOS != "freebsd" {
- return // not ELF
- }
- _ = net.ResolveIPAddr // force dynamic linkage
- f, err := Open(os.Args[0])
- if err != nil {
- t.Error(err)
- return
- }
- for i, si := range f.Sections {
- sih := si.SectionHeader
- if sih.Type == SHT_NOBITS {
- continue
- }
- for j, sj := range f.Sections {
- sjh := sj.SectionHeader
- if i == j || sjh.Type == SHT_NOBITS || sih.Offset == sjh.Offset && sih.Size == 0 {
- continue
- }
- if sih.Offset >= sjh.Offset && sih.Offset < sjh.Offset+sjh.Size {
- t.Errorf("ld produced ELF with section %s within %s: 0x%x <= 0x%x..0x%x < 0x%x",
- sih.Name, sjh.Name, sjh.Offset, sih.Offset, sih.Offset+sih.Size, sjh.Offset+sjh.Size)
- }
- }
- }
-}
diff --git a/src/pkg/debug/elf/testdata/gcc-386-freebsd-exec b/src/pkg/debug/elf/testdata/gcc-386-freebsd-exec
deleted file mode 100755
index 7af9c58ca..000000000
--- a/src/pkg/debug/elf/testdata/gcc-386-freebsd-exec
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/elf/testdata/gcc-amd64-linux-exec b/src/pkg/debug/elf/testdata/gcc-amd64-linux-exec
deleted file mode 100755
index c6cb1de28..000000000
--- a/src/pkg/debug/elf/testdata/gcc-amd64-linux-exec
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/elf/testdata/gcc-amd64-openbsd-debug-with-rela.obj b/src/pkg/debug/elf/testdata/gcc-amd64-openbsd-debug-with-rela.obj
deleted file mode 100644
index f62b1ea1c..000000000
--- a/src/pkg/debug/elf/testdata/gcc-amd64-openbsd-debug-with-rela.obj
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/elf/testdata/go-relocation-test-clang-x86.obj b/src/pkg/debug/elf/testdata/go-relocation-test-clang-x86.obj
deleted file mode 100644
index e909cf4e6..000000000
--- a/src/pkg/debug/elf/testdata/go-relocation-test-clang-x86.obj
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/elf/testdata/go-relocation-test-gcc424-x86-64.obj b/src/pkg/debug/elf/testdata/go-relocation-test-gcc424-x86-64.obj
deleted file mode 100644
index a7c6d6e56..000000000
--- a/src/pkg/debug/elf/testdata/go-relocation-test-gcc424-x86-64.obj
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/elf/testdata/go-relocation-test-gcc441-x86-64.obj b/src/pkg/debug/elf/testdata/go-relocation-test-gcc441-x86-64.obj
deleted file mode 100644
index 2d37ab6e6..000000000
--- a/src/pkg/debug/elf/testdata/go-relocation-test-gcc441-x86-64.obj
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/elf/testdata/go-relocation-test-gcc441-x86.obj b/src/pkg/debug/elf/testdata/go-relocation-test-gcc441-x86.obj
deleted file mode 100644
index 0d59fe303..000000000
--- a/src/pkg/debug/elf/testdata/go-relocation-test-gcc441-x86.obj
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/elf/testdata/hello-world-core.gz b/src/pkg/debug/elf/testdata/hello-world-core.gz
deleted file mode 100644
index 806af6edb..000000000
--- a/src/pkg/debug/elf/testdata/hello-world-core.gz
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/elf/testdata/hello.c b/src/pkg/debug/elf/testdata/hello.c
deleted file mode 100644
index 34d9ee792..000000000
--- a/src/pkg/debug/elf/testdata/hello.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <stdio.h>
-
-void
-main(int argc, char *argv[])
-{
- printf("hello, world\n");
-}
diff --git a/src/pkg/debug/gosym/pclinetest.asm b/src/pkg/debug/gosym/pclinetest.asm
deleted file mode 100644
index b9ee9c0a5..000000000
--- a/src/pkg/debug/gosym/pclinetest.asm
+++ /dev/null
@@ -1,58 +0,0 @@
-TEXT linefrompc(SB),4,$0 // Each byte stores its line delta
-BYTE $2;
-BYTE $1;
-BYTE $1; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1;
-BYTE $1;
-BYTE $1; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-#include "pclinetest.h"
-BYTE $2;
-#include "pclinetest.h"
-BYTE $2;
-BYTE $255;
-
-TEXT pcfromline(SB),4,$0 // Each record stores its line delta, then n, then n more bytes
-BYTE $32; BYTE $0;
-BYTE $1; BYTE $1; BYTE $0;
-BYTE $1; BYTE $0;
-
-BYTE $2; BYTE $4; BYTE $0; BYTE $0; BYTE $0; BYTE $0;
-
-
-#include "pclinetest.h"
-BYTE $4; BYTE $0;
-
-
-BYTE $3; BYTE $3; BYTE $0; BYTE $0; BYTE $0;
-#include "pclinetest.h"
-
-
-BYTE $4; BYTE $3; BYTE $0; BYTE $0; BYTE $0;
-BYTE $255;
-
-// Keep the linker happy
-TEXT main·main(SB),4,$0
- RET
-
-TEXT main·init(SB),4,$0
- // Prevent GC of our test symbols
- CALL linefrompc(SB)
- CALL pcfromline(SB)
- RET
diff --git a/src/pkg/debug/gosym/pclinetest.h b/src/pkg/debug/gosym/pclinetest.h
deleted file mode 100644
index 156c0b87b..000000000
--- a/src/pkg/debug/gosym/pclinetest.h
+++ /dev/null
@@ -1,9 +0,0 @@
-// +build ignore
-
-// Empty include file to generate z symbols
-
-
-
-
-
-// EOF
diff --git a/src/pkg/debug/gosym/pclntab.go b/src/pkg/debug/gosym/pclntab.go
deleted file mode 100644
index 6620aefb0..000000000
--- a/src/pkg/debug/gosym/pclntab.go
+++ /dev/null
@@ -1,453 +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.
-
-/*
- * Line tables
- */
-
-package gosym
-
-import (
- "encoding/binary"
- "sync"
-)
-
-// A LineTable is a data structure mapping program counters to line numbers.
-//
-// In Go 1.1 and earlier, each function (represented by a Func) had its own LineTable,
-// and the line number corresponded to a numbering of all source lines in the
-// program, across all files. That absolute line number would then have to be
-// converted separately to a file name and line number within the file.
-//
-// In Go 1.2, the format of the data changed so that there is a single LineTable
-// for the entire program, shared by all Funcs, and there are no absolute line
-// numbers, just line numbers within specific files.
-//
-// For the most part, LineTable's methods should be treated as an internal
-// detail of the package; callers should use the methods on Table instead.
-type LineTable struct {
- Data []byte
- PC uint64
- Line int
-
- // Go 1.2 state
- mu sync.Mutex
- go12 int // is this in Go 1.2 format? -1 no, 0 unknown, 1 yes
- binary binary.ByteOrder
- quantum uint32
- ptrsize uint32
- functab []byte
- nfunctab uint32
- filetab []byte
- nfiletab uint32
- fileMap map[string]uint32
-}
-
-// NOTE(rsc): This is wrong for GOARCH=arm, which uses a quantum of 4,
-// but we have no idea whether we're using arm or not. This only
-// matters in the old (pre-Go 1.2) symbol table format, so it's not worth
-// fixing.
-const oldQuantum = 1
-
-func (t *LineTable) parse(targetPC uint64, targetLine int) (b []byte, pc uint64, line int) {
- // The PC/line table can be thought of as a sequence of
- // <pc update>* <line update>
- // batches. Each update batch results in a (pc, line) pair,
- // where line applies to every PC from pc up to but not
- // including the pc of the next pair.
- //
- // Here we process each update individually, which simplifies
- // the code, but makes the corner cases more confusing.
- b, pc, line = t.Data, t.PC, t.Line
- for pc <= targetPC && line != targetLine && len(b) > 0 {
- code := b[0]
- b = b[1:]
- switch {
- case code == 0:
- if len(b) < 4 {
- b = b[0:0]
- break
- }
- val := binary.BigEndian.Uint32(b)
- b = b[4:]
- line += int(val)
- case code <= 64:
- line += int(code)
- case code <= 128:
- line -= int(code - 64)
- default:
- pc += oldQuantum * uint64(code-128)
- continue
- }
- pc += oldQuantum
- }
- return b, pc, line
-}
-
-func (t *LineTable) slice(pc uint64) *LineTable {
- data, pc, line := t.parse(pc, -1)
- return &LineTable{Data: data, PC: pc, Line: line}
-}
-
-// PCToLine returns the line number for the given program counter.
-// Callers should use Table's PCToLine method instead.
-func (t *LineTable) PCToLine(pc uint64) int {
- if t.isGo12() {
- return t.go12PCToLine(pc)
- }
- _, _, line := t.parse(pc, -1)
- return line
-}
-
-// LineToPC returns the program counter for the given line number,
-// considering only program counters before maxpc.
-// Callers should use Table's LineToPC method instead.
-func (t *LineTable) LineToPC(line int, maxpc uint64) uint64 {
- if t.isGo12() {
- return 0
- }
- _, pc, line1 := t.parse(maxpc, line)
- if line1 != line {
- return 0
- }
- // Subtract quantum from PC to account for post-line increment
- return pc - oldQuantum
-}
-
-// NewLineTable returns a new PC/line table
-// corresponding to the encoded data.
-// Text must be the start address of the
-// corresponding text segment.
-func NewLineTable(data []byte, text uint64) *LineTable {
- return &LineTable{Data: data, PC: text, Line: 0}
-}
-
-// Go 1.2 symbol table format.
-// See golang.org/s/go12symtab.
-//
-// A general note about the methods here: rather than try to avoid
-// index out of bounds errors, we trust Go to detect them, and then
-// we recover from the panics and treat them as indicative of a malformed
-// or incomplete table.
-//
-// The methods called by symtab.go, which begin with "go12" prefixes,
-// are expected to have that recovery logic.
-
-// isGo12 reports whether this is a Go 1.2 (or later) symbol table.
-func (t *LineTable) isGo12() bool {
- t.go12Init()
- return t.go12 == 1
-}
-
-const go12magic = 0xfffffffb
-
-// uintptr returns the pointer-sized value encoded at b.
-// The pointer size is dictated by the table being read.
-func (t *LineTable) uintptr(b []byte) uint64 {
- if t.ptrsize == 4 {
- return uint64(t.binary.Uint32(b))
- }
- return t.binary.Uint64(b)
-}
-
-// go12init initializes the Go 1.2 metadata if t is a Go 1.2 symbol table.
-func (t *LineTable) go12Init() {
- t.mu.Lock()
- defer t.mu.Unlock()
- if t.go12 != 0 {
- return
- }
-
- defer func() {
- // If we panic parsing, assume it's not a Go 1.2 symbol table.
- recover()
- }()
-
- // Check header: 4-byte magic, two zeros, pc quantum, pointer size.
- t.go12 = -1 // not Go 1.2 until proven otherwise
- if len(t.Data) < 16 || t.Data[4] != 0 || t.Data[5] != 0 ||
- (t.Data[6] != 1 && t.Data[6] != 4) || // pc quantum
- (t.Data[7] != 4 && t.Data[7] != 8) { // pointer size
- return
- }
-
- switch uint32(go12magic) {
- case binary.LittleEndian.Uint32(t.Data):
- t.binary = binary.LittleEndian
- case binary.BigEndian.Uint32(t.Data):
- t.binary = binary.BigEndian
- default:
- return
- }
-
- t.quantum = uint32(t.Data[6])
- t.ptrsize = uint32(t.Data[7])
-
- t.nfunctab = uint32(t.uintptr(t.Data[8:]))
- t.functab = t.Data[8+t.ptrsize:]
- functabsize := t.nfunctab*2*t.ptrsize + t.ptrsize
- fileoff := t.binary.Uint32(t.functab[functabsize:])
- t.functab = t.functab[:functabsize]
- t.filetab = t.Data[fileoff:]
- t.nfiletab = t.binary.Uint32(t.filetab)
- t.filetab = t.filetab[:t.nfiletab*4]
-
- t.go12 = 1 // so far so good
-}
-
-// go12Funcs returns a slice of Funcs derived from the Go 1.2 pcln table.
-func (t *LineTable) go12Funcs() []Func {
- // Assume it is malformed and return nil on error.
- defer func() {
- recover()
- }()
-
- n := len(t.functab) / int(t.ptrsize) / 2
- funcs := make([]Func, n)
- for i := range funcs {
- f := &funcs[i]
- f.Entry = uint64(t.uintptr(t.functab[2*i*int(t.ptrsize):]))
- f.End = uint64(t.uintptr(t.functab[(2*i+2)*int(t.ptrsize):]))
- info := t.Data[t.uintptr(t.functab[(2*i+1)*int(t.ptrsize):]):]
- f.LineTable = t
- f.FrameSize = int(t.binary.Uint32(info[t.ptrsize+2*4:]))
- f.Sym = &Sym{
- Value: f.Entry,
- Type: 'T',
- Name: t.string(t.binary.Uint32(info[t.ptrsize:])),
- GoType: 0,
- Func: f,
- }
- }
- return funcs
-}
-
-// findFunc returns the func corresponding to the given program counter.
-func (t *LineTable) findFunc(pc uint64) []byte {
- if pc < t.uintptr(t.functab) || pc >= t.uintptr(t.functab[len(t.functab)-int(t.ptrsize):]) {
- return nil
- }
-
- // The function table is a list of 2*nfunctab+1 uintptrs,
- // alternating program counters and offsets to func structures.
- f := t.functab
- nf := t.nfunctab
- for nf > 0 {
- m := nf / 2
- fm := f[2*t.ptrsize*m:]
- if t.uintptr(fm) <= pc && pc < t.uintptr(fm[2*t.ptrsize:]) {
- return t.Data[t.uintptr(fm[t.ptrsize:]):]
- } else if pc < t.uintptr(fm) {
- nf = m
- } else {
- f = f[(m+1)*2*t.ptrsize:]
- nf -= m + 1
- }
- }
- return nil
-}
-
-// readvarint reads, removes, and returns a varint from *pp.
-func (t *LineTable) readvarint(pp *[]byte) uint32 {
- var v, shift uint32
- p := *pp
- for shift = 0; ; shift += 7 {
- b := p[0]
- p = p[1:]
- v |= (uint32(b) & 0x7F) << shift
- if b&0x80 == 0 {
- break
- }
- }
- *pp = p
- return v
-}
-
-// string returns a Go string found at off.
-func (t *LineTable) string(off uint32) string {
- for i := off; ; i++ {
- if t.Data[i] == 0 {
- return string(t.Data[off:i])
- }
- }
-}
-
-// step advances to the next pc, value pair in the encoded table.
-func (t *LineTable) step(p *[]byte, pc *uint64, val *int32, first bool) bool {
- uvdelta := t.readvarint(p)
- if uvdelta == 0 && !first {
- return false
- }
- if uvdelta&1 != 0 {
- uvdelta = ^(uvdelta >> 1)
- } else {
- uvdelta >>= 1
- }
- vdelta := int32(uvdelta)
- pcdelta := t.readvarint(p) * t.quantum
- *pc += uint64(pcdelta)
- *val += vdelta
- return true
-}
-
-// pcvalue reports the value associated with the target pc.
-// off is the offset to the beginning of the pc-value table,
-// and entry is the start PC for the corresponding function.
-func (t *LineTable) pcvalue(off uint32, entry, targetpc uint64) int32 {
- if off == 0 {
- return -1
- }
- p := t.Data[off:]
-
- val := int32(-1)
- pc := entry
- for t.step(&p, &pc, &val, pc == entry) {
- if targetpc < pc {
- return val
- }
- }
- return -1
-}
-
-// findFileLine scans one function in the binary looking for a
-// program counter in the given file on the given line.
-// It does so by running the pc-value tables mapping program counter
-// to file number. Since most functions come from a single file, these
-// are usually short and quick to scan. If a file match is found, then the
-// code goes to the expense of looking for a simultaneous line number match.
-func (t *LineTable) findFileLine(entry uint64, filetab, linetab uint32, filenum, line int32) uint64 {
- if filetab == 0 || linetab == 0 {
- return 0
- }
-
- fp := t.Data[filetab:]
- fl := t.Data[linetab:]
- fileVal := int32(-1)
- filePC := entry
- lineVal := int32(-1)
- linePC := entry
- fileStartPC := filePC
- for t.step(&fp, &filePC, &fileVal, filePC == entry) {
- if fileVal == filenum && fileStartPC < filePC {
- // fileVal is in effect starting at fileStartPC up to
- // but not including filePC, and it's the file we want.
- // Run the PC table looking for a matching line number
- // or until we reach filePC.
- lineStartPC := linePC
- for linePC < filePC && t.step(&fl, &linePC, &lineVal, linePC == entry) {
- // lineVal is in effect until linePC, and lineStartPC < filePC.
- if lineVal == line {
- if fileStartPC <= lineStartPC {
- return lineStartPC
- }
- if fileStartPC < linePC {
- return fileStartPC
- }
- }
- lineStartPC = linePC
- }
- }
- fileStartPC = filePC
- }
- return 0
-}
-
-// go12PCToLine maps program counter to line number for the Go 1.2 pcln table.
-func (t *LineTable) go12PCToLine(pc uint64) (line int) {
- defer func() {
- if recover() != nil {
- line = -1
- }
- }()
-
- f := t.findFunc(pc)
- if f == nil {
- return -1
- }
- entry := t.uintptr(f)
- linetab := t.binary.Uint32(f[t.ptrsize+5*4:])
- return int(t.pcvalue(linetab, entry, pc))
-}
-
-// go12PCToFile maps program counter to file name for the Go 1.2 pcln table.
-func (t *LineTable) go12PCToFile(pc uint64) (file string) {
- defer func() {
- if recover() != nil {
- file = ""
- }
- }()
-
- f := t.findFunc(pc)
- if f == nil {
- return ""
- }
- entry := t.uintptr(f)
- filetab := t.binary.Uint32(f[t.ptrsize+4*4:])
- fno := t.pcvalue(filetab, entry, pc)
- if fno <= 0 {
- return ""
- }
- return t.string(t.binary.Uint32(t.filetab[4*fno:]))
-}
-
-// go12LineToPC maps a (file, line) pair to a program counter for the Go 1.2 pcln table.
-func (t *LineTable) go12LineToPC(file string, line int) (pc uint64) {
- defer func() {
- if recover() != nil {
- pc = 0
- }
- }()
-
- t.initFileMap()
- filenum := t.fileMap[file]
- if filenum == 0 {
- return 0
- }
-
- // Scan all functions.
- // If this turns out to be a bottleneck, we could build a map[int32][]int32
- // mapping file number to a list of functions with code from that file.
- for i := uint32(0); i < t.nfunctab; i++ {
- f := t.Data[t.uintptr(t.functab[2*t.ptrsize*i+t.ptrsize:]):]
- entry := t.uintptr(f)
- filetab := t.binary.Uint32(f[t.ptrsize+4*4:])
- linetab := t.binary.Uint32(f[t.ptrsize+5*4:])
- pc := t.findFileLine(entry, filetab, linetab, int32(filenum), int32(line))
- if pc != 0 {
- return pc
- }
- }
- return 0
-}
-
-// initFileMap initializes the map from file name to file number.
-func (t *LineTable) initFileMap() {
- t.mu.Lock()
- defer t.mu.Unlock()
-
- if t.fileMap != nil {
- return
- }
- m := make(map[string]uint32)
-
- for i := uint32(1); i < t.nfiletab; i++ {
- s := t.string(t.binary.Uint32(t.filetab[4*i:]))
- m[s] = i
- }
- t.fileMap = m
-}
-
-// go12MapFiles adds to m a key for every file in the Go 1.2 LineTable.
-// Every key maps to obj. That's not a very interesting map, but it provides
-// a way for callers to obtain the list of files in the program.
-func (t *LineTable) go12MapFiles(m map[string]*Obj, obj *Obj) {
- defer func() {
- recover()
- }()
-
- t.initFileMap()
- for file := range t.fileMap {
- m[file] = obj
- }
-}
diff --git a/src/pkg/debug/gosym/pclntab_test.go b/src/pkg/debug/gosym/pclntab_test.go
deleted file mode 100644
index 35502e8c3..000000000
--- a/src/pkg/debug/gosym/pclntab_test.go
+++ /dev/null
@@ -1,274 +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 gosym
-
-import (
- "debug/elf"
- "fmt"
- "io/ioutil"
- "os"
- "os/exec"
- "path/filepath"
- "runtime"
- "strings"
- "testing"
-)
-
-var (
- pclineTempDir string
- pclinetestBinary string
-)
-
-func dotest(self bool) bool {
- // For now, only works on amd64 platforms.
- if runtime.GOARCH != "amd64" {
- return false
- }
- // Self test reads test binary; only works on Linux.
- if self && runtime.GOOS != "linux" {
- return false
- }
- // Command below expects "sh", so Unix.
- if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
- return false
- }
- if pclinetestBinary != "" {
- return true
- }
- var err error
- pclineTempDir, err = ioutil.TempDir("", "pclinetest")
- if err != nil {
- panic(err)
- }
- if strings.Contains(pclineTempDir, " ") {
- panic("unexpected space in tempdir")
- }
- // This command builds pclinetest from pclinetest.asm;
- // the resulting binary looks like it was built from pclinetest.s,
- // but we have renamed it to keep it away from the go tool.
- pclinetestBinary = filepath.Join(pclineTempDir, "pclinetest")
- command := fmt.Sprintf("go tool 6a -o %s.6 pclinetest.asm && go tool 6l -H linux -E main -o %s %s.6",
- pclinetestBinary, pclinetestBinary, pclinetestBinary)
- cmd := exec.Command("sh", "-c", command)
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- if err := cmd.Run(); err != nil {
- panic(err)
- }
- return true
-}
-
-func endtest() {
- if pclineTempDir != "" {
- os.RemoveAll(pclineTempDir)
- pclineTempDir = ""
- pclinetestBinary = ""
- }
-}
-
-func getTable(t *testing.T) *Table {
- f, tab := crack(os.Args[0], t)
- f.Close()
- return tab
-}
-
-func crack(file string, t *testing.T) (*elf.File, *Table) {
- // Open self
- f, err := elf.Open(file)
- if err != nil {
- t.Fatal(err)
- }
- return parse(file, f, t)
-}
-
-func parse(file string, f *elf.File, t *testing.T) (*elf.File, *Table) {
- symdat, err := f.Section(".gosymtab").Data()
- if err != nil {
- f.Close()
- t.Fatalf("reading %s gosymtab: %v", file, err)
- }
- pclndat, err := f.Section(".gopclntab").Data()
- if err != nil {
- f.Close()
- t.Fatalf("reading %s gopclntab: %v", file, err)
- }
-
- pcln := NewLineTable(pclndat, f.Section(".text").Addr)
- tab, err := NewTable(symdat, pcln)
- if err != nil {
- f.Close()
- t.Fatalf("parsing %s gosymtab: %v", file, err)
- }
-
- return f, tab
-}
-
-var goarch = os.Getenv("O")
-
-func TestLineFromAline(t *testing.T) {
- if !dotest(true) {
- return
- }
- defer endtest()
-
- tab := getTable(t)
- if tab.go12line != nil {
- // aline's don't exist in the Go 1.2 table.
- t.Skip("not relevant to Go 1.2 symbol table")
- }
-
- // Find the sym package
- pkg := tab.LookupFunc("debug/gosym.TestLineFromAline").Obj
- if pkg == nil {
- t.Fatalf("nil pkg")
- }
-
- // Walk every absolute line and ensure that we hit every
- // source line monotonically
- lastline := make(map[string]int)
- final := -1
- for i := 0; i < 10000; i++ {
- path, line := pkg.lineFromAline(i)
- // Check for end of object
- if path == "" {
- if final == -1 {
- final = i - 1
- }
- continue
- } else if final != -1 {
- t.Fatalf("reached end of package at absolute line %d, but absolute line %d mapped to %s:%d", final, i, path, line)
- }
- // It's okay to see files multiple times (e.g., sys.a)
- if line == 1 {
- lastline[path] = 1
- continue
- }
- // Check that the is the next line in path
- ll, ok := lastline[path]
- if !ok {
- t.Errorf("file %s starts on line %d", path, line)
- } else if line != ll+1 {
- t.Fatalf("expected next line of file %s to be %d, got %d", path, ll+1, line)
- }
- lastline[path] = line
- }
- if final == -1 {
- t.Errorf("never reached end of object")
- }
-}
-
-func TestLineAline(t *testing.T) {
- if !dotest(true) {
- return
- }
- defer endtest()
-
- tab := getTable(t)
- if tab.go12line != nil {
- // aline's don't exist in the Go 1.2 table.
- t.Skip("not relevant to Go 1.2 symbol table")
- }
-
- for _, o := range tab.Files {
- // A source file can appear multiple times in a
- // object. alineFromLine will always return alines in
- // the first file, so track which lines we've seen.
- found := make(map[string]int)
- for i := 0; i < 1000; i++ {
- path, line := o.lineFromAline(i)
- if path == "" {
- break
- }
-
- // cgo files are full of 'Z' symbols, which we don't handle
- if len(path) > 4 && path[len(path)-4:] == ".cgo" {
- continue
- }
-
- if minline, ok := found[path]; path != "" && ok {
- if minline >= line {
- // We've already covered this file
- continue
- }
- }
- found[path] = line
-
- a, err := o.alineFromLine(path, line)
- if err != nil {
- t.Errorf("absolute line %d in object %s maps to %s:%d, but mapping that back gives error %s", i, o.Paths[0].Name, path, line, err)
- } else if a != i {
- t.Errorf("absolute line %d in object %s maps to %s:%d, which maps back to absolute line %d\n", i, o.Paths[0].Name, path, line, a)
- }
- }
- }
-}
-
-func TestPCLine(t *testing.T) {
- if !dotest(false) {
- return
- }
- defer endtest()
-
- f, tab := crack(pclinetestBinary, t)
- text := f.Section(".text")
- textdat, err := text.Data()
- if err != nil {
- t.Fatalf("reading .text: %v", err)
- }
-
- // Test PCToLine
- sym := tab.LookupFunc("linefrompc")
- wantLine := 0
- for pc := sym.Entry; pc < sym.End; pc++ {
- off := pc - text.Addr // TODO(rsc): should not need off; bug in 8g
- if textdat[off] == 255 {
- break
- }
- wantLine += int(textdat[off])
- t.Logf("off is %d %#x (max %d)", off, textdat[off], sym.End-pc)
- file, line, fn := tab.PCToLine(pc)
- if fn == nil {
- t.Errorf("failed to get line of PC %#x", pc)
- } else if !strings.HasSuffix(file, "pclinetest.asm") || line != wantLine || fn != sym {
- t.Errorf("PCToLine(%#x) = %s:%d (%s), want %s:%d (%s)", pc, file, line, fn.Name, "pclinetest.asm", wantLine, sym.Name)
- }
- }
-
- // Test LineToPC
- sym = tab.LookupFunc("pcfromline")
- lookupline := -1
- wantLine = 0
- off := uint64(0) // TODO(rsc): should not need off; bug in 8g
- for pc := sym.Value; pc < sym.End; pc += 2 + uint64(textdat[off]) {
- file, line, fn := tab.PCToLine(pc)
- off = pc - text.Addr
- if textdat[off] == 255 {
- break
- }
- wantLine += int(textdat[off])
- if line != wantLine {
- t.Errorf("expected line %d at PC %#x in pcfromline, got %d", wantLine, pc, line)
- off = pc + 1 - text.Addr
- continue
- }
- if lookupline == -1 {
- lookupline = line
- }
- for ; lookupline <= line; lookupline++ {
- pc2, fn2, err := tab.LineToPC(file, lookupline)
- if lookupline != line {
- // Should be nothing on this line
- if err == nil {
- t.Errorf("expected no PC at line %d, got %#x (%s)", lookupline, pc2, fn2.Name)
- }
- } else if err != nil {
- t.Errorf("failed to get PC of line %d: %s", lookupline, err)
- } else if pc != pc2 {
- t.Errorf("expected PC %#x (%s) at line %d, got PC %#x (%s)", pc, fn.Name, line, pc2, fn2.Name)
- }
- }
- off = pc + 1 - text.Addr
- }
-}
diff --git a/src/pkg/debug/gosym/symtab.go b/src/pkg/debug/gosym/symtab.go
deleted file mode 100644
index 3864e3cb4..000000000
--- a/src/pkg/debug/gosym/symtab.go
+++ /dev/null
@@ -1,710 +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 gosym implements access to the Go symbol
-// and line number tables embedded in Go binaries generated
-// by the gc compilers.
-package gosym
-
-// The table format is a variant of the format used in Plan 9's a.out
-// format, documented at http://plan9.bell-labs.com/magic/man2html/6/a.out.
-// The best reference for the differences between the Plan 9 format
-// and the Go format is the runtime source, specifically ../../runtime/symtab.c.
-
-import (
- "bytes"
- "encoding/binary"
- "fmt"
- "strconv"
- "strings"
-)
-
-/*
- * Symbols
- */
-
-// A Sym represents a single symbol table entry.
-type Sym struct {
- Value uint64
- Type byte
- Name string
- GoType uint64
- // If this symbol if a function symbol, the corresponding Func
- Func *Func
-}
-
-// Static reports whether this symbol is static (not visible outside its file).
-func (s *Sym) Static() bool { return s.Type >= 'a' }
-
-// PackageName returns the package part of the symbol name,
-// or the empty string if there is none.
-func (s *Sym) PackageName() string {
- if i := strings.Index(s.Name, "."); i != -1 {
- return s.Name[0:i]
- }
- return ""
-}
-
-// ReceiverName returns the receiver type name of this symbol,
-// or the empty string if there is none.
-func (s *Sym) ReceiverName() string {
- l := strings.Index(s.Name, ".")
- r := strings.LastIndex(s.Name, ".")
- if l == -1 || r == -1 || l == r {
- return ""
- }
- return s.Name[l+1 : r]
-}
-
-// BaseName returns the symbol name without the package or receiver name.
-func (s *Sym) BaseName() string {
- if i := strings.LastIndex(s.Name, "."); i != -1 {
- return s.Name[i+1:]
- }
- return s.Name
-}
-
-// A Func collects information about a single function.
-type Func struct {
- Entry uint64
- *Sym
- End uint64
- Params []*Sym
- Locals []*Sym
- FrameSize int
- LineTable *LineTable
- Obj *Obj
-}
-
-// An Obj represents a collection of functions in a symbol table.
-//
-// The exact method of division of a binary into separate Objs is an internal detail
-// of the symbol table format.
-//
-// In early versions of Go each source file became a different Obj.
-//
-// In Go 1 and Go 1.1, each package produced one Obj for all Go sources
-// and one Obj per C source file.
-//
-// In Go 1.2, there is a single Obj for the entire program.
-type Obj struct {
- // Funcs is a list of functions in the Obj.
- Funcs []Func
-
- // In Go 1.1 and earlier, Paths is a list of symbols corresponding
- // to the source file names that produced the Obj.
- // In Go 1.2, Paths is nil.
- // Use the keys of Table.Files to obtain a list of source files.
- Paths []Sym // meta
-}
-
-/*
- * Symbol tables
- */
-
-// Table represents a Go symbol table. It stores all of the
-// symbols decoded from the program and provides methods to translate
-// between symbols, names, and addresses.
-type Table struct {
- Syms []Sym
- Funcs []Func
- Files map[string]*Obj // nil for Go 1.2 and later binaries
- Objs []Obj // nil for Go 1.2 and later binaries
-
- go12line *LineTable // Go 1.2 line number table
-}
-
-type sym struct {
- value uint64
- gotype uint64
- typ byte
- name []byte
-}
-
-var (
- littleEndianSymtab = []byte{0xFD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00}
- bigEndianSymtab = []byte{0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00}
- oldLittleEndianSymtab = []byte{0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00}
-)
-
-func walksymtab(data []byte, fn func(sym) error) error {
- if len(data) == 0 { // missing symtab is okay
- return nil
- }
- var order binary.ByteOrder = binary.BigEndian
- newTable := false
- switch {
- case bytes.HasPrefix(data, oldLittleEndianSymtab):
- // Same as Go 1.0, but little endian.
- // Format was used during interim development between Go 1.0 and Go 1.1.
- // Should not be widespread, but easy to support.
- data = data[6:]
- order = binary.LittleEndian
- case bytes.HasPrefix(data, bigEndianSymtab):
- newTable = true
- case bytes.HasPrefix(data, littleEndianSymtab):
- newTable = true
- order = binary.LittleEndian
- }
- var ptrsz int
- if newTable {
- if len(data) < 8 {
- return &DecodingError{len(data), "unexpected EOF", nil}
- }
- ptrsz = int(data[7])
- if ptrsz != 4 && ptrsz != 8 {
- return &DecodingError{7, "invalid pointer size", ptrsz}
- }
- data = data[8:]
- }
- var s sym
- p := data
- for len(p) >= 4 {
- var typ byte
- if newTable {
- // Symbol type, value, Go type.
- typ = p[0] & 0x3F
- wideValue := p[0]&0x40 != 0
- goType := p[0]&0x80 != 0
- if typ < 26 {
- typ += 'A'
- } else {
- typ += 'a' - 26
- }
- s.typ = typ
- p = p[1:]
- if wideValue {
- if len(p) < ptrsz {
- return &DecodingError{len(data), "unexpected EOF", nil}
- }
- // fixed-width value
- if ptrsz == 8 {
- s.value = order.Uint64(p[0:8])
- p = p[8:]
- } else {
- s.value = uint64(order.Uint32(p[0:4]))
- p = p[4:]
- }
- } else {
- // varint value
- s.value = 0
- shift := uint(0)
- for len(p) > 0 && p[0]&0x80 != 0 {
- s.value |= uint64(p[0]&0x7F) << shift
- shift += 7
- p = p[1:]
- }
- if len(p) == 0 {
- return &DecodingError{len(data), "unexpected EOF", nil}
- }
- s.value |= uint64(p[0]) << shift
- p = p[1:]
- }
- if goType {
- if len(p) < ptrsz {
- return &DecodingError{len(data), "unexpected EOF", nil}
- }
- // fixed-width go type
- if ptrsz == 8 {
- s.gotype = order.Uint64(p[0:8])
- p = p[8:]
- } else {
- s.gotype = uint64(order.Uint32(p[0:4]))
- p = p[4:]
- }
- }
- } else {
- // Value, symbol type.
- s.value = uint64(order.Uint32(p[0:4]))
- if len(p) < 5 {
- return &DecodingError{len(data), "unexpected EOF", nil}
- }
- typ = p[4]
- if typ&0x80 == 0 {
- return &DecodingError{len(data) - len(p) + 4, "bad symbol type", typ}
- }
- typ &^= 0x80
- s.typ = typ
- p = p[5:]
- }
-
- // Name.
- var i int
- var nnul int
- for i = 0; i < len(p); i++ {
- if p[i] == 0 {
- nnul = 1
- break
- }
- }
- switch typ {
- case 'z', 'Z':
- p = p[i+nnul:]
- for i = 0; i+2 <= len(p); i += 2 {
- if p[i] == 0 && p[i+1] == 0 {
- nnul = 2
- break
- }
- }
- }
- if len(p) < i+nnul {
- return &DecodingError{len(data), "unexpected EOF", nil}
- }
- s.name = p[0:i]
- i += nnul
- p = p[i:]
-
- if !newTable {
- if len(p) < 4 {
- return &DecodingError{len(data), "unexpected EOF", nil}
- }
- // Go type.
- s.gotype = uint64(order.Uint32(p[:4]))
- p = p[4:]
- }
- fn(s)
- }
- return nil
-}
-
-// NewTable decodes the Go symbol table in data,
-// returning an in-memory representation.
-func NewTable(symtab []byte, pcln *LineTable) (*Table, error) {
- var n int
- err := walksymtab(symtab, func(s sym) error {
- n++
- return nil
- })
- if err != nil {
- return nil, err
- }
-
- var t Table
- if pcln.isGo12() {
- t.go12line = pcln
- }
- fname := make(map[uint16]string)
- t.Syms = make([]Sym, 0, n)
- nf := 0
- nz := 0
- lasttyp := uint8(0)
- err = walksymtab(symtab, func(s sym) error {
- n := len(t.Syms)
- t.Syms = t.Syms[0 : n+1]
- ts := &t.Syms[n]
- ts.Type = s.typ
- ts.Value = uint64(s.value)
- ts.GoType = uint64(s.gotype)
- switch s.typ {
- default:
- // rewrite name to use . instead of · (c2 b7)
- w := 0
- b := s.name
- for i := 0; i < len(b); i++ {
- if b[i] == 0xc2 && i+1 < len(b) && b[i+1] == 0xb7 {
- i++
- b[i] = '.'
- }
- b[w] = b[i]
- w++
- }
- ts.Name = string(s.name[0:w])
- case 'z', 'Z':
- if lasttyp != 'z' && lasttyp != 'Z' {
- nz++
- }
- for i := 0; i < len(s.name); i += 2 {
- eltIdx := binary.BigEndian.Uint16(s.name[i : i+2])
- elt, ok := fname[eltIdx]
- if !ok {
- return &DecodingError{-1, "bad filename code", eltIdx}
- }
- if n := len(ts.Name); n > 0 && ts.Name[n-1] != '/' {
- ts.Name += "/"
- }
- ts.Name += elt
- }
- }
- switch s.typ {
- case 'T', 't', 'L', 'l':
- nf++
- case 'f':
- fname[uint16(s.value)] = ts.Name
- }
- lasttyp = s.typ
- return nil
- })
- if err != nil {
- return nil, err
- }
-
- t.Funcs = make([]Func, 0, nf)
- t.Files = make(map[string]*Obj)
-
- var obj *Obj
- if t.go12line != nil {
- // Put all functions into one Obj.
- t.Objs = make([]Obj, 1)
- obj = &t.Objs[0]
- t.go12line.go12MapFiles(t.Files, obj)
- } else {
- t.Objs = make([]Obj, 0, nz)
- }
-
- // Count text symbols and attach frame sizes, parameters, and
- // locals to them. Also, find object file boundaries.
- lastf := 0
- for i := 0; i < len(t.Syms); i++ {
- sym := &t.Syms[i]
- switch sym.Type {
- case 'Z', 'z': // path symbol
- if t.go12line != nil {
- // Go 1.2 binaries have the file information elsewhere. Ignore.
- break
- }
- // Finish the current object
- if obj != nil {
- obj.Funcs = t.Funcs[lastf:]
- }
- lastf = len(t.Funcs)
-
- // Start new object
- n := len(t.Objs)
- t.Objs = t.Objs[0 : n+1]
- obj = &t.Objs[n]
-
- // Count & copy path symbols
- var end int
- for end = i + 1; end < len(t.Syms); end++ {
- if c := t.Syms[end].Type; c != 'Z' && c != 'z' {
- break
- }
- }
- obj.Paths = t.Syms[i:end]
- i = end - 1 // loop will i++
-
- // Record file names
- depth := 0
- for j := range obj.Paths {
- s := &obj.Paths[j]
- if s.Name == "" {
- depth--
- } else {
- if depth == 0 {
- t.Files[s.Name] = obj
- }
- depth++
- }
- }
-
- case 'T', 't', 'L', 'l': // text symbol
- if n := len(t.Funcs); n > 0 {
- t.Funcs[n-1].End = sym.Value
- }
- if sym.Name == "etext" {
- continue
- }
-
- // Count parameter and local (auto) syms
- var np, na int
- var end int
- countloop:
- for end = i + 1; end < len(t.Syms); end++ {
- switch t.Syms[end].Type {
- case 'T', 't', 'L', 'l', 'Z', 'z':
- break countloop
- case 'p':
- np++
- case 'a':
- na++
- }
- }
-
- // Fill in the function symbol
- n := len(t.Funcs)
- t.Funcs = t.Funcs[0 : n+1]
- fn := &t.Funcs[n]
- sym.Func = fn
- fn.Params = make([]*Sym, 0, np)
- fn.Locals = make([]*Sym, 0, na)
- fn.Sym = sym
- fn.Entry = sym.Value
- fn.Obj = obj
- if t.go12line != nil {
- // All functions share the same line table.
- // It knows how to narrow down to a specific
- // function quickly.
- fn.LineTable = t.go12line
- } else if pcln != nil {
- fn.LineTable = pcln.slice(fn.Entry)
- pcln = fn.LineTable
- }
- for j := i; j < end; j++ {
- s := &t.Syms[j]
- switch s.Type {
- case 'm':
- fn.FrameSize = int(s.Value)
- case 'p':
- n := len(fn.Params)
- fn.Params = fn.Params[0 : n+1]
- fn.Params[n] = s
- case 'a':
- n := len(fn.Locals)
- fn.Locals = fn.Locals[0 : n+1]
- fn.Locals[n] = s
- }
- }
- i = end - 1 // loop will i++
- }
- }
-
- if t.go12line != nil && nf == 0 {
- t.Funcs = t.go12line.go12Funcs()
- }
- if obj != nil {
- obj.Funcs = t.Funcs[lastf:]
- }
- return &t, nil
-}
-
-// PCToFunc returns the function containing the program counter pc,
-// or nil if there is no such function.
-func (t *Table) PCToFunc(pc uint64) *Func {
- funcs := t.Funcs
- for len(funcs) > 0 {
- m := len(funcs) / 2
- fn := &funcs[m]
- switch {
- case pc < fn.Entry:
- funcs = funcs[0:m]
- case fn.Entry <= pc && pc < fn.End:
- return fn
- default:
- funcs = funcs[m+1:]
- }
- }
- return nil
-}
-
-// PCToLine looks up line number information for a program counter.
-// If there is no information, it returns fn == nil.
-func (t *Table) PCToLine(pc uint64) (file string, line int, fn *Func) {
- if fn = t.PCToFunc(pc); fn == nil {
- return
- }
- if t.go12line != nil {
- file = t.go12line.go12PCToFile(pc)
- line = t.go12line.go12PCToLine(pc)
- } else {
- file, line = fn.Obj.lineFromAline(fn.LineTable.PCToLine(pc))
- }
- return
-}
-
-// LineToPC looks up the first program counter on the given line in
-// the named file. It returns UnknownPathError or UnknownLineError if
-// there is an error looking up this line.
-func (t *Table) LineToPC(file string, line int) (pc uint64, fn *Func, err error) {
- obj, ok := t.Files[file]
- if !ok {
- return 0, nil, UnknownFileError(file)
- }
-
- if t.go12line != nil {
- pc := t.go12line.go12LineToPC(file, line)
- if pc == 0 {
- return 0, nil, &UnknownLineError{file, line}
- }
- return pc, t.PCToFunc(pc), nil
- }
-
- abs, err := obj.alineFromLine(file, line)
- if err != nil {
- return
- }
- for i := range obj.Funcs {
- f := &obj.Funcs[i]
- pc := f.LineTable.LineToPC(abs, f.End)
- if pc != 0 {
- return pc, f, nil
- }
- }
- return 0, nil, &UnknownLineError{file, line}
-}
-
-// LookupSym returns the text, data, or bss symbol with the given name,
-// or nil if no such symbol is found.
-func (t *Table) LookupSym(name string) *Sym {
- // TODO(austin) Maybe make a map
- for i := range t.Syms {
- s := &t.Syms[i]
- switch s.Type {
- case 'T', 't', 'L', 'l', 'D', 'd', 'B', 'b':
- if s.Name == name {
- return s
- }
- }
- }
- return nil
-}
-
-// LookupFunc returns the text, data, or bss symbol with the given name,
-// or nil if no such symbol is found.
-func (t *Table) LookupFunc(name string) *Func {
- for i := range t.Funcs {
- f := &t.Funcs[i]
- if f.Sym.Name == name {
- return f
- }
- }
- return nil
-}
-
-// SymByAddr returns the text, data, or bss symbol starting at the given address.
-func (t *Table) SymByAddr(addr uint64) *Sym {
- for i := range t.Syms {
- s := &t.Syms[i]
- switch s.Type {
- case 'T', 't', 'L', 'l', 'D', 'd', 'B', 'b':
- if s.Value == addr {
- return s
- }
- }
- }
- return nil
-}
-
-/*
- * Object files
- */
-
-// This is legacy code for Go 1.1 and earlier, which used the
-// Plan 9 format for pc-line tables. This code was never quite
-// correct. It's probably very close, and it's usually correct, but
-// we never quite found all the corner cases.
-//
-// Go 1.2 and later use a simpler format, documented at golang.org/s/go12symtab.
-
-func (o *Obj) lineFromAline(aline int) (string, int) {
- type stackEnt struct {
- path string
- start int
- offset int
- prev *stackEnt
- }
-
- noPath := &stackEnt{"", 0, 0, nil}
- tos := noPath
-
-pathloop:
- for _, s := range o.Paths {
- val := int(s.Value)
- switch {
- case val > aline:
- break pathloop
-
- case val == 1:
- // Start a new stack
- tos = &stackEnt{s.Name, val, 0, noPath}
-
- case s.Name == "":
- // Pop
- if tos == noPath {
- return "<malformed symbol table>", 0
- }
- tos.prev.offset += val - tos.start
- tos = tos.prev
-
- default:
- // Push
- tos = &stackEnt{s.Name, val, 0, tos}
- }
- }
-
- if tos == noPath {
- return "", 0
- }
- return tos.path, aline - tos.start - tos.offset + 1
-}
-
-func (o *Obj) alineFromLine(path string, line int) (int, error) {
- if line < 1 {
- return 0, &UnknownLineError{path, line}
- }
-
- for i, s := range o.Paths {
- // Find this path
- if s.Name != path {
- continue
- }
-
- // Find this line at this stack level
- depth := 0
- var incstart int
- line += int(s.Value)
- pathloop:
- for _, s := range o.Paths[i:] {
- val := int(s.Value)
- switch {
- case depth == 1 && val >= line:
- return line - 1, nil
-
- case s.Name == "":
- depth--
- if depth == 0 {
- break pathloop
- } else if depth == 1 {
- line += val - incstart
- }
-
- default:
- if depth == 1 {
- incstart = val
- }
- depth++
- }
- }
- return 0, &UnknownLineError{path, line}
- }
- return 0, UnknownFileError(path)
-}
-
-/*
- * Errors
- */
-
-// UnknownFileError represents a failure to find the specific file in
-// the symbol table.
-type UnknownFileError string
-
-func (e UnknownFileError) Error() string { return "unknown file: " + string(e) }
-
-// UnknownLineError represents a failure to map a line to a program
-// counter, either because the line is beyond the bounds of the file
-// or because there is no code on the given line.
-type UnknownLineError struct {
- File string
- Line int
-}
-
-func (e *UnknownLineError) Error() string {
- return "no code at " + e.File + ":" + strconv.Itoa(e.Line)
-}
-
-// DecodingError represents an error during the decoding of
-// the symbol table.
-type DecodingError struct {
- off int
- msg string
- val interface{}
-}
-
-func (e *DecodingError) Error() string {
- msg := e.msg
- if e.val != nil {
- msg += fmt.Sprintf(" '%v'", e.val)
- }
- msg += fmt.Sprintf(" at byte %#x", e.off)
- return msg
-}
diff --git a/src/pkg/debug/macho/fat.go b/src/pkg/debug/macho/fat.go
deleted file mode 100644
index 93b831526..000000000
--- a/src/pkg/debug/macho/fat.go
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2014 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 macho
-
-import (
- "encoding/binary"
- "fmt"
- "io"
- "os"
-)
-
-// A FatFile is a Mach-O universal binary that contains at least one architecture.
-type FatFile struct {
- Magic uint32
- Arches []FatArch
- closer io.Closer
-}
-
-// A FatArchHeader represents a fat header for a specific image architecture.
-type FatArchHeader struct {
- Cpu Cpu
- SubCpu uint32
- Offset uint32
- Size uint32
- Align uint32
-}
-
-const fatArchHeaderSize = 5 * 4
-
-// A FatArch is a Mach-O File inside a FatFile.
-type FatArch struct {
- FatArchHeader
- *File
-}
-
-// ErrNotFat is returned from NewFatFile or OpenFat when the file is not a
-// universal binary but may be a thin binary, based on its magic number.
-var ErrNotFat = &FormatError{0, "not a fat Mach-O file", nil}
-
-// NewFatFile creates a new FatFile for accessing all the Mach-O images in a
-// universal binary. The Mach-O binary is expected to start at position 0 in
-// the ReaderAt.
-func NewFatFile(r io.ReaderAt) (*FatFile, error) {
- var ff FatFile
- sr := io.NewSectionReader(r, 0, 1<<63-1)
-
- // Read the fat_header struct, which is always in big endian.
- // Start with the magic number.
- err := binary.Read(sr, binary.BigEndian, &ff.Magic)
- if err != nil {
- return nil, &FormatError{0, "error reading magic number", nil}
- } else if ff.Magic != MagicFat {
- // See if this is a Mach-O file via its magic number. The magic
- // must be converted to little endian first though.
- var buf [4]byte
- binary.BigEndian.PutUint32(buf[:], ff.Magic)
- leMagic := binary.LittleEndian.Uint32(buf[:])
- if leMagic == Magic32 || leMagic == Magic64 {
- return nil, ErrNotFat
- } else {
- return nil, &FormatError{0, "invalid magic number", nil}
- }
- }
- offset := int64(4)
-
- // Read the number of FatArchHeaders that come after the fat_header.
- var narch uint32
- err = binary.Read(sr, binary.BigEndian, &narch)
- if err != nil {
- return nil, &FormatError{offset, "invalid fat_header", nil}
- }
- offset += 4
-
- if narch < 1 {
- return nil, &FormatError{offset, "file contains no images", nil}
- }
-
- // Combine the Cpu and SubCpu (both uint32) into a uint64 to make sure
- // there are not duplicate architectures.
- seenArches := make(map[uint64]bool, narch)
- // Make sure that all images are for the same MH_ type.
- var machoType Type
-
- // Following the fat_header comes narch fat_arch structs that index
- // Mach-O images further in the file.
- ff.Arches = make([]FatArch, narch)
- for i := uint32(0); i < narch; i++ {
- fa := &ff.Arches[i]
- err = binary.Read(sr, binary.BigEndian, &fa.FatArchHeader)
- if err != nil {
- return nil, &FormatError{offset, "invalid fat_arch header", nil}
- }
- offset += fatArchHeaderSize
-
- fr := io.NewSectionReader(r, int64(fa.Offset), int64(fa.Size))
- fa.File, err = NewFile(fr)
- if err != nil {
- return nil, err
- }
-
- // Make sure the architecture for this image is not duplicate.
- seenArch := (uint64(fa.Cpu) << 32) | uint64(fa.SubCpu)
- if o, k := seenArches[seenArch]; o || k {
- return nil, &FormatError{offset, fmt.Sprintf("duplicate architecture cpu=%v, subcpu=%#x", fa.Cpu, fa.SubCpu), nil}
- }
- seenArches[seenArch] = true
-
- // Make sure the Mach-O type matches that of the first image.
- if i == 0 {
- machoType = fa.Type
- } else {
- if fa.Type != machoType {
- return nil, &FormatError{offset, fmt.Sprintf("Mach-O type for architecture #%d (type=%#x) does not match first (type=%#x)", i, fa.Type, machoType), nil}
- }
- }
- }
-
- return &ff, nil
-}
-
-// OpenFat opens the named file using os.Open and prepares it for use as a Mach-O
-// universal binary.
-func OpenFat(name string) (ff *FatFile, err error) {
- f, err := os.Open(name)
- if err != nil {
- return nil, err
- }
- ff, err = NewFatFile(f)
- if err != nil {
- f.Close()
- return nil, err
- }
- ff.closer = f
- return
-}
-
-func (ff *FatFile) Close() error {
- var err error
- if ff.closer != nil {
- err = ff.closer.Close()
- ff.closer = nil
- }
- return err
-}
diff --git a/src/pkg/debug/macho/file.go b/src/pkg/debug/macho/file.go
deleted file mode 100644
index eefb74444..000000000
--- a/src/pkg/debug/macho/file.go
+++ /dev/null
@@ -1,524 +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 macho implements access to Mach-O object files.
-package macho
-
-// High level access to low level data structures.
-
-import (
- "bytes"
- "debug/dwarf"
- "encoding/binary"
- "fmt"
- "io"
- "os"
-)
-
-// A File represents an open Mach-O file.
-type File struct {
- FileHeader
- ByteOrder binary.ByteOrder
- Loads []Load
- Sections []*Section
-
- Symtab *Symtab
- Dysymtab *Dysymtab
-
- closer io.Closer
-}
-
-// A Load represents any Mach-O load command.
-type Load interface {
- Raw() []byte
-}
-
-// A LoadBytes is the uninterpreted bytes of a Mach-O load command.
-type LoadBytes []byte
-
-func (b LoadBytes) Raw() []byte { return b }
-
-// A SegmentHeader is the header for a Mach-O 32-bit or 64-bit load segment command.
-type SegmentHeader struct {
- Cmd LoadCmd
- Len uint32
- Name string
- Addr uint64
- Memsz uint64
- Offset uint64
- Filesz uint64
- Maxprot uint32
- Prot uint32
- Nsect uint32
- Flag uint32
-}
-
-// A Segment represents a Mach-O 32-bit or 64-bit load segment command.
-type Segment struct {
- LoadBytes
- SegmentHeader
-
- // Embed ReaderAt for ReadAt method.
- // Do not embed SectionReader directly
- // to avoid having Read and Seek.
- // If a client wants Read and Seek it must use
- // Open() to avoid fighting over the seek offset
- // with other clients.
- io.ReaderAt
- sr *io.SectionReader
-}
-
-// Data reads and returns the contents of the segment.
-func (s *Segment) Data() ([]byte, error) {
- dat := make([]byte, s.sr.Size())
- n, err := s.sr.ReadAt(dat, 0)
- if n == len(dat) {
- err = nil
- }
- return dat[0:n], err
-}
-
-// Open returns a new ReadSeeker reading the segment.
-func (s *Segment) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
-
-type SectionHeader struct {
- Name string
- Seg string
- Addr uint64
- Size uint64
- Offset uint32
- Align uint32
- Reloff uint32
- Nreloc uint32
- Flags uint32
-}
-
-type Section struct {
- SectionHeader
-
- // Embed ReaderAt for ReadAt method.
- // Do not embed SectionReader directly
- // to avoid having Read and Seek.
- // If a client wants Read and Seek it must use
- // Open() to avoid fighting over the seek offset
- // with other clients.
- io.ReaderAt
- sr *io.SectionReader
-}
-
-// Data reads and returns the contents of the Mach-O section.
-func (s *Section) Data() ([]byte, error) {
- dat := make([]byte, s.sr.Size())
- n, err := s.sr.ReadAt(dat, 0)
- if n == len(dat) {
- err = nil
- }
- return dat[0:n], err
-}
-
-// Open returns a new ReadSeeker reading the Mach-O section.
-func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
-
-// A Dylib represents a Mach-O load dynamic library command.
-type Dylib struct {
- LoadBytes
- Name string
- Time uint32
- CurrentVersion uint32
- CompatVersion uint32
-}
-
-// A Symtab represents a Mach-O symbol table command.
-type Symtab struct {
- LoadBytes
- SymtabCmd
- Syms []Symbol
-}
-
-// A Dysymtab represents a Mach-O dynamic symbol table command.
-type Dysymtab struct {
- LoadBytes
- DysymtabCmd
- IndirectSyms []uint32 // indices into Symtab.Syms
-}
-
-/*
- * Mach-O reader
- */
-
-// FormatError is returned by some operations if the data does
-// not have the correct format for an object file.
-type FormatError struct {
- off int64
- msg string
- val interface{}
-}
-
-func (e *FormatError) Error() string {
- msg := e.msg
- if e.val != nil {
- msg += fmt.Sprintf(" '%v'", e.val)
- }
- msg += fmt.Sprintf(" in record at byte %#x", e.off)
- return msg
-}
-
-// Open opens the named file using os.Open and prepares it for use as a Mach-O binary.
-func Open(name string) (*File, error) {
- f, err := os.Open(name)
- if err != nil {
- return nil, err
- }
- ff, err := NewFile(f)
- if err != nil {
- f.Close()
- return nil, err
- }
- ff.closer = f
- return ff, nil
-}
-
-// Close closes the File.
-// If the File was created using NewFile directly instead of Open,
-// Close has no effect.
-func (f *File) Close() error {
- var err error
- if f.closer != nil {
- err = f.closer.Close()
- f.closer = nil
- }
- return err
-}
-
-// NewFile creates a new File for accessing a Mach-O binary in an underlying reader.
-// The Mach-O binary is expected to start at position 0 in the ReaderAt.
-func NewFile(r io.ReaderAt) (*File, error) {
- f := new(File)
- sr := io.NewSectionReader(r, 0, 1<<63-1)
-
- // Read and decode Mach magic to determine byte order, size.
- // Magic32 and Magic64 differ only in the bottom bit.
- var ident [4]byte
- if _, err := r.ReadAt(ident[0:], 0); err != nil {
- return nil, err
- }
- be := binary.BigEndian.Uint32(ident[0:])
- le := binary.LittleEndian.Uint32(ident[0:])
- switch Magic32 &^ 1 {
- case be &^ 1:
- f.ByteOrder = binary.BigEndian
- f.Magic = be
- case le &^ 1:
- f.ByteOrder = binary.LittleEndian
- f.Magic = le
- default:
- return nil, &FormatError{0, "invalid magic number", nil}
- }
-
- // Read entire file header.
- if err := binary.Read(sr, f.ByteOrder, &f.FileHeader); err != nil {
- return nil, err
- }
-
- // Then load commands.
- offset := int64(fileHeaderSize32)
- if f.Magic == Magic64 {
- offset = fileHeaderSize64
- }
- dat := make([]byte, f.Cmdsz)
- if _, err := r.ReadAt(dat, offset); err != nil {
- return nil, err
- }
- f.Loads = make([]Load, f.Ncmd)
- bo := f.ByteOrder
- for i := range f.Loads {
- // Each load command begins with uint32 command and length.
- if len(dat) < 8 {
- return nil, &FormatError{offset, "command block too small", nil}
- }
- cmd, siz := LoadCmd(bo.Uint32(dat[0:4])), bo.Uint32(dat[4:8])
- if siz < 8 || siz > uint32(len(dat)) {
- return nil, &FormatError{offset, "invalid command block size", nil}
- }
- var cmddat []byte
- cmddat, dat = dat[0:siz], dat[siz:]
- offset += int64(siz)
- var s *Segment
- switch cmd {
- default:
- f.Loads[i] = LoadBytes(cmddat)
-
- case LoadCmdDylib:
- var hdr DylibCmd
- b := bytes.NewReader(cmddat)
- if err := binary.Read(b, bo, &hdr); err != nil {
- return nil, err
- }
- l := new(Dylib)
- if hdr.Name >= uint32(len(cmddat)) {
- return nil, &FormatError{offset, "invalid name in dynamic library command", hdr.Name}
- }
- l.Name = cstring(cmddat[hdr.Name:])
- l.Time = hdr.Time
- l.CurrentVersion = hdr.CurrentVersion
- l.CompatVersion = hdr.CompatVersion
- l.LoadBytes = LoadBytes(cmddat)
- f.Loads[i] = l
-
- case LoadCmdSymtab:
- var hdr SymtabCmd
- b := bytes.NewReader(cmddat)
- if err := binary.Read(b, bo, &hdr); err != nil {
- return nil, err
- }
- strtab := make([]byte, hdr.Strsize)
- if _, err := r.ReadAt(strtab, int64(hdr.Stroff)); err != nil {
- return nil, err
- }
- var symsz int
- if f.Magic == Magic64 {
- symsz = 16
- } else {
- symsz = 12
- }
- symdat := make([]byte, int(hdr.Nsyms)*symsz)
- if _, err := r.ReadAt(symdat, int64(hdr.Symoff)); err != nil {
- return nil, err
- }
- st, err := f.parseSymtab(symdat, strtab, cmddat, &hdr, offset)
- if err != nil {
- return nil, err
- }
- f.Loads[i] = st
- f.Symtab = st
-
- case LoadCmdDysymtab:
- var hdr DysymtabCmd
- b := bytes.NewReader(cmddat)
- if err := binary.Read(b, bo, &hdr); err != nil {
- return nil, err
- }
- dat := make([]byte, hdr.Nindirectsyms*4)
- if _, err := r.ReadAt(dat, int64(hdr.Indirectsymoff)); err != nil {
- return nil, err
- }
- x := make([]uint32, hdr.Nindirectsyms)
- if err := binary.Read(bytes.NewReader(dat), bo, x); err != nil {
- return nil, err
- }
- st := new(Dysymtab)
- st.LoadBytes = LoadBytes(cmddat)
- st.DysymtabCmd = hdr
- st.IndirectSyms = x
- f.Loads[i] = st
- f.Dysymtab = st
-
- case LoadCmdSegment:
- var seg32 Segment32
- b := bytes.NewReader(cmddat)
- if err := binary.Read(b, bo, &seg32); err != nil {
- return nil, err
- }
- s = new(Segment)
- s.LoadBytes = cmddat
- s.Cmd = cmd
- s.Len = siz
- s.Name = cstring(seg32.Name[0:])
- s.Addr = uint64(seg32.Addr)
- s.Memsz = uint64(seg32.Memsz)
- s.Offset = uint64(seg32.Offset)
- s.Filesz = uint64(seg32.Filesz)
- s.Maxprot = seg32.Maxprot
- s.Prot = seg32.Prot
- s.Nsect = seg32.Nsect
- s.Flag = seg32.Flag
- f.Loads[i] = s
- for i := 0; i < int(s.Nsect); i++ {
- var sh32 Section32
- if err := binary.Read(b, bo, &sh32); err != nil {
- return nil, err
- }
- sh := new(Section)
- sh.Name = cstring(sh32.Name[0:])
- sh.Seg = cstring(sh32.Seg[0:])
- sh.Addr = uint64(sh32.Addr)
- sh.Size = uint64(sh32.Size)
- sh.Offset = sh32.Offset
- sh.Align = sh32.Align
- sh.Reloff = sh32.Reloff
- sh.Nreloc = sh32.Nreloc
- sh.Flags = sh32.Flags
- f.pushSection(sh, r)
- }
-
- case LoadCmdSegment64:
- var seg64 Segment64
- b := bytes.NewReader(cmddat)
- if err := binary.Read(b, bo, &seg64); err != nil {
- return nil, err
- }
- s = new(Segment)
- s.LoadBytes = cmddat
- s.Cmd = cmd
- s.Len = siz
- s.Name = cstring(seg64.Name[0:])
- s.Addr = seg64.Addr
- s.Memsz = seg64.Memsz
- s.Offset = seg64.Offset
- s.Filesz = seg64.Filesz
- s.Maxprot = seg64.Maxprot
- s.Prot = seg64.Prot
- s.Nsect = seg64.Nsect
- s.Flag = seg64.Flag
- f.Loads[i] = s
- for i := 0; i < int(s.Nsect); i++ {
- var sh64 Section64
- if err := binary.Read(b, bo, &sh64); err != nil {
- return nil, err
- }
- sh := new(Section)
- sh.Name = cstring(sh64.Name[0:])
- sh.Seg = cstring(sh64.Seg[0:])
- sh.Addr = sh64.Addr
- sh.Size = sh64.Size
- sh.Offset = sh64.Offset
- sh.Align = sh64.Align
- sh.Reloff = sh64.Reloff
- sh.Nreloc = sh64.Nreloc
- sh.Flags = sh64.Flags
- f.pushSection(sh, r)
- }
- }
- if s != nil {
- s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.Filesz))
- s.ReaderAt = s.sr
- }
- }
- return f, nil
-}
-
-func (f *File) parseSymtab(symdat, strtab, cmddat []byte, hdr *SymtabCmd, offset int64) (*Symtab, error) {
- bo := f.ByteOrder
- symtab := make([]Symbol, hdr.Nsyms)
- b := bytes.NewReader(symdat)
- for i := range symtab {
- var n Nlist64
- if f.Magic == Magic64 {
- if err := binary.Read(b, bo, &n); err != nil {
- return nil, err
- }
- } else {
- var n32 Nlist32
- if err := binary.Read(b, bo, &n32); err != nil {
- return nil, err
- }
- n.Name = n32.Name
- n.Type = n32.Type
- n.Sect = n32.Sect
- n.Desc = n32.Desc
- n.Value = uint64(n32.Value)
- }
- sym := &symtab[i]
- if n.Name >= uint32(len(strtab)) {
- return nil, &FormatError{offset, "invalid name in symbol table", n.Name}
- }
- sym.Name = cstring(strtab[n.Name:])
- sym.Type = n.Type
- sym.Sect = n.Sect
- sym.Desc = n.Desc
- sym.Value = n.Value
- }
- st := new(Symtab)
- st.LoadBytes = LoadBytes(cmddat)
- st.Syms = symtab
- return st, nil
-}
-
-func (f *File) pushSection(sh *Section, r io.ReaderAt) {
- f.Sections = append(f.Sections, sh)
- sh.sr = io.NewSectionReader(r, int64(sh.Offset), int64(sh.Size))
- sh.ReaderAt = sh.sr
-}
-
-func cstring(b []byte) string {
- var i int
- for i = 0; i < len(b) && b[i] != 0; i++ {
- }
- return string(b[0:i])
-}
-
-// Segment returns the first Segment with the given name, or nil if no such segment exists.
-func (f *File) Segment(name string) *Segment {
- for _, l := range f.Loads {
- if s, ok := l.(*Segment); ok && s.Name == name {
- return s
- }
- }
- return nil
-}
-
-// Section returns the first section with the given name, or nil if no such
-// section exists.
-func (f *File) Section(name string) *Section {
- for _, s := range f.Sections {
- if s.Name == name {
- return s
- }
- }
- return nil
-}
-
-// DWARF returns the DWARF debug information for the Mach-O file.
-func (f *File) DWARF() (*dwarf.Data, error) {
- // There are many other DWARF sections, but these
- // are the required ones, and the debug/dwarf package
- // does not use the others, so don't bother loading them.
- var names = [...]string{"abbrev", "info", "str"}
- var dat [len(names)][]byte
- for i, name := range names {
- name = "__debug_" + name
- s := f.Section(name)
- if s == nil {
- continue
- }
- b, err := s.Data()
- if err != nil && uint64(len(b)) < s.Size {
- return nil, err
- }
- dat[i] = b
- }
-
- abbrev, info, str := dat[0], dat[1], dat[2]
- return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str)
-}
-
-// ImportedSymbols returns the names of all symbols
-// referred to by the binary f that are expected to be
-// satisfied by other libraries at dynamic load time.
-func (f *File) ImportedSymbols() ([]string, error) {
- if f.Dysymtab == nil || f.Symtab == nil {
- return nil, &FormatError{0, "missing symbol table", nil}
- }
-
- st := f.Symtab
- dt := f.Dysymtab
- var all []string
- for _, s := range st.Syms[dt.Iundefsym : dt.Iundefsym+dt.Nundefsym] {
- all = append(all, s.Name)
- }
- return all, nil
-}
-
-// ImportedLibraries returns the paths of all libraries
-// referred to by the binary f that are expected to be
-// linked with the binary at dynamic link time.
-func (f *File) ImportedLibraries() ([]string, error) {
- var all []string
- for _, l := range f.Loads {
- if lib, ok := l.(*Dylib); ok {
- all = append(all, lib.Name)
- }
- }
- return all, nil
-}
diff --git a/src/pkg/debug/macho/file_test.go b/src/pkg/debug/macho/file_test.go
deleted file mode 100644
index 4797780ce..000000000
--- a/src/pkg/debug/macho/file_test.go
+++ /dev/null
@@ -1,210 +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 macho
-
-import (
- "reflect"
- "testing"
-)
-
-type fileTest struct {
- file string
- hdr FileHeader
- segments []*SegmentHeader
- sections []*SectionHeader
-}
-
-var fileTests = []fileTest{
- {
- "testdata/gcc-386-darwin-exec",
- FileHeader{0xfeedface, Cpu386, 0x3, 0x2, 0xc, 0x3c0, 0x85},
- []*SegmentHeader{
- {LoadCmdSegment, 0x38, "__PAGEZERO", 0x0, 0x1000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
- {LoadCmdSegment, 0xc0, "__TEXT", 0x1000, 0x1000, 0x0, 0x1000, 0x7, 0x5, 0x2, 0x0},
- {LoadCmdSegment, 0xc0, "__DATA", 0x2000, 0x1000, 0x1000, 0x1000, 0x7, 0x3, 0x2, 0x0},
- {LoadCmdSegment, 0x7c, "__IMPORT", 0x3000, 0x1000, 0x2000, 0x1000, 0x7, 0x7, 0x1, 0x0},
- {LoadCmdSegment, 0x38, "__LINKEDIT", 0x4000, 0x1000, 0x3000, 0x12c, 0x7, 0x1, 0x0, 0x0},
- nil,
- nil,
- nil,
- nil,
- nil,
- nil,
- nil,
- },
- []*SectionHeader{
- {"__text", "__TEXT", 0x1f68, 0x88, 0xf68, 0x2, 0x0, 0x0, 0x80000400},
- {"__cstring", "__TEXT", 0x1ff0, 0xd, 0xff0, 0x0, 0x0, 0x0, 0x2},
- {"__data", "__DATA", 0x2000, 0x14, 0x1000, 0x2, 0x0, 0x0, 0x0},
- {"__dyld", "__DATA", 0x2014, 0x1c, 0x1014, 0x2, 0x0, 0x0, 0x0},
- {"__jump_table", "__IMPORT", 0x3000, 0xa, 0x2000, 0x6, 0x0, 0x0, 0x4000008},
- },
- },
- {
- "testdata/gcc-amd64-darwin-exec",
- FileHeader{0xfeedfacf, CpuAmd64, 0x80000003, 0x2, 0xb, 0x568, 0x85},
- []*SegmentHeader{
- {LoadCmdSegment64, 0x48, "__PAGEZERO", 0x0, 0x100000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
- {LoadCmdSegment64, 0x1d8, "__TEXT", 0x100000000, 0x1000, 0x0, 0x1000, 0x7, 0x5, 0x5, 0x0},
- {LoadCmdSegment64, 0x138, "__DATA", 0x100001000, 0x1000, 0x1000, 0x1000, 0x7, 0x3, 0x3, 0x0},
- {LoadCmdSegment64, 0x48, "__LINKEDIT", 0x100002000, 0x1000, 0x2000, 0x140, 0x7, 0x1, 0x0, 0x0},
- nil,
- nil,
- nil,
- nil,
- nil,
- nil,
- nil,
- },
- []*SectionHeader{
- {"__text", "__TEXT", 0x100000f14, 0x6d, 0xf14, 0x2, 0x0, 0x0, 0x80000400},
- {"__symbol_stub1", "__TEXT", 0x100000f81, 0xc, 0xf81, 0x0, 0x0, 0x0, 0x80000408},
- {"__stub_helper", "__TEXT", 0x100000f90, 0x18, 0xf90, 0x2, 0x0, 0x0, 0x0},
- {"__cstring", "__TEXT", 0x100000fa8, 0xd, 0xfa8, 0x0, 0x0, 0x0, 0x2},
- {"__eh_frame", "__TEXT", 0x100000fb8, 0x48, 0xfb8, 0x3, 0x0, 0x0, 0x6000000b},
- {"__data", "__DATA", 0x100001000, 0x1c, 0x1000, 0x3, 0x0, 0x0, 0x0},
- {"__dyld", "__DATA", 0x100001020, 0x38, 0x1020, 0x3, 0x0, 0x0, 0x0},
- {"__la_symbol_ptr", "__DATA", 0x100001058, 0x10, 0x1058, 0x2, 0x0, 0x0, 0x7},
- },
- },
- {
- "testdata/gcc-amd64-darwin-exec-debug",
- FileHeader{0xfeedfacf, CpuAmd64, 0x80000003, 0xa, 0x4, 0x5a0, 0},
- []*SegmentHeader{
- nil,
- {LoadCmdSegment64, 0x1d8, "__TEXT", 0x100000000, 0x1000, 0x0, 0x0, 0x7, 0x5, 0x5, 0x0},
- {LoadCmdSegment64, 0x138, "__DATA", 0x100001000, 0x1000, 0x0, 0x0, 0x7, 0x3, 0x3, 0x0},
- {LoadCmdSegment64, 0x278, "__DWARF", 0x100002000, 0x1000, 0x1000, 0x1bc, 0x7, 0x3, 0x7, 0x0},
- },
- []*SectionHeader{
- {"__text", "__TEXT", 0x100000f14, 0x0, 0x0, 0x2, 0x0, 0x0, 0x80000400},
- {"__symbol_stub1", "__TEXT", 0x100000f81, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000408},
- {"__stub_helper", "__TEXT", 0x100000f90, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0},
- {"__cstring", "__TEXT", 0x100000fa8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2},
- {"__eh_frame", "__TEXT", 0x100000fb8, 0x0, 0x0, 0x3, 0x0, 0x0, 0x6000000b},
- {"__data", "__DATA", 0x100001000, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0},
- {"__dyld", "__DATA", 0x100001020, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0},
- {"__la_symbol_ptr", "__DATA", 0x100001058, 0x0, 0x0, 0x2, 0x0, 0x0, 0x7},
- {"__debug_abbrev", "__DWARF", 0x100002000, 0x36, 0x1000, 0x0, 0x0, 0x0, 0x0},
- {"__debug_aranges", "__DWARF", 0x100002036, 0x30, 0x1036, 0x0, 0x0, 0x0, 0x0},
- {"__debug_frame", "__DWARF", 0x100002066, 0x40, 0x1066, 0x0, 0x0, 0x0, 0x0},
- {"__debug_info", "__DWARF", 0x1000020a6, 0x54, 0x10a6, 0x0, 0x0, 0x0, 0x0},
- {"__debug_line", "__DWARF", 0x1000020fa, 0x47, 0x10fa, 0x0, 0x0, 0x0, 0x0},
- {"__debug_pubnames", "__DWARF", 0x100002141, 0x1b, 0x1141, 0x0, 0x0, 0x0, 0x0},
- {"__debug_str", "__DWARF", 0x10000215c, 0x60, 0x115c, 0x0, 0x0, 0x0, 0x0},
- },
- },
-}
-
-func TestOpen(t *testing.T) {
- for i := range fileTests {
- tt := &fileTests[i]
-
- f, err := Open(tt.file)
- if err != nil {
- t.Error(err)
- continue
- }
- if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
- t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)
- continue
- }
- for i, l := range f.Loads {
- if i >= len(tt.segments) {
- break
- }
- sh := tt.segments[i]
- s, ok := l.(*Segment)
- if sh == nil {
- if ok {
- t.Errorf("open %s, section %d: skipping %#v\n", tt.file, i, &s.SegmentHeader)
- }
- continue
- }
- if !ok {
- t.Errorf("open %s, section %d: not *Segment\n", tt.file, i)
- continue
- }
- have := &s.SegmentHeader
- want := sh
- if !reflect.DeepEqual(have, want) {
- t.Errorf("open %s, segment %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
- }
- }
- tn := len(tt.segments)
- fn := len(f.Loads)
- if tn != fn {
- t.Errorf("open %s: len(Loads) = %d, want %d", tt.file, fn, tn)
- }
-
- for i, sh := range f.Sections {
- if i >= len(tt.sections) {
- break
- }
- have := &sh.SectionHeader
- want := tt.sections[i]
- if !reflect.DeepEqual(have, want) {
- t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
- }
- }
- tn = len(tt.sections)
- fn = len(f.Sections)
- if tn != fn {
- t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
- }
-
- }
-}
-
-func TestOpenFailure(t *testing.T) {
- filename := "file.go" // not a Mach-O file
- _, err := Open(filename) // don't crash
- if err == nil {
- t.Errorf("open %s: succeeded unexpectedly", filename)
- }
-}
-
-func TestOpenFat(t *testing.T) {
- ff, err := OpenFat("testdata/fat-gcc-386-amd64-darwin-exec")
- if err != nil {
- t.Fatal(err)
- }
-
- if ff.Magic != MagicFat {
- t.Errorf("OpenFat: got magic number %#x, want %#x", ff.Magic, MagicFat)
- }
- if len(ff.Arches) != 2 {
- t.Errorf("OpenFat: got %d architectures, want 2", len(ff.Arches))
- }
-
- for i := range ff.Arches {
- arch := &ff.Arches[i]
- ftArch := &fileTests[i]
-
- if arch.Cpu != ftArch.hdr.Cpu || arch.SubCpu != ftArch.hdr.SubCpu {
- t.Errorf("OpenFat: architecture #%d got cpu=%#x subtype=%#x, expected cpu=%#x, subtype=%#x", i, arch.Cpu, arch.SubCpu, ftArch.hdr.Cpu, ftArch.hdr.SubCpu)
- }
-
- if !reflect.DeepEqual(arch.FileHeader, ftArch.hdr) {
- t.Errorf("OpenFat header:\n\tgot %#v\n\twant %#v\n", arch.FileHeader, ftArch.hdr)
- }
- }
-}
-
-func TestOpenFatFailure(t *testing.T) {
- filename := "file.go" // not a Mach-O file
- if _, err := OpenFat(filename); err == nil {
- t.Errorf("OpenFat %s: succeeded unexpectedly", filename)
- }
-
- filename = "testdata/gcc-386-darwin-exec" // not a fat Mach-O
- ff, err := OpenFat(filename)
- if err != ErrNotFat {
- t.Errorf("OpenFat %s: got %v, want ErrNotFat", filename, err)
- }
- if ff != nil {
- t.Errorf("OpenFat %s: got %v, want nil", filename, ff)
- }
-}
diff --git a/src/pkg/debug/macho/macho.go b/src/pkg/debug/macho/macho.go
deleted file mode 100644
index d9678c8ed..000000000
--- a/src/pkg/debug/macho/macho.go
+++ /dev/null
@@ -1,316 +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.
-
-// Mach-O header data structures
-// http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html
-
-package macho
-
-import "strconv"
-
-// A FileHeader represents a Mach-O file header.
-type FileHeader struct {
- Magic uint32
- Cpu Cpu
- SubCpu uint32
- Type Type
- Ncmd uint32
- Cmdsz uint32
- Flags uint32
-}
-
-const (
- fileHeaderSize32 = 7 * 4
- fileHeaderSize64 = 8 * 4
-)
-
-const (
- Magic32 uint32 = 0xfeedface
- Magic64 uint32 = 0xfeedfacf
- MagicFat uint32 = 0xcafebabe
-)
-
-// A Type is the Mach-O file type, e.g. an object file, executable, or dynamic library.
-type Type uint32
-
-const (
- TypeObj Type = 1
- TypeExec Type = 2
- TypeDylib Type = 6
- TypeBundle Type = 8
-)
-
-// A Cpu is a Mach-O cpu type.
-type Cpu uint32
-
-const cpuArch64 = 0x01000000
-
-const (
- Cpu386 Cpu = 7
- CpuAmd64 Cpu = Cpu386 | cpuArch64
- CpuArm Cpu = 12
- CpuPpc Cpu = 18
- CpuPpc64 Cpu = CpuPpc | cpuArch64
-)
-
-var cpuStrings = []intName{
- {uint32(Cpu386), "Cpu386"},
- {uint32(CpuAmd64), "CpuAmd64"},
- {uint32(CpuArm), "CpuArm"},
- {uint32(CpuPpc), "CpuPpc"},
- {uint32(CpuPpc64), "CpuPpc64"},
-}
-
-func (i Cpu) String() string { return stringName(uint32(i), cpuStrings, false) }
-func (i Cpu) GoString() string { return stringName(uint32(i), cpuStrings, true) }
-
-// A LoadCmd is a Mach-O load command.
-type LoadCmd uint32
-
-const (
- LoadCmdSegment LoadCmd = 1
- LoadCmdSymtab LoadCmd = 2
- LoadCmdThread LoadCmd = 4
- LoadCmdUnixThread LoadCmd = 5 // thread+stack
- LoadCmdDysymtab LoadCmd = 11
- LoadCmdDylib LoadCmd = 12
- LoadCmdDylinker LoadCmd = 15
- LoadCmdSegment64 LoadCmd = 25
-)
-
-var cmdStrings = []intName{
- {uint32(LoadCmdSegment), "LoadCmdSegment"},
- {uint32(LoadCmdThread), "LoadCmdThread"},
- {uint32(LoadCmdUnixThread), "LoadCmdUnixThread"},
- {uint32(LoadCmdDylib), "LoadCmdDylib"},
- {uint32(LoadCmdSegment64), "LoadCmdSegment64"},
-}
-
-func (i LoadCmd) String() string { return stringName(uint32(i), cmdStrings, false) }
-func (i LoadCmd) GoString() string { return stringName(uint32(i), cmdStrings, true) }
-
-// A Segment64 is a 64-bit Mach-O segment load command.
-type Segment64 struct {
- Cmd LoadCmd
- Len uint32
- Name [16]byte
- Addr uint64
- Memsz uint64
- Offset uint64
- Filesz uint64
- Maxprot uint32
- Prot uint32
- Nsect uint32
- Flag uint32
-}
-
-// A Segment32 is a 32-bit Mach-O segment load command.
-type Segment32 struct {
- Cmd LoadCmd
- Len uint32
- Name [16]byte
- Addr uint32
- Memsz uint32
- Offset uint32
- Filesz uint32
- Maxprot uint32
- Prot uint32
- Nsect uint32
- Flag uint32
-}
-
-// A DylibCmd is a Mach-O load dynamic library command.
-type DylibCmd struct {
- Cmd LoadCmd
- Len uint32
- Name uint32
- Time uint32
- CurrentVersion uint32
- CompatVersion uint32
-}
-
-// A Section32 is a 32-bit Mach-O section header.
-type Section32 struct {
- Name [16]byte
- Seg [16]byte
- Addr uint32
- Size uint32
- Offset uint32
- Align uint32
- Reloff uint32
- Nreloc uint32
- Flags uint32
- Reserve1 uint32
- Reserve2 uint32
-}
-
-// A Section32 is a 64-bit Mach-O section header.
-type Section64 struct {
- Name [16]byte
- Seg [16]byte
- Addr uint64
- Size uint64
- Offset uint32
- Align uint32
- Reloff uint32
- Nreloc uint32
- Flags uint32
- Reserve1 uint32
- Reserve2 uint32
- Reserve3 uint32
-}
-
-// A SymtabCmd is a Mach-O symbol table command.
-type SymtabCmd struct {
- Cmd LoadCmd
- Len uint32
- Symoff uint32
- Nsyms uint32
- Stroff uint32
- Strsize uint32
-}
-
-// A DysymtabCmd is a Mach-O dynamic symbol table command.
-type DysymtabCmd struct {
- Cmd LoadCmd
- Len uint32
- Ilocalsym uint32
- Nlocalsym uint32
- Iextdefsym uint32
- Nextdefsym uint32
- Iundefsym uint32
- Nundefsym uint32
- Tocoffset uint32
- Ntoc uint32
- Modtaboff uint32
- Nmodtab uint32
- Extrefsymoff uint32
- Nextrefsyms uint32
- Indirectsymoff uint32
- Nindirectsyms uint32
- Extreloff uint32
- Nextrel uint32
- Locreloff uint32
- Nlocrel uint32
-}
-
-// An Nlist32 is a Mach-O 32-bit symbol table entry.
-type Nlist32 struct {
- Name uint32
- Type uint8
- Sect uint8
- Desc uint16
- Value uint32
-}
-
-// An Nlist64 is a Mach-O 64-bit symbol table entry.
-type Nlist64 struct {
- Name uint32
- Type uint8
- Sect uint8
- Desc uint16
- Value uint64
-}
-
-// A Symbol is a Mach-O 32-bit or 64-bit symbol table entry.
-type Symbol struct {
- Name string
- Type uint8
- Sect uint8
- Desc uint16
- Value uint64
-}
-
-// A Thread is a Mach-O thread state command.
-type Thread struct {
- Cmd LoadCmd
- Len uint32
- Type uint32
- Data []uint32
-}
-
-// Regs386 is the Mach-O 386 register structure.
-type Regs386 struct {
- AX uint32
- BX uint32
- CX uint32
- DX uint32
- DI uint32
- SI uint32
- BP uint32
- SP uint32
- SS uint32
- FLAGS uint32
- IP uint32
- CS uint32
- DS uint32
- ES uint32
- FS uint32
- GS uint32
-}
-
-// RegsAMD64 is the Mach-O AMD64 register structure.
-type RegsAMD64 struct {
- AX uint64
- BX uint64
- CX uint64
- DX uint64
- DI uint64
- SI uint64
- BP uint64
- SP uint64
- R8 uint64
- R9 uint64
- R10 uint64
- R11 uint64
- R12 uint64
- R13 uint64
- R14 uint64
- R15 uint64
- IP uint64
- FLAGS uint64
- CS uint64
- FS uint64
- GS uint64
-}
-
-type intName struct {
- i uint32
- s string
-}
-
-func stringName(i uint32, names []intName, goSyntax bool) string {
- for _, n := range names {
- if n.i == i {
- if goSyntax {
- return "macho." + n.s
- }
- return n.s
- }
- }
- return strconv.FormatUint(uint64(i), 10)
-}
-
-func flagName(i uint32, names []intName, goSyntax bool) string {
- s := ""
- for _, n := range names {
- if n.i&i == n.i {
- if len(s) > 0 {
- s += "+"
- }
- if goSyntax {
- s += "macho."
- }
- s += n.s
- i -= n.i
- }
- }
- if len(s) == 0 {
- return "0x" + strconv.FormatUint(uint64(i), 16)
- }
- if i != 0 {
- s += "+0x" + strconv.FormatUint(uint64(i), 16)
- }
- return s
-}
diff --git a/src/pkg/debug/macho/testdata/fat-gcc-386-amd64-darwin-exec b/src/pkg/debug/macho/testdata/fat-gcc-386-amd64-darwin-exec
deleted file mode 100644
index 7efd19300..000000000
--- a/src/pkg/debug/macho/testdata/fat-gcc-386-amd64-darwin-exec
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/macho/testdata/gcc-386-darwin-exec b/src/pkg/debug/macho/testdata/gcc-386-darwin-exec
deleted file mode 100755
index 03ba1bafa..000000000
--- a/src/pkg/debug/macho/testdata/gcc-386-darwin-exec
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/macho/testdata/gcc-amd64-darwin-exec b/src/pkg/debug/macho/testdata/gcc-amd64-darwin-exec
deleted file mode 100755
index 5155a5a26..000000000
--- a/src/pkg/debug/macho/testdata/gcc-amd64-darwin-exec
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/macho/testdata/gcc-amd64-darwin-exec-debug b/src/pkg/debug/macho/testdata/gcc-amd64-darwin-exec-debug
deleted file mode 100644
index a47d3aef7..000000000
--- a/src/pkg/debug/macho/testdata/gcc-amd64-darwin-exec-debug
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/macho/testdata/hello.c b/src/pkg/debug/macho/testdata/hello.c
deleted file mode 100644
index a689d3644..000000000
--- a/src/pkg/debug/macho/testdata/hello.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <stdio.h>
-
-int
-main(void)
-{
- printf("hello, world\n");
- return 0;
-}
diff --git a/src/pkg/debug/pe/file.go b/src/pkg/debug/pe/file.go
deleted file mode 100644
index ce6f1408f..000000000
--- a/src/pkg/debug/pe/file.go
+++ /dev/null
@@ -1,390 +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 pe implements access to PE (Microsoft Windows Portable Executable) files.
-package pe
-
-import (
- "debug/dwarf"
- "encoding/binary"
- "errors"
- "fmt"
- "io"
- "os"
- "strconv"
- "unsafe"
-)
-
-// A File represents an open PE file.
-type File struct {
- FileHeader
- OptionalHeader interface{} // of type *OptionalHeader32 or *OptionalHeader64
- Sections []*Section
- Symbols []*Symbol
-
- closer io.Closer
-}
-
-type SectionHeader struct {
- Name string
- VirtualSize uint32
- VirtualAddress uint32
- Size uint32
- Offset uint32
- PointerToRelocations uint32
- PointerToLineNumbers uint32
- NumberOfRelocations uint16
- NumberOfLineNumbers uint16
- Characteristics uint32
-}
-
-type Section struct {
- SectionHeader
-
- // Embed ReaderAt for ReadAt method.
- // Do not embed SectionReader directly
- // to avoid having Read and Seek.
- // If a client wants Read and Seek it must use
- // Open() to avoid fighting over the seek offset
- // with other clients.
- io.ReaderAt
- sr *io.SectionReader
-}
-
-type Symbol struct {
- Name string
- Value uint32
- SectionNumber int16
- Type uint16
- StorageClass uint8
-}
-
-type ImportDirectory struct {
- OriginalFirstThunk uint32
- TimeDateStamp uint32
- ForwarderChain uint32
- Name uint32
- FirstThunk uint32
-
- dll string
-}
-
-// Data reads and returns the contents of the PE section.
-func (s *Section) Data() ([]byte, error) {
- dat := make([]byte, s.sr.Size())
- n, err := s.sr.ReadAt(dat, 0)
- if n == len(dat) {
- err = nil
- }
- return dat[0:n], err
-}
-
-// Open returns a new ReadSeeker reading the PE section.
-func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
-
-type FormatError struct {
- off int64
- msg string
- val interface{}
-}
-
-func (e *FormatError) Error() string {
- msg := e.msg
- if e.val != nil {
- msg += fmt.Sprintf(" '%v'", e.val)
- }
- msg += fmt.Sprintf(" in record at byte %#x", e.off)
- return msg
-}
-
-// Open opens the named file using os.Open and prepares it for use as a PE binary.
-func Open(name string) (*File, error) {
- f, err := os.Open(name)
- if err != nil {
- return nil, err
- }
- ff, err := NewFile(f)
- if err != nil {
- f.Close()
- return nil, err
- }
- ff.closer = f
- return ff, nil
-}
-
-// Close closes the File.
-// If the File was created using NewFile directly instead of Open,
-// Close has no effect.
-func (f *File) Close() error {
- var err error
- if f.closer != nil {
- err = f.closer.Close()
- f.closer = nil
- }
- return err
-}
-
-// NewFile creates a new File for accessing a PE binary in an underlying reader.
-func NewFile(r io.ReaderAt) (*File, error) {
- f := new(File)
- sr := io.NewSectionReader(r, 0, 1<<63-1)
-
- var dosheader [96]byte
- if _, err := r.ReadAt(dosheader[0:], 0); err != nil {
- return nil, err
- }
- var base int64
- if dosheader[0] == 'M' && dosheader[1] == 'Z' {
- signoff := int64(binary.LittleEndian.Uint32(dosheader[0x3c:]))
- var sign [4]byte
- r.ReadAt(sign[:], signoff)
- if !(sign[0] == 'P' && sign[1] == 'E' && sign[2] == 0 && sign[3] == 0) {
- return nil, errors.New("Invalid PE File Format.")
- }
- base = signoff + 4
- } else {
- base = int64(0)
- }
- sr.Seek(base, os.SEEK_SET)
- if err := binary.Read(sr, binary.LittleEndian, &f.FileHeader); err != nil {
- return nil, err
- }
- if f.FileHeader.Machine != IMAGE_FILE_MACHINE_UNKNOWN && f.FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64 && f.FileHeader.Machine != IMAGE_FILE_MACHINE_I386 {
- return nil, errors.New("Invalid PE File Format.")
- }
-
- var ss []byte
- if f.FileHeader.NumberOfSymbols > 0 {
- // Get COFF string table, which is located at the end of the COFF symbol table.
- sr.Seek(int64(f.FileHeader.PointerToSymbolTable+COFFSymbolSize*f.FileHeader.NumberOfSymbols), os.SEEK_SET)
- var l uint32
- if err := binary.Read(sr, binary.LittleEndian, &l); err != nil {
- return nil, err
- }
- ss = make([]byte, l)
- if _, err := r.ReadAt(ss, int64(f.FileHeader.PointerToSymbolTable+COFFSymbolSize*f.FileHeader.NumberOfSymbols)); err != nil {
- return nil, err
- }
-
- // Process COFF symbol table.
- sr.Seek(int64(f.FileHeader.PointerToSymbolTable), os.SEEK_SET)
- aux := uint8(0)
- for i := 0; i < int(f.FileHeader.NumberOfSymbols); i++ {
- cs := new(COFFSymbol)
- if err := binary.Read(sr, binary.LittleEndian, cs); err != nil {
- return nil, err
- }
- if aux > 0 {
- aux--
- continue
- }
- var name string
- if cs.Name[0] == 0 && cs.Name[1] == 0 && cs.Name[2] == 0 && cs.Name[3] == 0 {
- si := int(binary.LittleEndian.Uint32(cs.Name[4:]))
- name, _ = getString(ss, si)
- } else {
- name = cstring(cs.Name[:])
- }
- aux = cs.NumberOfAuxSymbols
- s := &Symbol{
- Name: name,
- Value: cs.Value,
- SectionNumber: cs.SectionNumber,
- Type: cs.Type,
- StorageClass: cs.StorageClass,
- }
- f.Symbols = append(f.Symbols, s)
- }
- }
-
- // Read optional header.
- sr.Seek(base, os.SEEK_SET)
- if err := binary.Read(sr, binary.LittleEndian, &f.FileHeader); err != nil {
- return nil, err
- }
- var oh32 OptionalHeader32
- var oh64 OptionalHeader64
- switch uintptr(f.FileHeader.SizeOfOptionalHeader) {
- case unsafe.Sizeof(oh32):
- if err := binary.Read(sr, binary.LittleEndian, &oh32); err != nil {
- return nil, err
- }
- if oh32.Magic != 0x10b { // PE32
- return nil, fmt.Errorf("pe32 optional header has unexpected Magic of 0x%x", oh32.Magic)
- }
- f.OptionalHeader = &oh32
- case unsafe.Sizeof(oh64):
- if err := binary.Read(sr, binary.LittleEndian, &oh64); err != nil {
- return nil, err
- }
- if oh64.Magic != 0x20b { // PE32+
- return nil, fmt.Errorf("pe32+ optional header has unexpected Magic of 0x%x", oh64.Magic)
- }
- f.OptionalHeader = &oh64
- }
-
- // Process sections.
- f.Sections = make([]*Section, f.FileHeader.NumberOfSections)
- for i := 0; i < int(f.FileHeader.NumberOfSections); i++ {
- sh := new(SectionHeader32)
- if err := binary.Read(sr, binary.LittleEndian, sh); err != nil {
- return nil, err
- }
- var name string
- if sh.Name[0] == '\x2F' {
- si, _ := strconv.Atoi(cstring(sh.Name[1:]))
- name, _ = getString(ss, si)
- } else {
- name = cstring(sh.Name[0:])
- }
- s := new(Section)
- s.SectionHeader = SectionHeader{
- Name: name,
- VirtualSize: sh.VirtualSize,
- VirtualAddress: sh.VirtualAddress,
- Size: sh.SizeOfRawData,
- Offset: sh.PointerToRawData,
- PointerToRelocations: sh.PointerToRelocations,
- PointerToLineNumbers: sh.PointerToLineNumbers,
- NumberOfRelocations: sh.NumberOfRelocations,
- NumberOfLineNumbers: sh.NumberOfLineNumbers,
- Characteristics: sh.Characteristics,
- }
- s.sr = io.NewSectionReader(r, int64(s.SectionHeader.Offset), int64(s.SectionHeader.Size))
- s.ReaderAt = s.sr
- f.Sections[i] = s
- }
- return f, nil
-}
-
-func cstring(b []byte) string {
- var i int
- for i = 0; i < len(b) && b[i] != 0; i++ {
- }
- return string(b[0:i])
-}
-
-// getString extracts a string from symbol string table.
-func getString(section []byte, start int) (string, bool) {
- if start < 0 || start >= len(section) {
- return "", false
- }
-
- for end := start; end < len(section); end++ {
- if section[end] == 0 {
- return string(section[start:end]), true
- }
- }
- return "", false
-}
-
-// Section returns the first section with the given name, or nil if no such
-// section exists.
-func (f *File) Section(name string) *Section {
- for _, s := range f.Sections {
- if s.Name == name {
- return s
- }
- }
- return nil
-}
-
-func (f *File) DWARF() (*dwarf.Data, error) {
- // There are many other DWARF sections, but these
- // are the required ones, and the debug/dwarf package
- // does not use the others, so don't bother loading them.
- var names = [...]string{"abbrev", "info", "str"}
- var dat [len(names)][]byte
- for i, name := range names {
- name = ".debug_" + name
- s := f.Section(name)
- if s == nil {
- continue
- }
- b, err := s.Data()
- if err != nil && uint32(len(b)) < s.Size {
- return nil, err
- }
- dat[i] = b
- }
-
- abbrev, info, str := dat[0], dat[1], dat[2]
- return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str)
-}
-
-// ImportedSymbols returns the names of all symbols
-// referred to by the binary f that are expected to be
-// satisfied by other libraries at dynamic load time.
-// It does not return weak symbols.
-func (f *File) ImportedSymbols() ([]string, error) {
- pe64 := f.Machine == IMAGE_FILE_MACHINE_AMD64
- ds := f.Section(".idata")
- if ds == nil {
- // not dynamic, so no libraries
- return nil, nil
- }
- d, err := ds.Data()
- if err != nil {
- return nil, err
- }
- var ida []ImportDirectory
- for len(d) > 0 {
- var dt ImportDirectory
- dt.OriginalFirstThunk = binary.LittleEndian.Uint32(d[0:4])
- dt.Name = binary.LittleEndian.Uint32(d[12:16])
- dt.FirstThunk = binary.LittleEndian.Uint32(d[16:20])
- d = d[20:]
- if dt.OriginalFirstThunk == 0 {
- break
- }
- ida = append(ida, dt)
- }
- names, _ := ds.Data()
- var all []string
- for _, dt := range ida {
- dt.dll, _ = getString(names, int(dt.Name-ds.VirtualAddress))
- d, _ = ds.Data()
- // seek to OriginalFirstThunk
- d = d[dt.OriginalFirstThunk-ds.VirtualAddress:]
- for len(d) > 0 {
- if pe64 { // 64bit
- va := binary.LittleEndian.Uint64(d[0:8])
- d = d[8:]
- if va == 0 {
- break
- }
- if va&0x8000000000000000 > 0 { // is Ordinal
- // TODO add dynimport ordinal support.
- } else {
- fn, _ := getString(names, int(uint32(va)-ds.VirtualAddress+2))
- all = append(all, fn+":"+dt.dll)
- }
- } else { // 32bit
- va := binary.LittleEndian.Uint32(d[0:4])
- d = d[4:]
- if va == 0 {
- break
- }
- if va&0x80000000 > 0 { // is Ordinal
- // TODO add dynimport ordinal support.
- //ord := va&0x0000FFFF
- } else {
- fn, _ := getString(names, int(va-ds.VirtualAddress+2))
- all = append(all, fn+":"+dt.dll)
- }
- }
- }
- }
-
- return all, nil
-}
-
-// ImportedLibraries returns the names of all libraries
-// referred to by the binary f that are expected to be
-// linked with the binary at dynamic link time.
-func (f *File) ImportedLibraries() ([]string, error) {
- // TODO
- // cgo -dynimport don't use this for windows PE, so just return.
- return nil, nil
-}
diff --git a/src/pkg/debug/pe/file_test.go b/src/pkg/debug/pe/file_test.go
deleted file mode 100644
index ddbb27174..000000000
--- a/src/pkg/debug/pe/file_test.go
+++ /dev/null
@@ -1,236 +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 pe
-
-import (
- "reflect"
- "testing"
-)
-
-type fileTest struct {
- file string
- hdr FileHeader
- opthdr interface{}
- sections []*SectionHeader
- symbols []*Symbol
-}
-
-var fileTests = []fileTest{
- {
- "testdata/gcc-386-mingw-obj",
- FileHeader{0x014c, 0x000c, 0x0, 0x64a, 0x1e, 0x0, 0x104},
- nil,
- []*SectionHeader{
- {".text", 0, 0, 36, 500, 1440, 0, 3, 0, 0x60300020},
- {".data", 0, 0, 0, 0, 0, 0, 0, 0, 3224371264},
- {".bss", 0, 0, 0, 0, 0, 0, 0, 0, 3224371328},
- {".debug_abbrev", 0, 0, 137, 536, 0, 0, 0, 0, 0x42100000},
- {".debug_info", 0, 0, 418, 673, 1470, 0, 7, 0, 1108344832},
- {".debug_line", 0, 0, 128, 1091, 1540, 0, 1, 0, 1108344832},
- {".rdata", 0, 0, 16, 1219, 0, 0, 0, 0, 1076887616},
- {".debug_frame", 0, 0, 52, 1235, 1550, 0, 2, 0, 1110441984},
- {".debug_loc", 0, 0, 56, 1287, 0, 0, 0, 0, 1108344832},
- {".debug_pubnames", 0, 0, 27, 1343, 1570, 0, 1, 0, 1108344832},
- {".debug_pubtypes", 0, 0, 38, 1370, 1580, 0, 1, 0, 1108344832},
- {".debug_aranges", 0, 0, 32, 1408, 1590, 0, 2, 0, 1108344832},
- },
- []*Symbol{
- {".file", 0x0, -2, 0x0, 0x67},
- {"_main", 0x0, 1, 0x20, 0x2},
- {".text", 0x0, 1, 0x0, 0x3},
- {".data", 0x0, 2, 0x0, 0x3},
- {".bss", 0x0, 3, 0x0, 0x3},
- {".debug_abbrev", 0x0, 4, 0x0, 0x3},
- {".debug_info", 0x0, 5, 0x0, 0x3},
- {".debug_line", 0x0, 6, 0x0, 0x3},
- {".rdata", 0x0, 7, 0x0, 0x3},
- {".debug_frame", 0x0, 8, 0x0, 0x3},
- {".debug_loc", 0x0, 9, 0x0, 0x3},
- {".debug_pubnames", 0x0, 10, 0x0, 0x3},
- {".debug_pubtypes", 0x0, 11, 0x0, 0x3},
- {".debug_aranges", 0x0, 12, 0x0, 0x3},
- {"___main", 0x0, 0, 0x20, 0x2},
- {"_puts", 0x0, 0, 0x20, 0x2},
- },
- },
- {
- "testdata/gcc-386-mingw-exec",
- FileHeader{0x014c, 0x000f, 0x4c6a1b60, 0x3c00, 0x282, 0xe0, 0x107},
- &OptionalHeader32{
- 0x10b, 0x2, 0x38, 0xe00, 0x1a00, 0x200, 0x1160, 0x1000, 0x2000, 0x400000, 0x1000, 0x200, 0x4, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x10000, 0x400, 0x14abb, 0x3, 0x0, 0x200000, 0x1000, 0x100000, 0x1000, 0x0, 0x10,
- [16]DataDirectory{
- {0x0, 0x0},
- {0x5000, 0x3c8},
- {0x0, 0x0},
- {0x0, 0x0},
- {0x0, 0x0},
- {0x0, 0x0},
- {0x0, 0x0},
- {0x0, 0x0},
- {0x0, 0x0},
- {0x7000, 0x18},
- {0x0, 0x0},
- {0x0, 0x0},
- {0x0, 0x0},
- {0x0, 0x0},
- {0x0, 0x0},
- {0x0, 0x0},
- },
- },
- []*SectionHeader{
- {".text", 0xcd8, 0x1000, 0xe00, 0x400, 0x0, 0x0, 0x0, 0x0, 0x60500060},
- {".data", 0x10, 0x2000, 0x200, 0x1200, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
- {".rdata", 0x120, 0x3000, 0x200, 0x1400, 0x0, 0x0, 0x0, 0x0, 0x40300040},
- {".bss", 0xdc, 0x4000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0400080},
- {".idata", 0x3c8, 0x5000, 0x400, 0x1600, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
- {".CRT", 0x18, 0x6000, 0x200, 0x1a00, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
- {".tls", 0x20, 0x7000, 0x200, 0x1c00, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
- {".debug_aranges", 0x20, 0x8000, 0x200, 0x1e00, 0x0, 0x0, 0x0, 0x0, 0x42100000},
- {".debug_pubnames", 0x51, 0x9000, 0x200, 0x2000, 0x0, 0x0, 0x0, 0x0, 0x42100000},
- {".debug_pubtypes", 0x91, 0xa000, 0x200, 0x2200, 0x0, 0x0, 0x0, 0x0, 0x42100000},
- {".debug_info", 0xe22, 0xb000, 0x1000, 0x2400, 0x0, 0x0, 0x0, 0x0, 0x42100000},
- {".debug_abbrev", 0x157, 0xc000, 0x200, 0x3400, 0x0, 0x0, 0x0, 0x0, 0x42100000},
- {".debug_line", 0x144, 0xd000, 0x200, 0x3600, 0x0, 0x0, 0x0, 0x0, 0x42100000},
- {".debug_frame", 0x34, 0xe000, 0x200, 0x3800, 0x0, 0x0, 0x0, 0x0, 0x42300000},
- {".debug_loc", 0x38, 0xf000, 0x200, 0x3a00, 0x0, 0x0, 0x0, 0x0, 0x42100000},
- },
- []*Symbol{},
- },
- {
- "testdata/gcc-amd64-mingw-obj",
- FileHeader{0x8664, 0x6, 0x0, 0x198, 0x12, 0x0, 0x4},
- nil,
- []*SectionHeader{
- {".text", 0x0, 0x0, 0x30, 0x104, 0x15c, 0x0, 0x3, 0x0, 0x60500020},
- {".data", 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0500040},
- {".bss", 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0500080},
- {".rdata", 0x0, 0x0, 0x10, 0x134, 0x0, 0x0, 0x0, 0x0, 0x40500040},
- {".xdata", 0x0, 0x0, 0xc, 0x144, 0x0, 0x0, 0x0, 0x0, 0x40300040},
- {".pdata", 0x0, 0x0, 0xc, 0x150, 0x17a, 0x0, 0x3, 0x0, 0x40300040},
- },
- []*Symbol{
- {".file", 0x0, -2, 0x0, 0x67},
- {"main", 0x0, 1, 0x20, 0x2},
- {".text", 0x0, 1, 0x0, 0x3},
- {".data", 0x0, 2, 0x0, 0x3},
- {".bss", 0x0, 3, 0x0, 0x3},
- {".rdata", 0x0, 4, 0x0, 0x3},
- {".xdata", 0x0, 5, 0x0, 0x3},
- {".pdata", 0x0, 6, 0x0, 0x3},
- {"__main", 0x0, 0, 0x20, 0x2},
- {"puts", 0x0, 0, 0x20, 0x2},
- },
- },
- {
- "testdata/gcc-amd64-mingw-exec",
- FileHeader{0x8664, 0x9, 0x53472993, 0x0, 0x0, 0xf0, 0x22f},
- &OptionalHeader64{
- 0x20b, 0x2, 0x16, 0x6a00, 0x2400, 0x1600, 0x14e0, 0x1000, 0x400000, 0x1000, 0x200, 0x4, 0x0, 0x0, 0x0, 0x5, 0x2, 0x0, 0x11000, 0x400, 0x1841e, 0x3, 0x0, 0x200000, 0x1000, 0x100000, 0x1000, 0x0, 0x10,
- [16]DataDirectory{
- {0x0, 0x0},
- {0xe000, 0x990},
- {0x0, 0x0},
- {0xa000, 0x498},
- {0x0, 0x0},
- {0x0, 0x0},
- {0x0, 0x0},
- {0x0, 0x0},
- {0x0, 0x0},
- {0x10000, 0x28},
- {0x0, 0x0},
- {0x0, 0x0},
- {0xe254, 0x218},
- {0x0, 0x0},
- {0x0, 0x0},
- {0x0, 0x0},
- },
- },
- []*SectionHeader{
- {".text", 0x6860, 0x1000, 0x6a00, 0x400, 0x0, 0x0, 0x0, 0x0, 0x60500020},
- {".data", 0xe0, 0x8000, 0x200, 0x6e00, 0x0, 0x0, 0x0, 0x0, 0xc0500040},
- {".rdata", 0x6b0, 0x9000, 0x800, 0x7000, 0x0, 0x0, 0x0, 0x0, 0x40600040},
- {".pdata", 0x498, 0xa000, 0x600, 0x7800, 0x0, 0x0, 0x0, 0x0, 0x40300040},
- {".xdata", 0x488, 0xb000, 0x600, 0x7e00, 0x0, 0x0, 0x0, 0x0, 0x40300040},
- {".bss", 0x1410, 0xc000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0600080},
- {".idata", 0x990, 0xe000, 0xa00, 0x8400, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
- {".CRT", 0x68, 0xf000, 0x200, 0x8e00, 0x0, 0x0, 0x0, 0x0, 0xc0400040},
- {".tls", 0x48, 0x10000, 0x200, 0x9000, 0x0, 0x0, 0x0, 0x0, 0xc0600040},
- },
- []*Symbol{},
- },
-}
-
-func isOptHdrEq(a, b interface{}) bool {
- switch va := a.(type) {
- case *OptionalHeader32:
- vb, ok := b.(*OptionalHeader32)
- if !ok {
- return false
- }
- return *vb == *va
- case *OptionalHeader64:
- vb, ok := b.(*OptionalHeader64)
- if !ok {
- return false
- }
- return *vb == *va
- case nil:
- return b == nil
- }
- return false
-}
-
-func TestOpen(t *testing.T) {
- for i := range fileTests {
- tt := &fileTests[i]
-
- f, err := Open(tt.file)
- if err != nil {
- t.Error(err)
- continue
- }
- if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
- t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)
- continue
- }
- if !isOptHdrEq(tt.opthdr, f.OptionalHeader) {
- t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.OptionalHeader, tt.opthdr)
- continue
- }
-
- for i, sh := range f.Sections {
- if i >= len(tt.sections) {
- break
- }
- have := &sh.SectionHeader
- want := tt.sections[i]
- if !reflect.DeepEqual(have, want) {
- t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
- }
- }
- tn := len(tt.sections)
- fn := len(f.Sections)
- if tn != fn {
- t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
- }
- for i, have := range f.Symbols {
- if i >= len(tt.symbols) {
- break
- }
- want := tt.symbols[i]
- if !reflect.DeepEqual(have, want) {
- t.Errorf("open %s, symbol %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
- }
- }
- }
-}
-
-func TestOpenFailure(t *testing.T) {
- filename := "file.go" // not a PE file
- _, err := Open(filename) // don't crash
- if err == nil {
- t.Errorf("open %s: succeeded unexpectedly", filename)
- }
-}
diff --git a/src/pkg/debug/pe/pe.go b/src/pkg/debug/pe/pe.go
deleted file mode 100644
index 8e90b1b51..000000000
--- a/src/pkg/debug/pe/pe.go
+++ /dev/null
@@ -1,134 +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 pe
-
-type FileHeader struct {
- Machine uint16
- NumberOfSections uint16
- TimeDateStamp uint32
- PointerToSymbolTable uint32
- NumberOfSymbols uint32
- SizeOfOptionalHeader uint16
- Characteristics uint16
-}
-
-type DataDirectory struct {
- VirtualAddress uint32
- Size uint32
-}
-
-type OptionalHeader32 struct {
- Magic uint16
- MajorLinkerVersion uint8
- MinorLinkerVersion uint8
- SizeOfCode uint32
- SizeOfInitializedData uint32
- SizeOfUninitializedData uint32
- AddressOfEntryPoint uint32
- BaseOfCode uint32
- BaseOfData uint32
- ImageBase uint32
- SectionAlignment uint32
- FileAlignment uint32
- MajorOperatingSystemVersion uint16
- MinorOperatingSystemVersion uint16
- MajorImageVersion uint16
- MinorImageVersion uint16
- MajorSubsystemVersion uint16
- MinorSubsystemVersion uint16
- Win32VersionValue uint32
- SizeOfImage uint32
- SizeOfHeaders uint32
- CheckSum uint32
- Subsystem uint16
- DllCharacteristics uint16
- SizeOfStackReserve uint32
- SizeOfStackCommit uint32
- SizeOfHeapReserve uint32
- SizeOfHeapCommit uint32
- LoaderFlags uint32
- NumberOfRvaAndSizes uint32
- DataDirectory [16]DataDirectory
-}
-
-type OptionalHeader64 struct {
- Magic uint16
- MajorLinkerVersion uint8
- MinorLinkerVersion uint8
- SizeOfCode uint32
- SizeOfInitializedData uint32
- SizeOfUninitializedData uint32
- AddressOfEntryPoint uint32
- BaseOfCode uint32
- ImageBase uint64
- SectionAlignment uint32
- FileAlignment uint32
- MajorOperatingSystemVersion uint16
- MinorOperatingSystemVersion uint16
- MajorImageVersion uint16
- MinorImageVersion uint16
- MajorSubsystemVersion uint16
- MinorSubsystemVersion uint16
- Win32VersionValue uint32
- SizeOfImage uint32
- SizeOfHeaders uint32
- CheckSum uint32
- Subsystem uint16
- DllCharacteristics uint16
- SizeOfStackReserve uint64
- SizeOfStackCommit uint64
- SizeOfHeapReserve uint64
- SizeOfHeapCommit uint64
- LoaderFlags uint32
- NumberOfRvaAndSizes uint32
- DataDirectory [16]DataDirectory
-}
-
-type SectionHeader32 struct {
- Name [8]uint8
- VirtualSize uint32
- VirtualAddress uint32
- SizeOfRawData uint32
- PointerToRawData uint32
- PointerToRelocations uint32
- PointerToLineNumbers uint32
- NumberOfRelocations uint16
- NumberOfLineNumbers uint16
- Characteristics uint32
-}
-
-const COFFSymbolSize = 18
-
-type COFFSymbol struct {
- Name [8]uint8
- Value uint32
- SectionNumber int16
- Type uint16
- StorageClass uint8
- NumberOfAuxSymbols uint8
-}
-
-const (
- IMAGE_FILE_MACHINE_UNKNOWN = 0x0
- IMAGE_FILE_MACHINE_AM33 = 0x1d3
- IMAGE_FILE_MACHINE_AMD64 = 0x8664
- IMAGE_FILE_MACHINE_ARM = 0x1c0
- IMAGE_FILE_MACHINE_EBC = 0xebc
- IMAGE_FILE_MACHINE_I386 = 0x14c
- IMAGE_FILE_MACHINE_IA64 = 0x200
- IMAGE_FILE_MACHINE_M32R = 0x9041
- IMAGE_FILE_MACHINE_MIPS16 = 0x266
- IMAGE_FILE_MACHINE_MIPSFPU = 0x366
- IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466
- IMAGE_FILE_MACHINE_POWERPC = 0x1f0
- IMAGE_FILE_MACHINE_POWERPCFP = 0x1f1
- IMAGE_FILE_MACHINE_R4000 = 0x166
- IMAGE_FILE_MACHINE_SH3 = 0x1a2
- IMAGE_FILE_MACHINE_SH3DSP = 0x1a3
- IMAGE_FILE_MACHINE_SH4 = 0x1a6
- IMAGE_FILE_MACHINE_SH5 = 0x1a8
- IMAGE_FILE_MACHINE_THUMB = 0x1c2
- IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169
-)
diff --git a/src/pkg/debug/pe/testdata/gcc-386-mingw-exec b/src/pkg/debug/pe/testdata/gcc-386-mingw-exec
deleted file mode 100644
index 4b808d043..000000000
--- a/src/pkg/debug/pe/testdata/gcc-386-mingw-exec
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/pe/testdata/gcc-386-mingw-obj b/src/pkg/debug/pe/testdata/gcc-386-mingw-obj
deleted file mode 100644
index 0c84d898d..000000000
--- a/src/pkg/debug/pe/testdata/gcc-386-mingw-obj
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/pe/testdata/gcc-amd64-mingw-exec b/src/pkg/debug/pe/testdata/gcc-amd64-mingw-exec
deleted file mode 100644
index 78d4e5fed..000000000
--- a/src/pkg/debug/pe/testdata/gcc-amd64-mingw-exec
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/pe/testdata/gcc-amd64-mingw-obj b/src/pkg/debug/pe/testdata/gcc-amd64-mingw-obj
deleted file mode 100644
index 48ae7921f..000000000
--- a/src/pkg/debug/pe/testdata/gcc-amd64-mingw-obj
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/pe/testdata/hello.c b/src/pkg/debug/pe/testdata/hello.c
deleted file mode 100644
index a689d3644..000000000
--- a/src/pkg/debug/pe/testdata/hello.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <stdio.h>
-
-int
-main(void)
-{
- printf("hello, world\n");
- return 0;
-}
diff --git a/src/pkg/debug/plan9obj/file.go b/src/pkg/debug/plan9obj/file.go
deleted file mode 100644
index 60a585719..000000000
--- a/src/pkg/debug/plan9obj/file.go
+++ /dev/null
@@ -1,325 +0,0 @@
-// Copyright 2014 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 plan9obj implements access to Plan 9 a.out object files.
-package plan9obj
-
-import (
- "encoding/binary"
- "errors"
- "fmt"
- "io"
- "os"
-)
-
-// A FileHeader represents a Plan 9 a.out file header.
-type FileHeader struct {
- Magic uint32
- Bss uint32
- Entry uint64
- PtrSize int
-}
-
-// A File represents an open Plan 9 a.out file.
-type File struct {
- FileHeader
- Sections []*Section
- closer io.Closer
-}
-
-// A SectionHeader represents a single Plan 9 a.out section header.
-// This structure doesn't exist on-disk, but eases navigation
-// through the object file.
-type SectionHeader struct {
- Name string
- Size uint32
- Offset uint32
-}
-
-// A Section represents a single section in a Plan 9 a.out file.
-type Section struct {
- SectionHeader
-
- // Embed ReaderAt for ReadAt method.
- // Do not embed SectionReader directly
- // to avoid having Read and Seek.
- // If a client wants Read and Seek it must use
- // Open() to avoid fighting over the seek offset
- // with other clients.
- io.ReaderAt
- sr *io.SectionReader
-}
-
-// Data reads and returns the contents of the Plan 9 a.out section.
-func (s *Section) Data() ([]byte, error) {
- dat := make([]byte, s.sr.Size())
- n, err := s.sr.ReadAt(dat, 0)
- if n == len(dat) {
- err = nil
- }
- return dat[0:n], err
-}
-
-// Open returns a new ReadSeeker reading the Plan 9 a.out section.
-func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
-
-// A Symbol represents an entry in a Plan 9 a.out symbol table section.
-type Sym struct {
- Value uint64
- Type rune
- Name string
-}
-
-/*
- * Plan 9 a.out reader
- */
-
-// formatError is returned by some operations if the data does
-// not have the correct format for an object file.
-type formatError struct {
- off int
- msg string
- val interface{}
-}
-
-func (e *formatError) Error() string {
- msg := e.msg
- if e.val != nil {
- msg += fmt.Sprintf(" '%v'", e.val)
- }
- msg += fmt.Sprintf(" in record at byte %#x", e.off)
- return msg
-}
-
-// Open opens the named file using os.Open and prepares it for use as a Plan 9 a.out binary.
-func Open(name string) (*File, error) {
- f, err := os.Open(name)
- if err != nil {
- return nil, err
- }
- ff, err := NewFile(f)
- if err != nil {
- f.Close()
- return nil, err
- }
- ff.closer = f
- return ff, nil
-}
-
-// Close closes the File.
-// If the File was created using NewFile directly instead of Open,
-// Close has no effect.
-func (f *File) Close() error {
- var err error
- if f.closer != nil {
- err = f.closer.Close()
- f.closer = nil
- }
- return err
-}
-
-func parseMagic(magic []byte) (uint32, error) {
- m := binary.BigEndian.Uint32(magic)
- switch m {
- case Magic386, MagicAMD64, MagicARM:
- return m, nil
- }
- return 0, &formatError{0, "bad magic number", magic}
-}
-
-// NewFile creates a new File for accessing a Plan 9 binary in an underlying reader.
-// The Plan 9 binary is expected to start at position 0 in the ReaderAt.
-func NewFile(r io.ReaderAt) (*File, error) {
- sr := io.NewSectionReader(r, 0, 1<<63-1)
- // Read and decode Plan 9 magic
- var magic [4]byte
- if _, err := r.ReadAt(magic[:], 0); err != nil {
- return nil, err
- }
- _, err := parseMagic(magic[:])
- if err != nil {
- return nil, err
- }
-
- ph := new(prog)
- if err := binary.Read(sr, binary.BigEndian, ph); err != nil {
- return nil, err
- }
-
- f := &File{FileHeader: FileHeader{
- Magic: ph.Magic,
- Bss: ph.Bss,
- Entry: uint64(ph.Entry),
- PtrSize: 4,
- }}
-
- hdrSize := 4 * 8
-
- if ph.Magic&Magic64 != 0 {
- if err := binary.Read(sr, binary.BigEndian, &f.Entry); err != nil {
- return nil, err
- }
- f.PtrSize = 8
- hdrSize += 8
- }
-
- var sects = []struct {
- name string
- size uint32
- }{
- {"text", ph.Text},
- {"data", ph.Data},
- {"syms", ph.Syms},
- {"spsz", ph.Spsz},
- {"pcsz", ph.Pcsz},
- }
-
- f.Sections = make([]*Section, 5)
-
- off := uint32(hdrSize)
-
- for i, sect := range sects {
- s := new(Section)
- s.SectionHeader = SectionHeader{
- Name: sect.name,
- Size: sect.size,
- Offset: off,
- }
- off += sect.size
- s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.Size))
- s.ReaderAt = s.sr
- f.Sections[i] = s
- }
-
- return f, nil
-}
-
-func walksymtab(data []byte, ptrsz int, fn func(sym) error) error {
- var order binary.ByteOrder = binary.BigEndian
- var s sym
- p := data
- for len(p) >= 4 {
- // Symbol type, value.
- if len(p) < ptrsz {
- return &formatError{len(data), "unexpected EOF", nil}
- }
- // fixed-width value
- if ptrsz == 8 {
- s.value = order.Uint64(p[0:8])
- p = p[8:]
- } else {
- s.value = uint64(order.Uint32(p[0:4]))
- p = p[4:]
- }
-
- var typ byte
- typ = p[0] & 0x7F
- s.typ = typ
- p = p[1:]
-
- // Name.
- var i int
- var nnul int
- for i = 0; i < len(p); i++ {
- if p[i] == 0 {
- nnul = 1
- break
- }
- }
- switch typ {
- case 'z', 'Z':
- p = p[i+nnul:]
- for i = 0; i+2 <= len(p); i += 2 {
- if p[i] == 0 && p[i+1] == 0 {
- nnul = 2
- break
- }
- }
- }
- if len(p) < i+nnul {
- return &formatError{len(data), "unexpected EOF", nil}
- }
- s.name = p[0:i]
- i += nnul
- p = p[i:]
-
- fn(s)
- }
- return nil
-}
-
-// NewTable decodes the Go symbol table in data,
-// returning an in-memory representation.
-func newTable(symtab []byte, ptrsz int) ([]Sym, error) {
- var n int
- err := walksymtab(symtab, ptrsz, func(s sym) error {
- n++
- return nil
- })
- if err != nil {
- return nil, err
- }
-
- fname := make(map[uint16]string)
- syms := make([]Sym, 0, n)
- err = walksymtab(symtab, ptrsz, func(s sym) error {
- n := len(syms)
- syms = syms[0 : n+1]
- ts := &syms[n]
- ts.Type = rune(s.typ)
- ts.Value = s.value
- switch s.typ {
- default:
- ts.Name = string(s.name[:])
- case 'z', 'Z':
- for i := 0; i < len(s.name); i += 2 {
- eltIdx := binary.BigEndian.Uint16(s.name[i : i+2])
- elt, ok := fname[eltIdx]
- if !ok {
- return &formatError{-1, "bad filename code", eltIdx}
- }
- if n := len(ts.Name); n > 0 && ts.Name[n-1] != '/' {
- ts.Name += "/"
- }
- ts.Name += elt
- }
- }
- switch s.typ {
- case 'f':
- fname[uint16(s.value)] = ts.Name
- }
- return nil
- })
- if err != nil {
- return nil, err
- }
-
- return syms, nil
-}
-
-// Symbols returns the symbol table for f.
-func (f *File) Symbols() ([]Sym, error) {
- symtabSection := f.Section("syms")
- if symtabSection == nil {
- return nil, errors.New("no symbol section")
- }
-
- symtab, err := symtabSection.Data()
- if err != nil {
- return nil, errors.New("cannot load symbol section")
- }
-
- return newTable(symtab, f.PtrSize)
-}
-
-// Section returns a section with the given name, or nil if no such
-// section exists.
-func (f *File) Section(name string) *Section {
- for _, s := range f.Sections {
- if s.Name == name {
- return s
- }
- }
- return nil
-}
diff --git a/src/pkg/debug/plan9obj/file_test.go b/src/pkg/debug/plan9obj/file_test.go
deleted file mode 100644
index 96186d815..000000000
--- a/src/pkg/debug/plan9obj/file_test.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2014 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 plan9obj
-
-import (
- "reflect"
- "testing"
-)
-
-type fileTest struct {
- file string
- hdr FileHeader
- sections []*SectionHeader
-}
-
-var fileTests = []fileTest{
- {
- "testdata/386-plan9-exec",
- FileHeader{Magic386, 0x324, 0x14, 4},
- []*SectionHeader{
- {"text", 0x4c5f, 0x20},
- {"data", 0x94c, 0x4c7f},
- {"syms", 0x2c2b, 0x55cb},
- {"spsz", 0x0, 0x81f6},
- {"pcsz", 0xf7a, 0x81f6},
- },
- },
- {
- "testdata/amd64-plan9-exec",
- FileHeader{MagicAMD64, 0x618, 0x13, 8},
- []*SectionHeader{
- {"text", 0x4213, 0x28},
- {"data", 0xa80, 0x423b},
- {"syms", 0x2c8c, 0x4cbb},
- {"spsz", 0x0, 0x7947},
- {"pcsz", 0xca0, 0x7947},
- },
- },
-}
-
-func TestOpen(t *testing.T) {
- for i := range fileTests {
- tt := &fileTests[i]
-
- f, err := Open(tt.file)
- if err != nil {
- t.Error(err)
- continue
- }
- if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
- t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)
- continue
- }
-
- for i, sh := range f.Sections {
- if i >= len(tt.sections) {
- break
- }
- have := &sh.SectionHeader
- want := tt.sections[i]
- if !reflect.DeepEqual(have, want) {
- t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
- }
- }
- tn := len(tt.sections)
- fn := len(f.Sections)
- if tn != fn {
- t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
- }
- }
-}
-
-func TestOpenFailure(t *testing.T) {
- filename := "file.go" // not a Plan 9 a.out file
- _, err := Open(filename) // don't crash
- if err == nil {
- t.Errorf("open %s: succeeded unexpectedly", filename)
- }
-}
diff --git a/src/pkg/debug/plan9obj/plan9obj.go b/src/pkg/debug/plan9obj/plan9obj.go
deleted file mode 100644
index af9858562..000000000
--- a/src/pkg/debug/plan9obj/plan9obj.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2014 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.
-
-/*
- * Plan 9 a.out constants and data structures
- */
-
-package plan9obj
-
-// Plan 9 Program header.
-type prog struct {
- Magic uint32 /* magic number */
- Text uint32 /* size of text segment */
- Data uint32 /* size of initialized data */
- Bss uint32 /* size of uninitialized data */
- Syms uint32 /* size of symbol table */
- Entry uint32 /* entry point */
- Spsz uint32 /* size of pc/sp offset table */
- Pcsz uint32 /* size of pc/line number table */
-}
-
-// Plan 9 symbol table entries.
-type sym struct {
- value uint64
- typ byte
- name []byte
-}
-
-const (
- Magic64 = 0x8000 // 64-bit expanded header
-
- Magic386 = (4*11+0)*11 + 7
- MagicAMD64 = (4*26+0)*26 + 7 + Magic64
- MagicARM = (4*20+0)*20 + 7
-)
diff --git a/src/pkg/debug/plan9obj/testdata/386-plan9-exec b/src/pkg/debug/plan9obj/testdata/386-plan9-exec
deleted file mode 100755
index 748e83f8e..000000000
--- a/src/pkg/debug/plan9obj/testdata/386-plan9-exec
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/plan9obj/testdata/amd64-plan9-exec b/src/pkg/debug/plan9obj/testdata/amd64-plan9-exec
deleted file mode 100755
index 3e257dd8f..000000000
--- a/src/pkg/debug/plan9obj/testdata/amd64-plan9-exec
+++ /dev/null
Binary files differ
diff --git a/src/pkg/debug/plan9obj/testdata/hello.c b/src/pkg/debug/plan9obj/testdata/hello.c
deleted file mode 100644
index c0d633e29..000000000
--- a/src/pkg/debug/plan9obj/testdata/hello.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <u.h>
-#include <libc.h>
-
-void
-main(void)
-{
- print("hello, world\n");
-}