aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal
diff options
context:
space:
mode:
authorClément Chigot <clement.chigot@atos.net>2018-12-05 17:23:25 +0100
committerIan Lance Taylor <iant@golang.org>2018-12-10 18:52:31 +0000
commite256afff51f49c872975f5a5f73faa46ee64c334 (patch)
treedf4072b61e19c0986b509634ce0cadebdb2d6b0b /src/cmd/internal
parent033d09493d3dc03fda13801902b6e2e102b9d73c (diff)
downloadgo-e256afff51f49c872975f5a5f73faa46ee64c334.tar.xz
all: move cmd/internal/xcoff to internal/xcoff
This commit moves cmd/internal/xcoff package to internal/xcoff because it will be needed to add XCOFF support in go/internal/gccgoimporter. Change-Id: Id12df0c438fb7db4a6a458fc1478480851bf7771 Reviewed-on: https://go-review.googlesource.com/c/152719 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/cmd/internal')
-rw-r--r--src/cmd/internal/buildid/buildid.go2
-rw-r--r--src/cmd/internal/objfile/xcoff.go2
-rw-r--r--src/cmd/internal/xcoff/file.go687
-rw-r--r--src/cmd/internal/xcoff/file_test.go102
-rw-r--r--src/cmd/internal/xcoff/testdata/gcc-ppc32-aix-dwarf2-execbin54694 -> 0 bytes
-rw-r--r--src/cmd/internal/xcoff/testdata/gcc-ppc64-aix-dwarf2-execbin57152 -> 0 bytes
-rw-r--r--src/cmd/internal/xcoff/testdata/hello.c7
-rw-r--r--src/cmd/internal/xcoff/xcoff.go367
8 files changed, 2 insertions, 1165 deletions
diff --git a/src/cmd/internal/buildid/buildid.go b/src/cmd/internal/buildid/buildid.go
index 8205f696eb..ac238d70ea 100644
--- a/src/cmd/internal/buildid/buildid.go
+++ b/src/cmd/internal/buildid/buildid.go
@@ -6,9 +6,9 @@ package buildid
import (
"bytes"
- "cmd/internal/xcoff"
"debug/elf"
"fmt"
+ "internal/xcoff"
"io"
"os"
"strconv"
diff --git a/src/cmd/internal/objfile/xcoff.go b/src/cmd/internal/objfile/xcoff.go
index f62a7edf89..d438c80226 100644
--- a/src/cmd/internal/objfile/xcoff.go
+++ b/src/cmd/internal/objfile/xcoff.go
@@ -7,9 +7,9 @@
package objfile
import (
- "cmd/internal/xcoff"
"debug/dwarf"
"fmt"
+ "internal/xcoff"
"io"
"unicode"
)
diff --git a/src/cmd/internal/xcoff/file.go b/src/cmd/internal/xcoff/file.go
deleted file mode 100644
index 0923b9fcf3..0000000000
--- a/src/cmd/internal/xcoff/file.go
+++ /dev/null
@@ -1,687 +0,0 @@
-// Copyright 2018 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 xcoff implements access to XCOFF (Extended Common Object File Format) files.
-package xcoff
-
-import (
- "debug/dwarf"
- "encoding/binary"
- "fmt"
- "io"
- "os"
- "strings"
-)
-
-// SectionHeader holds information about an XCOFF section header.
-type SectionHeader struct {
- Name string
- VirtualAddress uint64
- Size uint64
- Type uint32
- Relptr uint64
- Nreloc uint32
-}
-
-type Section struct {
- SectionHeader
- Relocs []Reloc
- io.ReaderAt
- sr *io.SectionReader
-}
-
-// AuxiliaryCSect holds information about an XCOFF symbol in an AUX_CSECT entry.
-type AuxiliaryCSect struct {
- Length int64
- StorageMappingClass int
- SymbolType int
-}
-
-// AuxiliaryFcn holds information about an XCOFF symbol in an AUX_FCN entry.
-type AuxiliaryFcn struct {
- Size int64
-}
-
-type Symbol struct {
- Name string
- Value uint64
- SectionNumber int
- StorageClass int
- AuxFcn AuxiliaryFcn
- AuxCSect AuxiliaryCSect
-}
-
-type Reloc struct {
- VirtualAddress uint64
- Symbol *Symbol
- Signed bool
- InstructionFixed bool
- Length uint8
- Type uint8
-}
-
-// ImportedSymbol holds information about an imported XCOFF symbol.
-type ImportedSymbol struct {
- Name string
- Library string
-}
-
-// FileHeader holds information about an XCOFF file header.
-type FileHeader struct {
- TargetMachine uint16
-}
-
-// A File represents an open XCOFF file.
-type File struct {
- FileHeader
- Sections []*Section
- Symbols []*Symbol
- StringTable []byte
- LibraryPaths []string
-
- closer io.Closer
-}
-
-// Open opens the named file using os.Open and prepares it for use as an XCOFF 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
-}
-
-// Section returns the first section with the given name, or nil if no such
-// section exists.
-// Xcoff have section's name limited to 8 bytes. Some sections like .gosymtab
-// can be trunked but this method will still find them.
-func (f *File) Section(name string) *Section {
- for _, s := range f.Sections {
- if s.Name == name || (len(name) > 8 && s.Name == name[:8]) {
- return s
- }
- }
- return nil
-}
-
-// SectionByType returns the first section in f with the
-// given type, or nil if there is no such section.
-func (f *File) SectionByType(typ uint32) *Section {
- for _, s := range f.Sections {
- if s.Type == typ {
- return s
- }
- }
- return nil
-}
-
-// cstring converts ASCII byte sequence b to string.
-// It stops once it finds 0 or reaches end of b.
-func cstring(b []byte) string {
- var i int
- for i = 0; i < len(b) && b[i] != 0; i++ {
- }
- return string(b[:i])
-}
-
-// getString extracts a string from an XCOFF string table.
-func getString(st []byte, offset uint32) (string, bool) {
- if offset < 4 || int(offset) >= len(st) {
- return "", false
- }
- return cstring(st[offset:]), true
-}
-
-// NewFile creates a new File for accessing an XCOFF binary in an underlying reader.
-func NewFile(r io.ReaderAt) (*File, error) {
- sr := io.NewSectionReader(r, 0, 1<<63-1)
- // Read XCOFF target machine
- var magic uint16
- if err := binary.Read(sr, binary.BigEndian, &magic); err != nil {
- return nil, err
- }
- if magic != U802TOCMAGIC && magic != U64_TOCMAGIC {
- return nil, fmt.Errorf("unrecognised XCOFF magic: 0x%x", magic)
- }
-
- f := new(File)
- f.TargetMachine = magic
-
- // Read XCOFF file header
- if _, err := sr.Seek(0, os.SEEK_SET); err != nil {
- return nil, err
- }
- var nscns uint16
- var symptr uint64
- var nsyms int32
- var opthdr uint16
- var hdrsz int
- switch f.TargetMachine {
- case U802TOCMAGIC:
- fhdr := new(FileHeader32)
- if err := binary.Read(sr, binary.BigEndian, fhdr); err != nil {
- return nil, err
- }
- nscns = fhdr.Fnscns
- symptr = uint64(fhdr.Fsymptr)
- nsyms = fhdr.Fnsyms
- opthdr = fhdr.Fopthdr
- hdrsz = FILHSZ_32
- case U64_TOCMAGIC:
- fhdr := new(FileHeader64)
- if err := binary.Read(sr, binary.BigEndian, fhdr); err != nil {
- return nil, err
- }
- nscns = fhdr.Fnscns
- symptr = fhdr.Fsymptr
- nsyms = fhdr.Fnsyms
- opthdr = fhdr.Fopthdr
- hdrsz = FILHSZ_64
- }
-
- if symptr == 0 || nsyms <= 0 {
- return nil, fmt.Errorf("no symbol table")
- }
-
- // Read string table (located right after symbol table).
- offset := symptr + uint64(nsyms)*SYMESZ
- if _, err := sr.Seek(int64(offset), os.SEEK_SET); err != nil {
- return nil, err
- }
- // The first 4 bytes contain the length (in bytes).
- var l uint32
- if err := binary.Read(sr, binary.BigEndian, &l); err != nil {
- return nil, err
- }
- if l > 4 {
- if _, err := sr.Seek(int64(offset), os.SEEK_SET); err != nil {
- return nil, err
- }
- f.StringTable = make([]byte, l)
- if _, err := io.ReadFull(sr, f.StringTable); err != nil {
- return nil, err
- }
- }
-
- // Read section headers
- if _, err := sr.Seek(int64(hdrsz)+int64(opthdr), os.SEEK_SET); err != nil {
- return nil, err
- }
- f.Sections = make([]*Section, nscns)
- for i := 0; i < int(nscns); i++ {
- var scnptr uint64
- s := new(Section)
- switch f.TargetMachine {
- case U802TOCMAGIC:
- shdr := new(SectionHeader32)
- if err := binary.Read(sr, binary.BigEndian, shdr); err != nil {
- return nil, err
- }
- s.Name = cstring(shdr.Sname[:])
- s.VirtualAddress = uint64(shdr.Svaddr)
- s.Size = uint64(shdr.Ssize)
- scnptr = uint64(shdr.Sscnptr)
- s.Type = shdr.Sflags
- s.Relptr = uint64(shdr.Srelptr)
- s.Nreloc = uint32(shdr.Snreloc)
- case U64_TOCMAGIC:
- shdr := new(SectionHeader64)
- if err := binary.Read(sr, binary.BigEndian, shdr); err != nil {
- return nil, err
- }
- s.Name = cstring(shdr.Sname[:])
- s.VirtualAddress = shdr.Svaddr
- s.Size = shdr.Ssize
- scnptr = shdr.Sscnptr
- s.Type = shdr.Sflags
- s.Relptr = shdr.Srelptr
- s.Nreloc = shdr.Snreloc
- }
- r2 := r
- if scnptr == 0 { // .bss must have all 0s
- r2 = zeroReaderAt{}
- }
- s.sr = io.NewSectionReader(r2, int64(scnptr), int64(s.Size))
- s.ReaderAt = s.sr
- f.Sections[i] = s
- }
-
- // Symbol map needed by relocation
- var idxToSym = make(map[int]*Symbol)
-
- // Read symbol table
- if _, err := sr.Seek(int64(symptr), os.SEEK_SET); err != nil {
- return nil, err
- }
- f.Symbols = make([]*Symbol, 0)
- for i := 0; i < int(nsyms); i++ {
- var numaux int
- var ok, needAuxFcn bool
- sym := new(Symbol)
- switch f.TargetMachine {
- case U802TOCMAGIC:
- se := new(SymEnt32)
- if err := binary.Read(sr, binary.BigEndian, se); err != nil {
- return nil, err
- }
- numaux = int(se.Nnumaux)
- sym.SectionNumber = int(se.Nscnum)
- sym.StorageClass = int(se.Nsclass)
- sym.Value = uint64(se.Nvalue)
- needAuxFcn = se.Ntype&SYM_TYPE_FUNC != 0 && numaux > 1
- zeroes := binary.BigEndian.Uint32(se.Nname[:4])
- if zeroes != 0 {
- sym.Name = cstring(se.Nname[:])
- } else {
- offset := binary.BigEndian.Uint32(se.Nname[4:])
- sym.Name, ok = getString(f.StringTable, offset)
- if !ok {
- goto skip
- }
- }
- case U64_TOCMAGIC:
- se := new(SymEnt64)
- if err := binary.Read(sr, binary.BigEndian, se); err != nil {
- return nil, err
- }
- numaux = int(se.Nnumaux)
- sym.SectionNumber = int(se.Nscnum)
- sym.StorageClass = int(se.Nsclass)
- sym.Value = se.Nvalue
- needAuxFcn = se.Ntype&SYM_TYPE_FUNC != 0 && numaux > 1
- sym.Name, ok = getString(f.StringTable, se.Noffset)
- if !ok {
- goto skip
- }
- }
- if sym.StorageClass != C_EXT && sym.StorageClass != C_WEAKEXT && sym.StorageClass != C_HIDEXT {
- goto skip
- }
- // Must have at least one csect auxiliary entry.
- if numaux < 1 || i+numaux >= int(nsyms) {
- goto skip
- }
-
- if sym.SectionNumber > int(nscns) {
- goto skip
- }
- if sym.SectionNumber == 0 {
- sym.Value = 0
- } else {
- sym.Value -= f.Sections[sym.SectionNumber-1].VirtualAddress
- }
-
- idxToSym[i] = sym
-
- // If this symbol is a function, it must retrieve its size from
- // its AUX_FCN entry.
- // It can happend that a function symbol doesn't have any AUX_FCN.
- // In this case, needAuxFcn is false and their size will be set to 0
- if needAuxFcn {
- switch f.TargetMachine {
- case U802TOCMAGIC:
- aux := new(AuxFcn32)
- if err := binary.Read(sr, binary.BigEndian, aux); err != nil {
- return nil, err
- }
- sym.AuxFcn.Size = int64(aux.Xfsize)
- case U64_TOCMAGIC:
- aux := new(AuxFcn64)
- if err := binary.Read(sr, binary.BigEndian, aux); err != nil {
- return nil, err
- }
- sym.AuxFcn.Size = int64(aux.Xfsize)
- }
- }
-
- // Read csect auxiliary entry (by convention, it is the last).
- if !needAuxFcn {
- if _, err := sr.Seek(int64(numaux-1)*SYMESZ, os.SEEK_CUR); err != nil {
- return nil, err
- }
- }
- i += numaux
- numaux = 0
- switch f.TargetMachine {
- case U802TOCMAGIC:
- aux := new(AuxCSect32)
- if err := binary.Read(sr, binary.BigEndian, aux); err != nil {
- return nil, err
- }
- sym.AuxCSect.SymbolType = int(aux.Xsmtyp & 0x7)
- sym.AuxCSect.StorageMappingClass = int(aux.Xsmclas)
- sym.AuxCSect.Length = int64(aux.Xscnlen)
- case U64_TOCMAGIC:
- aux := new(AuxCSect64)
- if err := binary.Read(sr, binary.BigEndian, aux); err != nil {
- return nil, err
- }
- sym.AuxCSect.SymbolType = int(aux.Xsmtyp & 0x7)
- sym.AuxCSect.StorageMappingClass = int(aux.Xsmclas)
- sym.AuxCSect.Length = int64(aux.Xscnlenhi)<<32 | int64(aux.Xscnlenlo)
- }
- f.Symbols = append(f.Symbols, sym)
- skip:
- i += numaux // Skip auxiliary entries
- if _, err := sr.Seek(int64(numaux)*SYMESZ, os.SEEK_CUR); err != nil {
- return nil, err
- }
- }
-
- // Read relocations
- // Only for .data or .text section
- for _, sect := range f.Sections {
- if sect.Type != STYP_TEXT && sect.Type != STYP_DATA {
- continue
- }
- sect.Relocs = make([]Reloc, sect.Nreloc)
- if sect.Relptr == 0 {
- continue
- }
- if _, err := sr.Seek(int64(sect.Relptr), os.SEEK_SET); err != nil {
- return nil, err
- }
- for i := uint32(0); i < sect.Nreloc; i++ {
- switch f.TargetMachine {
- case U802TOCMAGIC:
- rel := new(Reloc32)
- if err := binary.Read(sr, binary.BigEndian, rel); err != nil {
- return nil, err
- }
- sect.Relocs[i].VirtualAddress = uint64(rel.Rvaddr)
- sect.Relocs[i].Symbol = idxToSym[int(rel.Rsymndx)]
- sect.Relocs[i].Type = rel.Rtype
- sect.Relocs[i].Length = rel.Rsize&0x3F + 1
-
- if rel.Rsize&0x80 == 1 {
- sect.Relocs[i].Signed = true
- }
- if rel.Rsize&0x40 == 1 {
- sect.Relocs[i].InstructionFixed = true
- }
-
- case U64_TOCMAGIC:
- rel := new(Reloc64)
- if err := binary.Read(sr, binary.BigEndian, rel); err != nil {
- return nil, err
- }
- sect.Relocs[i].VirtualAddress = rel.Rvaddr
- sect.Relocs[i].Symbol = idxToSym[int(rel.Rsymndx)]
- sect.Relocs[i].Type = rel.Rtype
- sect.Relocs[i].Length = rel.Rsize&0x3F + 1
- if rel.Rsize&0x80 == 1 {
- sect.Relocs[i].Signed = true
- }
- if rel.Rsize&0x40 == 1 {
- sect.Relocs[i].InstructionFixed = true
- }
- }
- }
- }
-
- return f, nil
-}
-
-// zeroReaderAt is ReaderAt that reads 0s.
-type zeroReaderAt struct{}
-
-// ReadAt writes len(p) 0s into p.
-func (w zeroReaderAt) ReadAt(p []byte, off int64) (n int, err error) {
- for i := range p {
- p[i] = 0
- }
- return len(p), nil
-}
-
-// Data reads and returns the contents of the XCOFF section s.
-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[:n], err
-}
-
-// CSect reads and returns the contents of a csect.
-func (f *File) CSect(name string) []byte {
- for _, sym := range f.Symbols {
- if sym.Name == name && sym.AuxCSect.SymbolType == XTY_SD {
- if i := sym.SectionNumber - 1; 0 <= i && i < len(f.Sections) {
- s := f.Sections[i]
- if sym.Value+uint64(sym.AuxCSect.Length) <= s.Size {
- dat := make([]byte, sym.AuxCSect.Length)
- _, err := s.sr.ReadAt(dat, int64(sym.Value))
- if err != nil {
- return nil
- }
- return dat
- }
- }
- break
- }
- }
- return nil
-}
-
-func (f *File) DWARF() (*dwarf.Data, error) {
- // There are many other DWARF sections, but these
- // are the ones the debug/dwarf package uses.
- // Don't bother loading others.
- var subtypes = [...]uint32{SSUBTYP_DWABREV, SSUBTYP_DWINFO, SSUBTYP_DWLINE, SSUBTYP_DWRNGES, SSUBTYP_DWSTR}
- var dat [len(subtypes)][]byte
- for i, subtype := range subtypes {
- s := f.SectionByType(STYP_DWARF | subtype)
- if s != nil {
- b, err := s.Data()
- if err != nil && uint64(len(b)) < s.Size {
- return nil, err
- }
- dat[i] = b
- }
- }
-
- abbrev, info, line, ranges, str := dat[0], dat[1], dat[2], dat[3], dat[4]
- return dwarf.New(abbrev, nil, nil, info, line, nil, ranges, str)
-}
-
-// readImportID returns the import file IDs stored inside the .loader section.
-// Library name pattern is either path/base/member or base/member
-func (f *File) readImportIDs(s *Section) ([]string, error) {
- // Read loader header
- if _, err := s.sr.Seek(0, os.SEEK_SET); err != nil {
- return nil, err
- }
- var istlen uint32
- var nimpid int32
- var impoff uint64
- switch f.TargetMachine {
- case U802TOCMAGIC:
- lhdr := new(LoaderHeader32)
- if err := binary.Read(s.sr, binary.BigEndian, lhdr); err != nil {
- return nil, err
- }
- istlen = lhdr.Listlen
- nimpid = lhdr.Lnimpid
- impoff = uint64(lhdr.Limpoff)
- case U64_TOCMAGIC:
- lhdr := new(LoaderHeader64)
- if err := binary.Read(s.sr, binary.BigEndian, lhdr); err != nil {
- return nil, err
- }
- istlen = lhdr.Listlen
- nimpid = lhdr.Lnimpid
- impoff = lhdr.Limpoff
- }
-
- // Read loader import file ID table
- if _, err := s.sr.Seek(int64(impoff), os.SEEK_SET); err != nil {
- return nil, err
- }
- table := make([]byte, istlen)
- if _, err := io.ReadFull(s.sr, table); err != nil {
- return nil, err
- }
-
- offset := 0
- // First import file ID is the default LIBPATH value
- libpath := cstring(table[offset:])
- f.LibraryPaths = strings.Split(libpath, ":")
- offset += len(libpath) + 3 // 3 null bytes
- all := make([]string, 0)
- for i := 1; i < int(nimpid); i++ {
- impidpath := cstring(table[offset:])
- offset += len(impidpath) + 1
- impidbase := cstring(table[offset:])
- offset += len(impidbase) + 1
- impidmem := cstring(table[offset:])
- offset += len(impidmem) + 1
- var path string
- if len(impidpath) > 0 {
- path = impidpath + "/" + impidbase + "/" + impidmem
- } else {
- path = impidbase + "/" + impidmem
- }
- all = append(all, path)
- }
-
- return all, nil
-}
-
-// 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) {
- s := f.SectionByType(STYP_LOADER)
- if s == nil {
- return nil, nil
- }
- // Read loader header
- if _, err := s.sr.Seek(0, os.SEEK_SET); err != nil {
- return nil, err
- }
- var stlen uint32
- var stoff uint64
- var nsyms int32
- var symoff uint64
- switch f.TargetMachine {
- case U802TOCMAGIC:
- lhdr := new(LoaderHeader32)
- if err := binary.Read(s.sr, binary.BigEndian, lhdr); err != nil {
- return nil, err
- }
- stlen = lhdr.Lstlen
- stoff = uint64(lhdr.Lstoff)
- nsyms = lhdr.Lnsyms
- symoff = LDHDRSZ_32
- case U64_TOCMAGIC:
- lhdr := new(LoaderHeader64)
- if err := binary.Read(s.sr, binary.BigEndian, lhdr); err != nil {
- return nil, err
- }
- stlen = lhdr.Lstlen
- stoff = lhdr.Lstoff
- nsyms = lhdr.Lnsyms
- symoff = lhdr.Lsymoff
- }
-
- // Read loader section string table
- if _, err := s.sr.Seek(int64(stoff), os.SEEK_SET); err != nil {
- return nil, err
- }
- st := make([]byte, stlen)
- if _, err := io.ReadFull(s.sr, st); err != nil {
- return nil, err
- }
-
- // Read imported libraries
- libs, err := f.readImportIDs(s)
- if err != nil {
- return nil, err
- }
-
- // Read loader symbol table
- if _, err := s.sr.Seek(int64(symoff), os.SEEK_SET); err != nil {
- return nil, err
- }
- all := make([]ImportedSymbol, 0)
- for i := 0; i < int(nsyms); i++ {
- var name string
- var ifile int32
- var ok bool
- switch f.TargetMachine {
- case U802TOCMAGIC:
- ldsym := new(LoaderSymbol32)
- if err := binary.Read(s.sr, binary.BigEndian, ldsym); err != nil {
- return nil, err
- }
- if ldsym.Lsmtype&0x40 == 0 {
- continue // Imported symbols only
- }
- zeroes := binary.BigEndian.Uint32(ldsym.Lname[:4])
- if zeroes != 0 {
- name = cstring(ldsym.Lname[:])
- } else {
- offset := binary.BigEndian.Uint32(ldsym.Lname[4:])
- name, ok = getString(st, offset)
- if !ok {
- continue
- }
- }
- ifile = ldsym.Lifile
- case U64_TOCMAGIC:
- ldsym := new(LoaderSymbol64)
- if err := binary.Read(s.sr, binary.BigEndian, ldsym); err != nil {
- return nil, err
- }
- if ldsym.Lsmtype&0x40 == 0 {
- continue // Imported symbols only
- }
- name, ok = getString(st, ldsym.Loffset)
- if !ok {
- continue
- }
- ifile = ldsym.Lifile
- }
- var sym ImportedSymbol
- sym.Name = name
- if ifile >= 1 && int(ifile) <= len(libs) {
- sym.Library = libs[ifile-1]
- }
- all = append(all, sym)
- }
-
- 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) {
- s := f.SectionByType(STYP_LOADER)
- if s == nil {
- return nil, nil
- }
- all, err := f.readImportIDs(s)
- return all, err
-}
diff --git a/src/cmd/internal/xcoff/file_test.go b/src/cmd/internal/xcoff/file_test.go
deleted file mode 100644
index a6722e9453..0000000000
--- a/src/cmd/internal/xcoff/file_test.go
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2018 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 xcoff
-
-import (
- "reflect"
- "testing"
-)
-
-type fileTest struct {
- file string
- hdr FileHeader
- sections []*SectionHeader
- needed []string
-}
-
-var fileTests = []fileTest{
- {
- "testdata/gcc-ppc32-aix-dwarf2-exec",
- FileHeader{U802TOCMAGIC},
- []*SectionHeader{
- {".text", 0x10000290, 0x00000bbd, STYP_TEXT, 0x7ae6, 0x36},
- {".data", 0x20000e4d, 0x00000437, STYP_DATA, 0x7d02, 0x2b},
- {".bss", 0x20001284, 0x0000021c, STYP_BSS, 0, 0},
- {".loader", 0x00000000, 0x000004b3, STYP_LOADER, 0, 0},
- {".dwline", 0x00000000, 0x000000df, STYP_DWARF | SSUBTYP_DWLINE, 0x7eb0, 0x7},
- {".dwinfo", 0x00000000, 0x00000314, STYP_DWARF | SSUBTYP_DWINFO, 0x7ef6, 0xa},
- {".dwabrev", 0x00000000, 0x000000d6, STYP_DWARF | SSUBTYP_DWABREV, 0, 0},
- {".dwarnge", 0x00000000, 0x00000020, STYP_DWARF | SSUBTYP_DWARNGE, 0x7f5a, 0x2},
- {".dwloc", 0x00000000, 0x00000074, STYP_DWARF | SSUBTYP_DWLOC, 0, 0},
- {".debug", 0x00000000, 0x00005e4f, STYP_DEBUG, 0, 0},
- },
- []string{"libc.a/shr.o"},
- },
- {
- "testdata/gcc-ppc64-aix-dwarf2-exec",
- FileHeader{U64_TOCMAGIC},
- []*SectionHeader{
- {".text", 0x10000480, 0x00000afd, STYP_TEXT, 0x8322, 0x34},
- {".data", 0x20000f7d, 0x000002f3, STYP_DATA, 0x85fa, 0x25},
- {".bss", 0x20001270, 0x00000428, STYP_BSS, 0, 0},
- {".loader", 0x00000000, 0x00000535, STYP_LOADER, 0, 0},
- {".dwline", 0x00000000, 0x000000b4, STYP_DWARF | SSUBTYP_DWLINE, 0x8800, 0x4},
- {".dwinfo", 0x00000000, 0x0000036a, STYP_DWARF | SSUBTYP_DWINFO, 0x8838, 0x7},
- {".dwabrev", 0x00000000, 0x000000b5, STYP_DWARF | SSUBTYP_DWABREV, 0, 0},
- {".dwarnge", 0x00000000, 0x00000040, STYP_DWARF | SSUBTYP_DWARNGE, 0x889a, 0x2},
- {".dwloc", 0x00000000, 0x00000062, STYP_DWARF | SSUBTYP_DWLOC, 0, 0},
- {".debug", 0x00000000, 0x00006605, STYP_DEBUG, 0, 0},
- },
- []string{"libc.a/shr_64.o"},
- },
-}
-
-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)
- }
- tl := tt.needed
- fl, err := f.ImportedLibraries()
- if err != nil {
- t.Error(err)
- }
- if !reflect.DeepEqual(tl, fl) {
- t.Errorf("open %s: loader import = %v, want %v", tt.file, tl, fl)
- }
- }
-}
-
-func TestOpenFailure(t *testing.T) {
- filename := "file.go" // not an XCOFF object file
- _, err := Open(filename) // don't crash
- if err == nil {
- t.Errorf("open %s: succeeded unexpectedly", filename)
- }
-}
diff --git a/src/cmd/internal/xcoff/testdata/gcc-ppc32-aix-dwarf2-exec b/src/cmd/internal/xcoff/testdata/gcc-ppc32-aix-dwarf2-exec
deleted file mode 100644
index 810e21a0df..0000000000
--- a/src/cmd/internal/xcoff/testdata/gcc-ppc32-aix-dwarf2-exec
+++ /dev/null
Binary files differ
diff --git a/src/cmd/internal/xcoff/testdata/gcc-ppc64-aix-dwarf2-exec b/src/cmd/internal/xcoff/testdata/gcc-ppc64-aix-dwarf2-exec
deleted file mode 100644
index 707d01ebd4..0000000000
--- a/src/cmd/internal/xcoff/testdata/gcc-ppc64-aix-dwarf2-exec
+++ /dev/null
Binary files differ
diff --git a/src/cmd/internal/xcoff/testdata/hello.c b/src/cmd/internal/xcoff/testdata/hello.c
deleted file mode 100644
index 34d9ee7923..0000000000
--- a/src/cmd/internal/xcoff/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/cmd/internal/xcoff/xcoff.go b/src/cmd/internal/xcoff/xcoff.go
deleted file mode 100644
index f8465d7289..0000000000
--- a/src/cmd/internal/xcoff/xcoff.go
+++ /dev/null
@@ -1,367 +0,0 @@
-// Copyright 2018 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 xcoff
-
-// File Header.
-type FileHeader32 struct {
- Fmagic uint16 // Target machine
- Fnscns uint16 // Number of sections
- Ftimedat int32 // Time and date of file creation
- Fsymptr uint32 // Byte offset to symbol table start
- Fnsyms int32 // Number of entries in symbol table
- Fopthdr uint16 // Number of bytes in optional header
- Fflags uint16 // Flags
-}
-
-type FileHeader64 struct {
- Fmagic uint16 // Target machine
- Fnscns uint16 // Number of sections
- Ftimedat int32 // Time and date of file creation
- Fsymptr uint64 // Byte offset to symbol table start
- Fopthdr uint16 // Number of bytes in optional header
- Fflags uint16 // Flags
- Fnsyms int32 // Number of entries in symbol table
-}
-
-const (
- FILHSZ_32 = 20
- FILHSZ_64 = 24
-)
-const (
- U802TOCMAGIC = 0737 // AIX 32-bit XCOFF
- U64_TOCMAGIC = 0767 // AIX 64-bit XCOFF
-)
-
-// Flags that describe the type of the object file.
-const (
- F_RELFLG = 0x0001
- F_EXEC = 0x0002
- F_LNNO = 0x0004
- F_FDPR_PROF = 0x0010
- F_FDPR_OPTI = 0x0020
- F_DSA = 0x0040
- F_VARPG = 0x0100
- F_DYNLOAD = 0x1000
- F_SHROBJ = 0x2000
- F_LOADONLY = 0x4000
-)
-
-// Section Header.
-type SectionHeader32 struct {
- Sname [8]byte // Section name
- Spaddr uint32 // Physical address
- Svaddr uint32 // Virtual address
- Ssize uint32 // Section size
- Sscnptr uint32 // Offset in file to raw data for section
- Srelptr uint32 // Offset in file to relocation entries for section
- Slnnoptr uint32 // Offset in file to line number entries for section
- Snreloc uint16 // Number of relocation entries
- Snlnno uint16 // Number of line number entries
- Sflags uint32 // Flags to define the section type
-}
-
-type SectionHeader64 struct {
- Sname [8]byte // Section name
- Spaddr uint64 // Physical address
- Svaddr uint64 // Virtual address
- Ssize uint64 // Section size
- Sscnptr uint64 // Offset in file to raw data for section
- Srelptr uint64 // Offset in file to relocation entries for section
- Slnnoptr uint64 // Offset in file to line number entries for section
- Snreloc uint32 // Number of relocation entries
- Snlnno uint32 // Number of line number entries
- Sflags uint32 // Flags to define the section type
- Spad uint32 // Needs to be 72 bytes long
-}
-
-// Flags defining the section type.
-const (
- STYP_DWARF = 0x0010
- STYP_TEXT = 0x0020
- STYP_DATA = 0x0040
- STYP_BSS = 0x0080
- STYP_EXCEPT = 0x0100
- STYP_INFO = 0x0200
- STYP_TDATA = 0x0400
- STYP_TBSS = 0x0800
- STYP_LOADER = 0x1000
- STYP_DEBUG = 0x2000
- STYP_TYPCHK = 0x4000
- STYP_OVRFLO = 0x8000
-)
-const (
- SSUBTYP_DWINFO = 0x10000 // DWARF info section
- SSUBTYP_DWLINE = 0x20000 // DWARF line-number section
- SSUBTYP_DWPBNMS = 0x30000 // DWARF public names section
- SSUBTYP_DWPBTYP = 0x40000 // DWARF public types section
- SSUBTYP_DWARNGE = 0x50000 // DWARF aranges section
- SSUBTYP_DWABREV = 0x60000 // DWARF abbreviation section
- SSUBTYP_DWSTR = 0x70000 // DWARF strings section
- SSUBTYP_DWRNGES = 0x80000 // DWARF ranges section
- SSUBTYP_DWLOC = 0x90000 // DWARF location lists section
- SSUBTYP_DWFRAME = 0xA0000 // DWARF frames section
- SSUBTYP_DWMAC = 0xB0000 // DWARF macros section
-)
-
-// Symbol Table Entry.
-type SymEnt32 struct {
- Nname [8]byte // Symbol name
- Nvalue uint32 // Symbol value
- Nscnum int16 // Section number of symbol
- Ntype uint16 // Basic and derived type specification
- Nsclass int8 // Storage class of symbol
- Nnumaux int8 // Number of auxiliary entries
-}
-
-type SymEnt64 struct {
- Nvalue uint64 // Symbol value
- Noffset uint32 // Offset of the name in string table or .debug section
- Nscnum int16 // Section number of symbol
- Ntype uint16 // Basic and derived type specification
- Nsclass int8 // Storage class of symbol
- Nnumaux int8 // Number of auxiliary entries
-}
-
-const SYMESZ = 18
-
-const (
- // Nscnum
- N_DEBUG = -2
- N_ABS = -1
- N_UNDEF = 0
-
- //Ntype
- SYM_V_INTERNAL = 0x1000
- SYM_V_HIDDEN = 0x2000
- SYM_V_PROTECTED = 0x3000
- SYM_V_EXPORTED = 0x4000
- SYM_TYPE_FUNC = 0x0020 // is function
-)
-
-// Storage Class.
-const (
- C_NULL = 0 // Symbol table entry marked for deletion
- C_EXT = 2 // External symbol
- C_STAT = 3 // Static symbol
- C_BLOCK = 100 // Beginning or end of inner block
- C_FCN = 101 // Beginning or end of function
- C_FILE = 103 // Source file name and compiler information
- C_HIDEXT = 107 // Unnamed external symbol
- C_BINCL = 108 // Beginning of include file
- C_EINCL = 109 // End of include file
- C_WEAKEXT = 111 // Weak external symbol
- C_DWARF = 112 // DWARF symbol
- C_GSYM = 128 // Global variable
- C_LSYM = 129 // Automatic variable allocated on stack
- C_PSYM = 130 // Argument to subroutine allocated on stack
- C_RSYM = 131 // Register variable
- C_RPSYM = 132 // Argument to function or procedure stored in register
- C_STSYM = 133 // Statically allocated symbol
- C_BCOMM = 135 // Beginning of common block
- C_ECOML = 136 // Local member of common block
- C_ECOMM = 137 // End of common block
- C_DECL = 140 // Declaration of object
- C_ENTRY = 141 // Alternate entry
- C_FUN = 142 // Function or procedure
- C_BSTAT = 143 // Beginning of static block
- C_ESTAT = 144 // End of static block
- C_GTLS = 145 // Global thread-local variable
- C_STTLS = 146 // Static thread-local variable
-)
-
-// File Auxiliary Entry
-type AuxFile64 struct {
- Xfname [8]byte // Name or offset inside string table
- Xftype uint8 // Source file string type
- Xauxtype uint8 // Type of auxiliary entry
-}
-
-// Function Auxiliary Entry
-type AuxFcn32 struct {
- Xexptr uint32 // File offset to exception table entry
- Xfsize uint32 // Size of function in bytes
- Xlnnoptr uint32 // File pointer to line number
- Xendndx uint32 // Symbol table index of next entry
- Xpad uint16 // Unused
-}
-type AuxFcn64 struct {
- Xlnnoptr uint64 // File pointer to line number
- Xfsize uint32 // Size of function in bytes
- Xendndx uint32 // Symbol table index of next entry
- Xpad uint8 // Unused
- Xauxtype uint8 // Type of auxiliary entry
-}
-
-type AuxSect64 struct {
- Xscnlen uint64 // section length
- Xnreloc uint64 // Num RLDs
- pad uint8
- Xauxtype uint8 // Type of auxiliary entry
-}
-
-// csect Auxiliary Entry.
-type AuxCSect32 struct {
- Xscnlen int32 // Length or symbol table index
- Xparmhash uint32 // Offset of parameter type-check string
- Xsnhash uint16 // .typchk section number
- Xsmtyp uint8 // Symbol alignment and type
- Xsmclas uint8 // Storage-mapping class
- Xstab uint32 // Reserved
- Xsnstab uint16 // Reserved
-}
-
-type AuxCSect64 struct {
- Xscnlenlo uint32 // Lower 4 bytes of length or symbol table index
- Xparmhash uint32 // Offset of parameter type-check string
- Xsnhash uint16 // .typchk section number
- Xsmtyp uint8 // Symbol alignment and type
- Xsmclas uint8 // Storage-mapping class
- Xscnlenhi int32 // Upper 4 bytes of length or symbol table index
- Xpad uint8 // Unused
- Xauxtype uint8 // Type of auxiliary entry
-}
-
-// Auxiliary type
-const (
- _AUX_EXCEPT = 255
- _AUX_FCN = 254
- _AUX_SYM = 253
- _AUX_FILE = 252
- _AUX_CSECT = 251
- _AUX_SECT = 250
-)
-
-// Symbol type field.
-const (
- XTY_ER = 0 // External reference
- XTY_SD = 1 // Section definition
- XTY_LD = 2 // Label definition
- XTY_CM = 3 // Common csect definition
-)
-
-// Defines for File auxiliary definitions: x_ftype field of x_file
-const (
- XFT_FN = 0 // Source File Name
- XFT_CT = 1 // Compile Time Stamp
- XFT_CV = 2 // Compiler Version Number
- XFT_CD = 128 // Compiler Defined Information
-)
-
-// Storage-mapping class.
-const (
- XMC_PR = 0 // Program code
- XMC_RO = 1 // Read-only constant
- XMC_DB = 2 // Debug dictionary table
- XMC_TC = 3 // TOC entry
- XMC_UA = 4 // Unclassified
- XMC_RW = 5 // Read/Write data
- XMC_GL = 6 // Global linkage
- XMC_XO = 7 // Extended operation
- XMC_SV = 8 // 32-bit supervisor call descriptor
- XMC_BS = 9 // BSS class
- XMC_DS = 10 // Function descriptor
- XMC_UC = 11 // Unnamed FORTRAN common
- XMC_TC0 = 15 // TOC anchor
- XMC_TD = 16 // Scalar data entry in the TOC
- XMC_SV64 = 17 // 64-bit supervisor call descriptor
- XMC_SV3264 = 18 // Supervisor call descriptor for both 32-bit and 64-bit
- XMC_TL = 20 // Read/Write thread-local data
- XMC_UL = 21 // Read/Write thread-local data (.tbss)
- XMC_TE = 22 // TOC entry
-)
-
-// Loader Header.
-type LoaderHeader32 struct {
- Lversion int32 // Loader section version number
- Lnsyms int32 // Number of symbol table entries
- Lnreloc int32 // Number of relocation table entries
- Listlen uint32 // Length of import file ID string table
- Lnimpid int32 // Number of import file IDs
- Limpoff uint32 // Offset to start of import file IDs
- Lstlen uint32 // Length of string table
- Lstoff uint32 // Offset to start of string table
-}
-
-type LoaderHeader64 struct {
- Lversion int32 // Loader section version number
- Lnsyms int32 // Number of symbol table entries
- Lnreloc int32 // Number of relocation table entries
- Listlen uint32 // Length of import file ID string table
- Lnimpid int32 // Number of import file IDs
- Lstlen uint32 // Length of string table
- Limpoff uint64 // Offset to start of import file IDs
- Lstoff uint64 // Offset to start of string table
- Lsymoff uint64 // Offset to start of symbol table
- Lrldoff uint64 // Offset to start of relocation entries
-}
-
-const (
- LDHDRSZ_32 = 32
- LDHDRSZ_64 = 56
-)
-
-// Loader Symbol.
-type LoaderSymbol32 struct {
- Lname [8]byte // Symbol name or byte offset into string table
- Lvalue uint32 // Address field
- Lscnum int16 // Section number containing symbol
- Lsmtype int8 // Symbol type, export, import flags
- Lsmclas int8 // Symbol storage class
- Lifile int32 // Import file ID; ordinal of import file IDs
- Lparm uint32 // Parameter type-check field
-}
-
-type LoaderSymbol64 struct {
- Lvalue uint64 // Address field
- Loffset uint32 // Byte offset into string table of symbol name
- Lscnum int16 // Section number containing symbol
- Lsmtype int8 // Symbol type, export, import flags
- Lsmclas int8 // Symbol storage class
- Lifile int32 // Import file ID; ordinal of import file IDs
- Lparm uint32 // Parameter type-check field
-}
-
-type Reloc32 struct {
- Rvaddr uint32 // (virtual) address of reference
- Rsymndx uint32 // Index into symbol table
- Rsize uint8 // Sign and reloc bit len
- Rtype uint8 // Toc relocation type
-}
-
-type Reloc64 struct {
- Rvaddr uint64 // (virtual) address of reference
- Rsymndx uint32 // Index into symbol table
- Rsize uint8 // Sign and reloc bit len
- Rtype uint8 // Toc relocation type
-}
-
-const (
- R_POS = 0x00 // A(sym) Positive Relocation
- R_NEG = 0x01 // -A(sym) Negative Relocation
- R_REL = 0x02 // A(sym-*) Relative to self
- R_TOC = 0x03 // A(sym-TOC) Relative to TOC
- R_TRL = 0x12 // A(sym-TOC) TOC Relative indirect load.
-
- R_TRLA = 0x13 // A(sym-TOC) TOC Rel load address. modifiable inst
- R_GL = 0x05 // A(external TOC of sym) Global Linkage
- R_TCL = 0x06 // A(local TOC of sym) Local object TOC address
- R_RL = 0x0C // A(sym) Pos indirect load. modifiable instruction
- R_RLA = 0x0D // A(sym) Pos Load Address. modifiable instruction
- R_REF = 0x0F // AL0(sym) Non relocating ref. No garbage collect
- R_BA = 0x08 // A(sym) Branch absolute. Cannot modify instruction
- R_RBA = 0x18 // A(sym) Branch absolute. modifiable instruction
- R_BR = 0x0A // A(sym-*) Branch rel to self. non modifiable
- R_RBR = 0x1A // A(sym-*) Branch rel to self. modifiable instr
-
- R_TLS = 0x20 // General-dynamic reference to TLS symbol
- R_TLS_IE = 0x21 // Initial-exec reference to TLS symbol
- R_TLS_LD = 0x22 // Local-dynamic reference to TLS symbol
- R_TLS_LE = 0x23 // Local-exec reference to TLS symbol
- R_TLSM = 0x24 // Module reference to TLS symbol
- R_TLSML = 0x25 // Module reference to local (own) module
-
- R_TOCU = 0x30 // Relative to TOC - high order bits
- R_TOCL = 0x31 // Relative to TOC - low order bits
-)