From 49dafc70c8558271fc2205061d07eed490f2bc18 Mon Sep 17 00:00:00 2001 From: Clément Chigot Date: Mon, 22 Oct 2018 17:00:37 +0200 Subject: cmd: add XCOFF objfile and adapt cmd/nm tests This commit adds a new file format in cmd/internal/objfile for XCOFF. It also adapts tests inside cmd/nm for AIX. Updates: #25893 Change-Id: I1e55ea0b7f7d08a871343bee27d11e2d3baad254 Reviewed-on: https://go-review.googlesource.com/c/145397 Run-TryBot: Tobias Klauser TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/cmd/internal/objfile/objfile.go | 1 + src/cmd/internal/objfile/xcoff.go | 133 ++++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 src/cmd/internal/objfile/xcoff.go (limited to 'src/cmd/internal/objfile') diff --git a/src/cmd/internal/objfile/objfile.go b/src/cmd/internal/objfile/objfile.go index 10307be072..41c5d9b9f5 100644 --- a/src/cmd/internal/objfile/objfile.go +++ b/src/cmd/internal/objfile/objfile.go @@ -61,6 +61,7 @@ var openers = []func(io.ReaderAt) (rawFile, error){ openMacho, openPE, openPlan9, + openXcoff, } // Open opens the named file. diff --git a/src/cmd/internal/objfile/xcoff.go b/src/cmd/internal/objfile/xcoff.go new file mode 100644 index 0000000000..c36b4362ba --- /dev/null +++ b/src/cmd/internal/objfile/xcoff.go @@ -0,0 +1,133 @@ +// 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. + +// Parsing of XCOFF executable (AIX) + +package objfile + +import ( + "cmd/internal/xcoff" + "debug/dwarf" + "fmt" + "io" + "unicode" +) + +type xcoffFile struct { + xcoff *xcoff.File +} + +func openXcoff(r io.ReaderAt) (rawFile, error) { + f, err := xcoff.NewFile(r) + if err != nil { + return nil, err + } + return &xcoffFile{f}, nil +} + +func (f *xcoffFile) symbols() ([]Sym, error) { + var syms []Sym + for _, s := range f.xcoff.Symbols { + const ( + N_UNDEF = 0 // An undefined (extern) symbol + N_ABS = -1 // An absolute symbol (e_value is a constant, not an address) + N_DEBUG = -2 // A debugging symbol + ) + sym := Sym{Name: s.Name, Addr: s.Value, Code: '?'} + + switch s.SectionNumber { + case N_UNDEF: + sym.Code = 'U' + case N_ABS: + sym.Code = 'C' + case N_DEBUG: + sym.Code = '?' + default: + if s.SectionNumber < 0 || len(f.xcoff.Sections) < int(s.SectionNumber) { + return nil, fmt.Errorf("invalid section number in symbol table") + } + sect := f.xcoff.Sections[s.SectionNumber-1] + + // debug/xcoff returns an offset in the section not the actual address + sym.Addr += sect.VirtualAddress + + if s.AuxCSect.SymbolType&0x3 == xcoff.XTY_LD { + // The size of a function is contained in the + // AUX_FCN entry + sym.Size = s.AuxFcn.Size + } else { + sym.Size = s.AuxCSect.Length + } + + sym.Size = s.AuxCSect.Length + + switch sect.Type { + case xcoff.STYP_TEXT: + if s.AuxCSect.StorageMappingClass == xcoff.XMC_RO { + sym.Code = 'R' + } else { + sym.Code = 'T' + } + case xcoff.STYP_DATA: + sym.Code = 'D' + case xcoff.STYP_BSS: + sym.Code = 'B' + } + + if s.StorageClass == xcoff.C_HIDEXT { + // Local symbol + sym.Code = unicode.ToLower(sym.Code) + } + + } + syms = append(syms, sym) + } + + return syms, nil +} + +func (f *xcoffFile) pcln() (textStart uint64, symtab, pclntab []byte, err error) { + if sect := f.xcoff.Section(".text"); sect != nil { + textStart = sect.VirtualAddress + } + if sect := f.xcoff.Section(".gosymtab"); sect != nil { + if symtab, err = sect.Data(); err != nil { + return 0, nil, nil, err + } + } + if sect := f.xcoff.Section(".gopclntab"); sect != nil { + if pclntab, err = sect.Data(); err != nil { + return 0, nil, nil, err + } + } + return textStart, symtab, pclntab, nil +} + +func (f *xcoffFile) text() (textStart uint64, text []byte, err error) { + sect := f.xcoff.Section(".text") + if sect == nil { + return 0, nil, fmt.Errorf("text section not found") + } + textStart = sect.VirtualAddress + text, err = sect.Data() + return +} + +func (f *xcoffFile) goarch() string { + switch f.xcoff.TargetMachine { + case xcoff.U802TOCMAGIC: + return "ppc" + case xcoff.U64_TOCMAGIC: + return "ppc64" + } + return "" +} + +func (f *xcoffFile) loadAddress() (uint64, error) { + return 0, fmt.Errorf("unknown load address") +} + +func (f *xcoffFile) dwarf() (*dwarf.Data, error) { + return f.xcoff.DWARF() +} -- cgit v1.3