diff options
| author | Clément Chigot <clement.chigot@atos.net> | 2018-12-05 17:23:25 +0100 |
|---|---|---|
| committer | Ian Lance Taylor <iant@golang.org> | 2018-12-10 18:52:31 +0000 |
| commit | e256afff51f49c872975f5a5f73faa46ee64c334 (patch) | |
| tree | df4072b61e19c0986b509634ce0cadebdb2d6b0b /src/cmd/internal | |
| parent | 033d09493d3dc03fda13801902b6e2e102b9d73c (diff) | |
| download | go-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.go | 2 | ||||
| -rw-r--r-- | src/cmd/internal/objfile/xcoff.go | 2 | ||||
| -rw-r--r-- | src/cmd/internal/xcoff/file.go | 687 | ||||
| -rw-r--r-- | src/cmd/internal/xcoff/file_test.go | 102 | ||||
| -rw-r--r-- | src/cmd/internal/xcoff/testdata/gcc-ppc32-aix-dwarf2-exec | bin | 54694 -> 0 bytes | |||
| -rw-r--r-- | src/cmd/internal/xcoff/testdata/gcc-ppc64-aix-dwarf2-exec | bin | 57152 -> 0 bytes | |||
| -rw-r--r-- | src/cmd/internal/xcoff/testdata/hello.c | 7 | ||||
| -rw-r--r-- | src/cmd/internal/xcoff/xcoff.go | 367 |
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 Binary files differdeleted file mode 100644 index 810e21a0df..0000000000 --- a/src/cmd/internal/xcoff/testdata/gcc-ppc32-aix-dwarf2-exec +++ /dev/null diff --git a/src/cmd/internal/xcoff/testdata/gcc-ppc64-aix-dwarf2-exec b/src/cmd/internal/xcoff/testdata/gcc-ppc64-aix-dwarf2-exec Binary files differdeleted file mode 100644 index 707d01ebd4..0000000000 --- a/src/cmd/internal/xcoff/testdata/gcc-ppc64-aix-dwarf2-exec +++ /dev/null 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 -) |
