diff options
| author | Clément Chigot <clement.chigot@atos.net> | 2018-10-22 17:00:37 +0200 |
|---|---|---|
| committer | Ian Lance Taylor <iant@golang.org> | 2018-10-31 13:47:42 +0000 |
| commit | 49dafc70c8558271fc2205061d07eed490f2bc18 (patch) | |
| tree | 25415a8f720ef6b3d698bbb6dba121baca3405a2 /src/cmd/internal/objfile | |
| parent | 5cc80899486027db5f0de00870f1e022e1cfb9c5 (diff) | |
| download | go-49dafc70c8558271fc2205061d07eed490f2bc18.tar.xz | |
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 <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/cmd/internal/objfile')
| -rw-r--r-- | src/cmd/internal/objfile/objfile.go | 1 | ||||
| -rw-r--r-- | src/cmd/internal/objfile/xcoff.go | 133 |
2 files changed, 134 insertions, 0 deletions
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() +} |
