mirror of
https://github.com/golang/go
synced 2024-11-18 09:44:50 -07:00
[dev.link] cmd/link: move xcoff to loader represenatation
Change-Id: I5b260493ffd7945f665c466e892be18d81e7940a Reviewed-on: https://go-review.googlesource.com/c/go/+/233340 Run-TryBot: Jeremy Faller <jeremy@golang.org> Reviewed-by: Than McIntosh <thanm@google.com> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
ff1a2d02dc
commit
4e03dac77c
@ -1,36 +0,0 @@
|
|||||||
// Copyright 2020 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 ld
|
|
||||||
|
|
||||||
import (
|
|
||||||
"cmd/link/internal/sym"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Temporary dumping around for sym.Symbol version of helper
|
|
||||||
// functions in dodata(), still being used for some archs/oses.
|
|
||||||
// FIXME: get rid of this file when dodata() is completely
|
|
||||||
// converted.
|
|
||||||
|
|
||||||
// symalign returns the required alignment for the given symbol s.
|
|
||||||
func symalign(s *sym.Symbol) int32 {
|
|
||||||
min := int32(thearch.Minalign)
|
|
||||||
if s.Align >= min {
|
|
||||||
return s.Align
|
|
||||||
} else if s.Align != 0 {
|
|
||||||
return min
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(s.Name, "go.string.") || strings.HasPrefix(s.Name, "type..namedata.") {
|
|
||||||
// String data is just bytes.
|
|
||||||
// If we align it, we waste a lot of space to padding.
|
|
||||||
return min
|
|
||||||
}
|
|
||||||
align := int32(thearch.Maxalign)
|
|
||||||
for int64(align) > s.Size && align > min {
|
|
||||||
align >>= 1
|
|
||||||
}
|
|
||||||
s.Align = align
|
|
||||||
return align
|
|
||||||
}
|
|
@ -273,7 +273,7 @@ type Arch struct {
|
|||||||
Gentext2 func(*Link, *loader.Loader)
|
Gentext2 func(*Link, *loader.Loader)
|
||||||
Machoreloc1 func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool
|
Machoreloc1 func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool
|
||||||
PEreloc1 func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool
|
PEreloc1 func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool
|
||||||
Xcoffreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
|
Xcoffreloc1 func(*sys.Arch, *OutBuf, *loader.Loader, loader.Sym, loader.ExtRelocView, int64) bool
|
||||||
|
|
||||||
// TLSIEtoLE converts a TLS Initial Executable relocation to
|
// TLSIEtoLE converts a TLS Initial Executable relocation to
|
||||||
// a TLS Local Executable relocation.
|
// a TLS Local Executable relocation.
|
||||||
@ -2870,13 +2870,6 @@ func (ctxt *Link) loadlibfull(symGroupType []sym.SymKind, needReloc, needExtRelo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func symPkg(ctxt *Link, s *sym.Symbol) string {
|
|
||||||
if s == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return ctxt.loader.SymPkg(loader.Sym(s.SymIdx))
|
|
||||||
}
|
|
||||||
|
|
||||||
func ElfSymForReloc2(ctxt *Link, s loader.Sym) int32 {
|
func ElfSymForReloc2(ctxt *Link, s loader.Sym) int32 {
|
||||||
// If putelfsym created a local version of this symbol, use that in all
|
// If putelfsym created a local version of this symbol, use that in all
|
||||||
// relocations.
|
// relocations.
|
||||||
|
@ -320,16 +320,6 @@ func Main(arch *sys.Arch, theArch Arch) {
|
|||||||
thearch.Asmb(ctxt, ctxt.loader)
|
thearch.Asmb(ctxt, ctxt.loader)
|
||||||
bench.Start("reloc")
|
bench.Start("reloc")
|
||||||
ctxt.reloc()
|
ctxt.reloc()
|
||||||
newasmb2 := ctxt.IsDarwin() || ctxt.IsWindows() || ctxt.IsWasm() || ctxt.IsPlan9() || ctxt.IsElf()
|
|
||||||
if !newasmb2 {
|
|
||||||
bench.Start("loadlibfull")
|
|
||||||
// We don't need relocations at this point.
|
|
||||||
needReloc := false
|
|
||||||
// On AMD64 ELF, we directly use the loader's ExtRelocs, so we don't
|
|
||||||
// need conversion. Otherwise we do.
|
|
||||||
needExtReloc := ctxt.IsExternal() && !(ctxt.IsAMD64() && ctxt.IsELF)
|
|
||||||
ctxt.loadlibfull(symGroupType, needReloc, needExtReloc) // XXX do it here for now
|
|
||||||
}
|
|
||||||
bench.Start("Asmb2")
|
bench.Start("Asmb2")
|
||||||
thearch.Asmb2(ctxt, ctxt.loader)
|
thearch.Asmb2(ctxt, ctxt.loader)
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"cmd/link/internal/loader"
|
"cmd/link/internal/loader"
|
||||||
"cmd/link/internal/sym"
|
"cmd/link/internal/sym"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/bits"
|
"math/bits"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -359,7 +360,6 @@ type XcoffLdRel64 struct {
|
|||||||
|
|
||||||
// xcoffLoaderReloc holds information about a relocation made by the loader.
|
// xcoffLoaderReloc holds information about a relocation made by the loader.
|
||||||
type xcoffLoaderReloc struct {
|
type xcoffLoaderReloc struct {
|
||||||
sym *sym.Symbol
|
|
||||||
sym2 loader.Sym
|
sym2 loader.Sym
|
||||||
roff int32
|
roff int32
|
||||||
rtype uint16
|
rtype uint16
|
||||||
@ -616,13 +616,13 @@ func (f *xcoffFile) addSymbol(sym xcoffSym) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// xcoffAlign returns the log base 2 of the symbol's alignment.
|
// xcoffAlign returns the log base 2 of the symbol's alignment.
|
||||||
func xcoffAlign(x *sym.Symbol, t SymbolType) uint8 {
|
func xcoffAlign(ldr *loader.Loader, x loader.Sym, t SymbolType) uint8 {
|
||||||
align := x.Align
|
align := ldr.SymAlign(x)
|
||||||
if align == 0 {
|
if align == 0 {
|
||||||
if t == TextSym {
|
if t == TextSym {
|
||||||
align = int32(Funcalign)
|
align = int32(Funcalign)
|
||||||
} else {
|
} else {
|
||||||
align = symalign(x)
|
align = symalign2(ldr, x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return logBase2(int(align))
|
return logBase2(int(align))
|
||||||
@ -642,6 +642,7 @@ func logBase2(a int) uint8 {
|
|||||||
// Currently, a new file is in fact a new package. It seems to be OK, but it might change
|
// Currently, a new file is in fact a new package. It seems to be OK, but it might change
|
||||||
// in the future.
|
// in the future.
|
||||||
func (f *xcoffFile) writeSymbolNewFile(ctxt *Link, name string, firstEntry uint64, extnum int16) {
|
func (f *xcoffFile) writeSymbolNewFile(ctxt *Link, name string, firstEntry uint64, extnum int16) {
|
||||||
|
ldr := ctxt.loader
|
||||||
/* C_FILE */
|
/* C_FILE */
|
||||||
s := &XcoffSymEnt64{
|
s := &XcoffSymEnt64{
|
||||||
Noffset: uint32(f.stringTable.add(".file")),
|
Noffset: uint32(f.stringTable.add(".file")),
|
||||||
@ -670,8 +671,7 @@ func (f *xcoffFile) writeSymbolNewFile(ctxt *Link, name string, firstEntry uint6
|
|||||||
dwsize = getDwsectCUSize(sect.Name, name)
|
dwsize = getDwsectCUSize(sect.Name, name)
|
||||||
// .debug_abbrev is common to all packages and not found with the previous function
|
// .debug_abbrev is common to all packages and not found with the previous function
|
||||||
if sect.Name == ".debug_abbrev" {
|
if sect.Name == ".debug_abbrev" {
|
||||||
s := ctxt.Syms.ROLookup(sect.Name, 0)
|
dwsize = uint64(ldr.SymSize(loader.Sym(sect.Sym2)))
|
||||||
dwsize = uint64(s.Size)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -693,8 +693,7 @@ func (f *xcoffFile) writeSymbolNewFile(ctxt *Link, name string, firstEntry uint6
|
|||||||
// Dwarf relocations need the symbol number of .dw* symbols.
|
// Dwarf relocations need the symbol number of .dw* symbols.
|
||||||
// It doesn't need to know it for each package, one is enough.
|
// It doesn't need to know it for each package, one is enough.
|
||||||
// currSymSrcFile.csectAux == nil means first package.
|
// currSymSrcFile.csectAux == nil means first package.
|
||||||
dws := ctxt.Syms.Lookup(sect.Name, 0)
|
ldr.SetSymDynid(loader.Sym(sect.Sym2), int32(f.symbolCount))
|
||||||
dws.Dynid = int32(f.symbolCount)
|
|
||||||
|
|
||||||
if sect.Name == ".debug_frame" && ctxt.LinkMode != LinkExternal {
|
if sect.Name == ".debug_frame" && ctxt.LinkMode != LinkExternal {
|
||||||
// CIE size must be added to the first package.
|
// CIE size must be added to the first package.
|
||||||
@ -774,28 +773,30 @@ func (f *xcoffFile) updatePreviousFile(ctxt *Link, last bool) {
|
|||||||
// Write symbol representing a .text function.
|
// Write symbol representing a .text function.
|
||||||
// The symbol table is split with C_FILE corresponding to each package
|
// The symbol table is split with C_FILE corresponding to each package
|
||||||
// and not to each source file as it should be.
|
// and not to each source file as it should be.
|
||||||
func (f *xcoffFile) writeSymbolFunc(ctxt *Link, x *sym.Symbol) []xcoffSym {
|
func (f *xcoffFile) writeSymbolFunc(ctxt *Link, x loader.Sym) []xcoffSym {
|
||||||
// New XCOFF symbols which will be written.
|
// New XCOFF symbols which will be written.
|
||||||
syms := []xcoffSym{}
|
syms := []xcoffSym{}
|
||||||
|
|
||||||
// Check if a new file is detected.
|
// Check if a new file is detected.
|
||||||
if strings.Contains(x.Name, "-tramp") || strings.HasPrefix(x.Name, "runtime.text.") {
|
ldr := ctxt.loader
|
||||||
|
name := ldr.SymName(x)
|
||||||
|
if strings.Contains(name, "-tramp") || strings.HasPrefix(name, "runtime.text.") {
|
||||||
// Trampoline don't have a FILE so there are considered
|
// Trampoline don't have a FILE so there are considered
|
||||||
// in the current file.
|
// in the current file.
|
||||||
// Same goes for runtime.text.X symbols.
|
// Same goes for runtime.text.X symbols.
|
||||||
} else if symPkg(ctxt, x) == "" { // Undefined global symbol
|
} else if ldr.SymPkg(x) == "" { // Undefined global symbol
|
||||||
// If this happens, the algorithm must be redone.
|
// If this happens, the algorithm must be redone.
|
||||||
if currSymSrcFile.name != "" {
|
if currSymSrcFile.name != "" {
|
||||||
Exitf("undefined global symbol found inside another file")
|
Exitf("undefined global symbol found inside another file")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Current file has changed. New C_FILE, C_DWARF, etc must be generated.
|
// Current file has changed. New C_FILE, C_DWARF, etc must be generated.
|
||||||
if currSymSrcFile.name != symPkg(ctxt, x) {
|
if currSymSrcFile.name != ldr.SymPkg(x) {
|
||||||
if ctxt.LinkMode == LinkInternal {
|
if ctxt.LinkMode == LinkInternal {
|
||||||
// update previous file values
|
// update previous file values
|
||||||
xfile.updatePreviousFile(ctxt, false)
|
xfile.updatePreviousFile(ctxt, false)
|
||||||
currSymSrcFile.name = symPkg(ctxt, x)
|
currSymSrcFile.name = ldr.SymPkg(x)
|
||||||
f.writeSymbolNewFile(ctxt, symPkg(ctxt, x), uint64(x.Value), xfile.getXCOFFscnum(x.Sect))
|
f.writeSymbolNewFile(ctxt, ldr.SymPkg(x), uint64(ldr.SymValue(x)), xfile.getXCOFFscnum(ldr.SymSect(x)))
|
||||||
} else {
|
} else {
|
||||||
// With external linking, ld will crash if there is several
|
// With external linking, ld will crash if there is several
|
||||||
// .FILE and DWARF debugging enable, somewhere during
|
// .FILE and DWARF debugging enable, somewhere during
|
||||||
@ -805,8 +806,8 @@ func (f *xcoffFile) writeSymbolFunc(ctxt *Link, x *sym.Symbol) []xcoffSym {
|
|||||||
// TODO(aix); remove once ld has been fixed or the triggering
|
// TODO(aix); remove once ld has been fixed or the triggering
|
||||||
// relocation has been found and fixed.
|
// relocation has been found and fixed.
|
||||||
if currSymSrcFile.name == "" {
|
if currSymSrcFile.name == "" {
|
||||||
currSymSrcFile.name = symPkg(ctxt, x)
|
currSymSrcFile.name = ldr.SymPkg(x)
|
||||||
f.writeSymbolNewFile(ctxt, "go_functions", uint64(x.Value), xfile.getXCOFFscnum(x.Sect))
|
f.writeSymbolNewFile(ctxt, "go_functions", uint64(ldr.SymValue(x)), xfile.getXCOFFscnum(ldr.SymSect(x)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -815,26 +816,26 @@ func (f *xcoffFile) writeSymbolFunc(ctxt *Link, x *sym.Symbol) []xcoffSym {
|
|||||||
|
|
||||||
s := &XcoffSymEnt64{
|
s := &XcoffSymEnt64{
|
||||||
Nsclass: C_EXT,
|
Nsclass: C_EXT,
|
||||||
Noffset: uint32(xfile.stringTable.add(x.Extname())),
|
Noffset: uint32(xfile.stringTable.add(ldr.SymExtname(x))),
|
||||||
Nvalue: uint64(x.Value),
|
Nvalue: uint64(ldr.SymValue(x)),
|
||||||
Nscnum: f.getXCOFFscnum(x.Sect),
|
Nscnum: f.getXCOFFscnum(ldr.SymSect(x)),
|
||||||
Ntype: SYM_TYPE_FUNC,
|
Ntype: SYM_TYPE_FUNC,
|
||||||
Nnumaux: 2,
|
Nnumaux: 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
if x.Version != 0 || x.Attr.VisibilityHidden() || x.Attr.Local() {
|
if ldr.SymVersion(x) != 0 || ldr.AttrVisibilityHidden(x) || ldr.AttrLocal(x) {
|
||||||
s.Nsclass = C_HIDEXT
|
s.Nsclass = C_HIDEXT
|
||||||
}
|
}
|
||||||
|
|
||||||
x.Dynid = int32(xfile.symbolCount)
|
ldr.SetSymDynid(x, int32(xfile.symbolCount))
|
||||||
syms = append(syms, s)
|
syms = append(syms, s)
|
||||||
|
|
||||||
// Update current csect size
|
// Update current csect size
|
||||||
currSymSrcFile.csectSize += x.Size
|
currSymSrcFile.csectSize += ldr.SymSize(x)
|
||||||
|
|
||||||
// create auxiliary entries
|
// create auxiliary entries
|
||||||
a2 := &XcoffAuxFcn64{
|
a2 := &XcoffAuxFcn64{
|
||||||
Xfsize: uint32(x.Size),
|
Xfsize: uint32(ldr.SymSize(x)),
|
||||||
Xlnnoptr: 0, // TODO
|
Xlnnoptr: 0, // TODO
|
||||||
Xendndx: xfile.symbolCount + 3, // this symbol + 2 aux entries
|
Xendndx: xfile.symbolCount + 3, // this symbol + 2 aux entries
|
||||||
Xauxtype: _AUX_FCN,
|
Xauxtype: _AUX_FCN,
|
||||||
@ -848,44 +849,49 @@ func (f *xcoffFile) writeSymbolFunc(ctxt *Link, x *sym.Symbol) []xcoffSym {
|
|||||||
Xsmtyp: XTY_LD, // label definition (based on C)
|
Xsmtyp: XTY_LD, // label definition (based on C)
|
||||||
Xauxtype: _AUX_CSECT,
|
Xauxtype: _AUX_CSECT,
|
||||||
}
|
}
|
||||||
a4.Xsmtyp |= uint8(xcoffAlign(x, TextSym) << 3)
|
a4.Xsmtyp |= uint8(xcoffAlign(ldr, x, TextSym) << 3)
|
||||||
|
|
||||||
syms = append(syms, a4)
|
syms = append(syms, a4)
|
||||||
return syms
|
return syms
|
||||||
}
|
}
|
||||||
|
|
||||||
// put function used by genasmsym to write symbol table
|
// put function used by genasmsym to write symbol table
|
||||||
func putaixsym(ctxt *Link, x *sym.Symbol, str string, t SymbolType, addr int64) {
|
func putaixsym(ctxt *Link, x loader.Sym, t SymbolType) {
|
||||||
|
|
||||||
// All XCOFF symbols generated by this GO symbols
|
// All XCOFF symbols generated by this GO symbols
|
||||||
// Can be a symbol entry or a auxiliary entry
|
// Can be a symbol entry or a auxiliary entry
|
||||||
syms := []xcoffSym{}
|
syms := []xcoffSym{}
|
||||||
|
|
||||||
|
ldr := ctxt.loader
|
||||||
|
name := ldr.SymName(x)
|
||||||
|
if t == UndefinedSym {
|
||||||
|
name = ldr.SymExtname(x)
|
||||||
|
}
|
||||||
|
|
||||||
switch t {
|
switch t {
|
||||||
default:
|
default:
|
||||||
return
|
return
|
||||||
|
|
||||||
case TextSym:
|
case TextSym:
|
||||||
if symPkg(ctxt, x) != "" || strings.Contains(x.Name, "-tramp") || strings.HasPrefix(x.Name, "runtime.text.") {
|
if ldr.SymPkg(x) != "" || strings.Contains(name, "-tramp") || strings.HasPrefix(name, "runtime.text.") {
|
||||||
// Function within a file
|
// Function within a file
|
||||||
syms = xfile.writeSymbolFunc(ctxt, x)
|
syms = xfile.writeSymbolFunc(ctxt, x)
|
||||||
} else {
|
} else {
|
||||||
// Only runtime.text and runtime.etext come through this way
|
// Only runtime.text and runtime.etext come through this way
|
||||||
if x.Name != "runtime.text" && x.Name != "runtime.etext" && x.Name != "go.buildid" {
|
if name != "runtime.text" && name != "runtime.etext" && name != "go.buildid" {
|
||||||
Exitf("putaixsym: unknown text symbol %s", x.Name)
|
Exitf("putaixsym: unknown text symbol %s", name)
|
||||||
}
|
}
|
||||||
s := &XcoffSymEnt64{
|
s := &XcoffSymEnt64{
|
||||||
Nsclass: C_HIDEXT,
|
Nsclass: C_HIDEXT,
|
||||||
Noffset: uint32(xfile.stringTable.add(str)),
|
Noffset: uint32(xfile.stringTable.add(name)),
|
||||||
Nvalue: uint64(x.Value),
|
Nvalue: uint64(ldr.SymValue(x)),
|
||||||
Nscnum: xfile.getXCOFFscnum(x.Sect),
|
Nscnum: xfile.getXCOFFscnum(ldr.SymSect(x)),
|
||||||
Ntype: SYM_TYPE_FUNC,
|
Ntype: SYM_TYPE_FUNC,
|
||||||
Nnumaux: 1,
|
Nnumaux: 1,
|
||||||
}
|
}
|
||||||
x.Dynid = int32(xfile.symbolCount)
|
ldr.SetSymDynid(x, int32(xfile.symbolCount))
|
||||||
syms = append(syms, s)
|
syms = append(syms, s)
|
||||||
|
|
||||||
size := uint64(x.Size)
|
size := uint64(ldr.SymSize(x))
|
||||||
a4 := &XcoffAuxCSect64{
|
a4 := &XcoffAuxCSect64{
|
||||||
Xauxtype: _AUX_CSECT,
|
Xauxtype: _AUX_CSECT,
|
||||||
Xscnlenlo: uint32(size & 0xFFFFFFFF),
|
Xscnlenlo: uint32(size & 0xFFFFFFFF),
|
||||||
@ -893,21 +899,20 @@ func putaixsym(ctxt *Link, x *sym.Symbol, str string, t SymbolType, addr int64)
|
|||||||
Xsmclas: XMC_PR,
|
Xsmclas: XMC_PR,
|
||||||
Xsmtyp: XTY_SD,
|
Xsmtyp: XTY_SD,
|
||||||
}
|
}
|
||||||
a4.Xsmtyp |= uint8(xcoffAlign(x, TextSym) << 3)
|
a4.Xsmtyp |= uint8(xcoffAlign(ldr, x, TextSym) << 3)
|
||||||
syms = append(syms, a4)
|
syms = append(syms, a4)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case DataSym, BSSSym:
|
case DataSym, BSSSym:
|
||||||
s := &XcoffSymEnt64{
|
s := &XcoffSymEnt64{
|
||||||
Nsclass: C_EXT,
|
Nsclass: C_EXT,
|
||||||
Noffset: uint32(xfile.stringTable.add(str)),
|
Noffset: uint32(xfile.stringTable.add(name)),
|
||||||
Nvalue: uint64(x.Value),
|
Nvalue: uint64(ldr.SymValue(x)),
|
||||||
Nscnum: xfile.getXCOFFscnum(x.Sect),
|
Nscnum: xfile.getXCOFFscnum(ldr.SymSect(x)),
|
||||||
Nnumaux: 1,
|
Nnumaux: 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
if x.Version != 0 || x.Attr.VisibilityHidden() || x.Attr.Local() {
|
if ldr.SymVersion(x) != 0 || ldr.AttrVisibilityHidden(x) || ldr.AttrLocal(x) {
|
||||||
// There is more symbols in the case of a global data
|
// There is more symbols in the case of a global data
|
||||||
// which are related to the assembly generated
|
// which are related to the assembly generated
|
||||||
// to access such symbols.
|
// to access such symbols.
|
||||||
@ -917,7 +922,7 @@ func putaixsym(ctxt *Link, x *sym.Symbol, str string, t SymbolType, addr int64)
|
|||||||
s.Nsclass = C_HIDEXT
|
s.Nsclass = C_HIDEXT
|
||||||
}
|
}
|
||||||
|
|
||||||
x.Dynid = int32(xfile.symbolCount)
|
ldr.SetSymDynid(x, int32(xfile.symbolCount))
|
||||||
syms = append(syms, s)
|
syms = append(syms, s)
|
||||||
|
|
||||||
// Create auxiliary entry
|
// Create auxiliary entry
|
||||||
@ -926,15 +931,15 @@ func putaixsym(ctxt *Link, x *sym.Symbol, str string, t SymbolType, addr int64)
|
|||||||
// the data and bss symbols of one file/package.
|
// the data and bss symbols of one file/package.
|
||||||
// However, it's easier to just have a csect for each symbol.
|
// However, it's easier to just have a csect for each symbol.
|
||||||
// It might change
|
// It might change
|
||||||
size := uint64(x.Size)
|
size := uint64(ldr.SymSize(x))
|
||||||
a4 := &XcoffAuxCSect64{
|
a4 := &XcoffAuxCSect64{
|
||||||
Xauxtype: _AUX_CSECT,
|
Xauxtype: _AUX_CSECT,
|
||||||
Xscnlenlo: uint32(size & 0xFFFFFFFF),
|
Xscnlenlo: uint32(size & 0xFFFFFFFF),
|
||||||
Xscnlenhi: uint32(size >> 32),
|
Xscnlenhi: uint32(size >> 32),
|
||||||
}
|
}
|
||||||
|
|
||||||
if x.Type >= sym.STYPE && x.Type <= sym.SPCLNTAB {
|
if ty := ldr.SymType(x); ty >= sym.STYPE && ty <= sym.SPCLNTAB {
|
||||||
if ctxt.LinkMode == LinkExternal && strings.HasPrefix(x.Sect.Name, ".data.rel.ro") {
|
if ctxt.IsExternal() && strings.HasPrefix(ldr.SymSect(x).Name, ".data.rel.ro") {
|
||||||
// During external linking, read-only datas with relocation
|
// During external linking, read-only datas with relocation
|
||||||
// must be in .data.
|
// must be in .data.
|
||||||
a4.Xsmclas = XMC_RW
|
a4.Xsmclas = XMC_RW
|
||||||
@ -942,9 +947,9 @@ func putaixsym(ctxt *Link, x *sym.Symbol, str string, t SymbolType, addr int64)
|
|||||||
// Read only data
|
// Read only data
|
||||||
a4.Xsmclas = XMC_RO
|
a4.Xsmclas = XMC_RO
|
||||||
}
|
}
|
||||||
} else if x.Type == sym.SDATA && strings.HasPrefix(x.Name, "TOC.") && ctxt.LinkMode == LinkExternal {
|
} else if /*ty == sym.SDATA &&*/ strings.HasPrefix(ldr.SymName(x), "TOC.") && ctxt.IsExternal() {
|
||||||
a4.Xsmclas = XMC_TC
|
a4.Xsmclas = XMC_TC
|
||||||
} else if x.Name == "TOC" {
|
} else if ldr.SymName(x) == "TOC" {
|
||||||
a4.Xsmclas = XMC_TC0
|
a4.Xsmclas = XMC_TC0
|
||||||
} else {
|
} else {
|
||||||
a4.Xsmclas = XMC_RW
|
a4.Xsmclas = XMC_RW
|
||||||
@ -955,20 +960,20 @@ func putaixsym(ctxt *Link, x *sym.Symbol, str string, t SymbolType, addr int64)
|
|||||||
a4.Xsmtyp |= XTY_CM
|
a4.Xsmtyp |= XTY_CM
|
||||||
}
|
}
|
||||||
|
|
||||||
a4.Xsmtyp |= uint8(xcoffAlign(x, t) << 3)
|
a4.Xsmtyp |= uint8(xcoffAlign(ldr, x, t) << 3)
|
||||||
|
|
||||||
syms = append(syms, a4)
|
syms = append(syms, a4)
|
||||||
|
|
||||||
case UndefinedSym:
|
case UndefinedSym:
|
||||||
if x.Type != sym.SDYNIMPORT && x.Type != sym.SHOSTOBJ && x.Type != sym.SUNDEFEXT {
|
if ty := ldr.SymType(x); ty != sym.SDYNIMPORT && ty != sym.SHOSTOBJ && ty != sym.SUNDEFEXT {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s := &XcoffSymEnt64{
|
s := &XcoffSymEnt64{
|
||||||
Nsclass: C_EXT,
|
Nsclass: C_EXT,
|
||||||
Noffset: uint32(xfile.stringTable.add(str)),
|
Noffset: uint32(xfile.stringTable.add(name)),
|
||||||
Nnumaux: 1,
|
Nnumaux: 1,
|
||||||
}
|
}
|
||||||
x.Dynid = int32(xfile.symbolCount)
|
ldr.SetSymDynid(x, int32(xfile.symbolCount))
|
||||||
syms = append(syms, s)
|
syms = append(syms, s)
|
||||||
|
|
||||||
a4 := &XcoffAuxCSect64{
|
a4 := &XcoffAuxCSect64{
|
||||||
@ -977,7 +982,7 @@ func putaixsym(ctxt *Link, x *sym.Symbol, str string, t SymbolType, addr int64)
|
|||||||
Xsmtyp: XTY_ER | XTY_IMP,
|
Xsmtyp: XTY_ER | XTY_IMP,
|
||||||
}
|
}
|
||||||
|
|
||||||
if x.Name == "__n_pthreads" {
|
if ldr.SymName(x) == "__n_pthreads" {
|
||||||
// Currently, all imported symbols made by cgo_import_dynamic are
|
// Currently, all imported symbols made by cgo_import_dynamic are
|
||||||
// syscall functions, except __n_pthreads which is a variable.
|
// syscall functions, except __n_pthreads which is a variable.
|
||||||
// TODO(aix): Find a way to detect variables imported by cgo.
|
// TODO(aix): Find a way to detect variables imported by cgo.
|
||||||
@ -989,16 +994,16 @@ func putaixsym(ctxt *Link, x *sym.Symbol, str string, t SymbolType, addr int64)
|
|||||||
case TLSSym:
|
case TLSSym:
|
||||||
s := &XcoffSymEnt64{
|
s := &XcoffSymEnt64{
|
||||||
Nsclass: C_EXT,
|
Nsclass: C_EXT,
|
||||||
Noffset: uint32(xfile.stringTable.add(str)),
|
Noffset: uint32(xfile.stringTable.add(name)),
|
||||||
Nscnum: xfile.getXCOFFscnum(x.Sect),
|
Nscnum: xfile.getXCOFFscnum(ldr.SymSect(x)),
|
||||||
Nvalue: uint64(x.Value),
|
Nvalue: uint64(ldr.SymValue(x)),
|
||||||
Nnumaux: 1,
|
Nnumaux: 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
x.Dynid = int32(xfile.symbolCount)
|
ldr.SetSymDynid(x, int32(xfile.symbolCount))
|
||||||
syms = append(syms, s)
|
syms = append(syms, s)
|
||||||
|
|
||||||
size := uint64(x.Size)
|
size := uint64(ldr.SymSize(x))
|
||||||
a4 := &XcoffAuxCSect64{
|
a4 := &XcoffAuxCSect64{
|
||||||
Xauxtype: _AUX_CSECT,
|
Xauxtype: _AUX_CSECT,
|
||||||
Xsmclas: XMC_UL,
|
Xsmclas: XMC_UL,
|
||||||
@ -1019,18 +1024,114 @@ func putaixsym(ctxt *Link, x *sym.Symbol, str string, t SymbolType, addr int64)
|
|||||||
// It will be written in out file in Asmbxcoff, because it must be
|
// It will be written in out file in Asmbxcoff, because it must be
|
||||||
// at the very end, especially after relocation sections which needs symbols' index.
|
// at the very end, especially after relocation sections which needs symbols' index.
|
||||||
func (f *xcoffFile) asmaixsym(ctxt *Link) {
|
func (f *xcoffFile) asmaixsym(ctxt *Link) {
|
||||||
|
ldr := ctxt.loader
|
||||||
// Get correct size for symbols wrapping others symbols like go.string.*
|
// Get correct size for symbols wrapping others symbols like go.string.*
|
||||||
// sym.Size can be used directly as the symbols have already been written.
|
// sym.Size can be used directly as the symbols have already been written.
|
||||||
for name, size := range outerSymSize {
|
for name, size := range outerSymSize {
|
||||||
sym := ctxt.Syms.ROLookup(name, 0)
|
sym := ldr.Lookup(name, 0)
|
||||||
if sym == nil {
|
if sym == 0 {
|
||||||
Errorf(nil, "unknown outer symbol with name %s", name)
|
Errorf(nil, "unknown outer symbol with name %s", name)
|
||||||
} else {
|
} else {
|
||||||
sym.Size = size
|
s := ldr.MakeSymbolUpdater(sym)
|
||||||
|
s.SetSize(size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
genasmsym(ctxt, putaixsym)
|
// These symbols won't show up in the first loop below because we
|
||||||
|
// skip sym.STEXT symbols. Normal sym.STEXT symbols are emitted by walking textp.
|
||||||
|
s := ldr.Lookup("runtime.text", 0)
|
||||||
|
if ldr.SymType(s) == sym.STEXT {
|
||||||
|
// We've already included this symbol in ctxt.Textp on AIX with external linker.
|
||||||
|
// See data.go:/textaddress
|
||||||
|
if !ctxt.IsExternal() {
|
||||||
|
putaixsym(ctxt, s, TextSym)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
n := 1
|
||||||
|
// Generate base addresses for all text sections if there are multiple
|
||||||
|
for _, sect := range Segtext.Sections[1:] {
|
||||||
|
if sect.Name != ".text" || ctxt.IsExternal() {
|
||||||
|
// On AIX, runtime.text.X are symbols already in the symtab.
|
||||||
|
break
|
||||||
|
}
|
||||||
|
s = ldr.Lookup(fmt.Sprintf("runtime.text.%d", n), 0)
|
||||||
|
if s == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if ldr.SymType(s) == sym.STEXT {
|
||||||
|
putaixsym(ctxt, s, TextSym)
|
||||||
|
}
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
|
||||||
|
s = ldr.Lookup("runtime.etext", 0)
|
||||||
|
if ldr.SymType(s) == sym.STEXT {
|
||||||
|
// We've already included this symbol in ctxt.Textp
|
||||||
|
// on AIX with external linker.
|
||||||
|
// See data.go:/textaddress
|
||||||
|
if !ctxt.IsExternal() {
|
||||||
|
putaixsym(ctxt, s, TextSym)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldBeInSymbolTable := func(s loader.Sym, name string) bool {
|
||||||
|
if name == ".go.buildinfo" {
|
||||||
|
// On AIX, .go.buildinfo must be in the symbol table as
|
||||||
|
// it has relocations.
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if ldr.AttrNotInSymbolTable(s) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (name == "" || name[0] == '.') && !ldr.IsFileLocal(s) && name != ".TOC." {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
for s, nsym := loader.Sym(1), loader.Sym(ldr.NSym()); s < nsym; s++ {
|
||||||
|
if !shouldBeInSymbolTable(s, ldr.SymName(s)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
st := ldr.SymType(s)
|
||||||
|
switch {
|
||||||
|
case st == sym.STLSBSS:
|
||||||
|
if ctxt.IsExternal() {
|
||||||
|
putaixsym(ctxt, s, TLSSym)
|
||||||
|
}
|
||||||
|
|
||||||
|
case st == sym.SBSS, st == sym.SNOPTRBSS, st == sym.SLIBFUZZER_EXTRA_COUNTER:
|
||||||
|
if ldr.AttrReachable(s) {
|
||||||
|
data := ldr.Data(s)
|
||||||
|
if len(data) > 0 {
|
||||||
|
ldr.Errorf(s, "should not be bss (size=%d type=%v special=%v)", len(data), ldr.SymType(s), ldr.AttrSpecial(s))
|
||||||
|
}
|
||||||
|
putaixsym(ctxt, s, BSSSym)
|
||||||
|
}
|
||||||
|
|
||||||
|
case st >= sym.SELFRXSECT && st < sym.SXREF: // data sections handled in dodata
|
||||||
|
if ldr.AttrReachable(s) {
|
||||||
|
putaixsym(ctxt, s, DataSym)
|
||||||
|
}
|
||||||
|
|
||||||
|
case st == sym.SUNDEFEXT:
|
||||||
|
putaixsym(ctxt, s, UndefinedSym)
|
||||||
|
|
||||||
|
case st == sym.SDYNIMPORT:
|
||||||
|
if ldr.AttrReachable(s) {
|
||||||
|
putaixsym(ctxt, s, UndefinedSym)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range ctxt.Textp2 {
|
||||||
|
putaixsym(ctxt, s, TextSym)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctxt.Debugvlog != 0 || *flagN {
|
||||||
|
ctxt.Logf("symsize = %d\n", uint32(Symsize))
|
||||||
|
}
|
||||||
xfile.updatePreviousFile(ctxt, true)
|
xfile.updatePreviousFile(ctxt, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1264,6 +1365,7 @@ func (f *xcoffFile) writeLdrScn(ctxt *Link, globalOff uint64) {
|
|||||||
Lsymoff: LDHDRSZ_64,
|
Lsymoff: LDHDRSZ_64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ldr := ctxt.loader
|
||||||
/* Symbol table */
|
/* Symbol table */
|
||||||
for _, s := range f.loaderSymbols {
|
for _, s := range f.loaderSymbols {
|
||||||
lds := &XcoffLdSym64{
|
lds := &XcoffLdSym64{
|
||||||
@ -1271,19 +1373,19 @@ func (f *xcoffFile) writeLdrScn(ctxt *Link, globalOff uint64) {
|
|||||||
Lsmtype: s.smtype,
|
Lsmtype: s.smtype,
|
||||||
Lsmclas: s.smclas,
|
Lsmclas: s.smclas,
|
||||||
}
|
}
|
||||||
sym := ctxt.loader.Syms[s.sym]
|
sym := s.sym
|
||||||
switch s.smtype {
|
switch s.smtype {
|
||||||
default:
|
default:
|
||||||
Errorf(sym, "unexpected loader symbol type: 0x%x", s.smtype)
|
ldr.Errorf(sym, "unexpected loader symbol type: 0x%x", s.smtype)
|
||||||
case XTY_ENT | XTY_SD:
|
case XTY_ENT | XTY_SD:
|
||||||
lds.Lvalue = uint64(sym.Value)
|
lds.Lvalue = uint64(ldr.SymValue(sym))
|
||||||
lds.Lscnum = f.getXCOFFscnum(sym.Sect)
|
lds.Lscnum = f.getXCOFFscnum(ldr.SymSect(sym))
|
||||||
case XTY_IMP:
|
case XTY_IMP:
|
||||||
lds.Lifile = int32(f.dynLibraries[sym.Dynimplib()] + 1)
|
lds.Lifile = int32(f.dynLibraries[ldr.SymDynimplib(sym)] + 1)
|
||||||
}
|
}
|
||||||
ldstr := &XcoffLdStr64{
|
ldstr := &XcoffLdStr64{
|
||||||
size: uint16(len(sym.Name) + 1), // + null terminator
|
size: uint16(len(ldr.SymName(sym)) + 1), // + null terminator
|
||||||
name: sym.Name,
|
name: ldr.SymName(sym),
|
||||||
}
|
}
|
||||||
stlen += uint32(2 + ldstr.size) // 2 = sizeof ldstr.size
|
stlen += uint32(2 + ldstr.size) // 2 = sizeof ldstr.size
|
||||||
symtab = append(symtab, lds)
|
symtab = append(symtab, lds)
|
||||||
@ -1296,11 +1398,11 @@ func (f *xcoffFile) writeLdrScn(ctxt *Link, globalOff uint64) {
|
|||||||
off := hdr.Lrldoff // current offset is the same of reloc offset
|
off := hdr.Lrldoff // current offset is the same of reloc offset
|
||||||
|
|
||||||
/* Reloc */
|
/* Reloc */
|
||||||
ep := ctxt.Syms.ROLookup(*flagEntrySymbol, 0)
|
ep := ldr.Lookup(*flagEntrySymbol, 0)
|
||||||
xldr := &XcoffLdRel64{
|
xldr := &XcoffLdRel64{
|
||||||
Lvaddr: uint64(ep.Value),
|
Lvaddr: uint64(ldr.SymValue(ep)),
|
||||||
Lrtype: 0x3F00,
|
Lrtype: 0x3F00,
|
||||||
Lrsecnm: f.getXCOFFscnum(ep.Sect),
|
Lrsecnm: f.getXCOFFscnum(ldr.SymSect(ep)),
|
||||||
Lsymndx: 0,
|
Lsymndx: 0,
|
||||||
}
|
}
|
||||||
off += 16
|
off += 16
|
||||||
@ -1308,18 +1410,18 @@ func (f *xcoffFile) writeLdrScn(ctxt *Link, globalOff uint64) {
|
|||||||
|
|
||||||
off += uint64(16 * len(f.loaderReloc))
|
off += uint64(16 * len(f.loaderReloc))
|
||||||
for _, r := range f.loaderReloc {
|
for _, r := range f.loaderReloc {
|
||||||
symp := r.sym
|
symp := r.sym2
|
||||||
if symp == nil {
|
if symp == 0 {
|
||||||
symp = ctxt.loader.Syms[r.sym2]
|
panic("unexpected 0 sym value")
|
||||||
}
|
}
|
||||||
xldr = &XcoffLdRel64{
|
xldr = &XcoffLdRel64{
|
||||||
Lvaddr: uint64(symp.Value + int64(r.roff)),
|
Lvaddr: uint64(ldr.SymValue(symp) + int64(r.roff)),
|
||||||
Lrtype: r.rtype,
|
Lrtype: r.rtype,
|
||||||
Lsymndx: r.symndx,
|
Lsymndx: r.symndx,
|
||||||
}
|
}
|
||||||
|
|
||||||
if symp.Sect != nil {
|
if ldr.SymSect(symp) != nil {
|
||||||
xldr.Lrsecnm = f.getXCOFFscnum(symp.Sect)
|
xldr.Lrsecnm = f.getXCOFFscnum(ldr.SymSect(symp))
|
||||||
}
|
}
|
||||||
|
|
||||||
reloctab = append(reloctab, xldr)
|
reloctab = append(reloctab, xldr)
|
||||||
@ -1416,6 +1518,7 @@ func (f *xcoffFile) writeFileHeader(ctxt *Link) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ctxt.BuildMode == BuildModeExe && ctxt.LinkMode == LinkInternal {
|
if ctxt.BuildMode == BuildModeExe && ctxt.LinkMode == LinkInternal {
|
||||||
|
ldr := ctxt.loader
|
||||||
f.xfhdr.Fopthdr = AOUTHSZ_EXEC64
|
f.xfhdr.Fopthdr = AOUTHSZ_EXEC64
|
||||||
f.xfhdr.Fflags = F_EXEC
|
f.xfhdr.Fflags = F_EXEC
|
||||||
|
|
||||||
@ -1423,12 +1526,12 @@ func (f *xcoffFile) writeFileHeader(ctxt *Link) {
|
|||||||
f.xahdr.Ovstamp = 1 // based on dump -o
|
f.xahdr.Ovstamp = 1 // based on dump -o
|
||||||
f.xahdr.Omagic = 0x10b
|
f.xahdr.Omagic = 0x10b
|
||||||
copy(f.xahdr.Omodtype[:], "1L")
|
copy(f.xahdr.Omodtype[:], "1L")
|
||||||
entry := ctxt.Syms.ROLookup(*flagEntrySymbol, 0)
|
entry := ldr.Lookup(*flagEntrySymbol, 0)
|
||||||
f.xahdr.Oentry = uint64(entry.Value)
|
f.xahdr.Oentry = uint64(ldr.SymValue(entry))
|
||||||
f.xahdr.Osnentry = f.getXCOFFscnum(entry.Sect)
|
f.xahdr.Osnentry = f.getXCOFFscnum(ldr.SymSect(entry))
|
||||||
toc := ctxt.Syms.ROLookup("TOC", 0)
|
toc := ldr.Lookup("TOC", 0)
|
||||||
f.xahdr.Otoc = uint64(toc.Value)
|
f.xahdr.Otoc = uint64(ldr.SymValue(toc))
|
||||||
f.xahdr.Osntoc = f.getXCOFFscnum(toc.Sect)
|
f.xahdr.Osntoc = f.getXCOFFscnum(ldr.SymSect(toc))
|
||||||
|
|
||||||
f.xahdr.Oalgntext = int16(logBase2(int(Funcalign)))
|
f.xahdr.Oalgntext = int16(logBase2(int(Funcalign)))
|
||||||
f.xahdr.Oalgndata = 0x5
|
f.xahdr.Oalgndata = 0x5
|
||||||
@ -1534,19 +1637,6 @@ func Asmbxcoff(ctxt *Link, fileoff int64) {
|
|||||||
xcoffwrite(ctxt)
|
xcoffwrite(ctxt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// byOffset is used to sort relocations by offset
|
|
||||||
type byOffset []sym.Reloc
|
|
||||||
|
|
||||||
func (x byOffset) Len() int { return len(x) }
|
|
||||||
|
|
||||||
func (x byOffset) Swap(i, j int) {
|
|
||||||
x[i], x[j] = x[j], x[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x byOffset) Less(i, j int) bool {
|
|
||||||
return x[i].Off < x[j].Off
|
|
||||||
}
|
|
||||||
|
|
||||||
// emitRelocations emits relocation entries for go.o in external linking.
|
// emitRelocations emits relocation entries for go.o in external linking.
|
||||||
func (f *xcoffFile) emitRelocations(ctxt *Link, fileoff int64) {
|
func (f *xcoffFile) emitRelocations(ctxt *Link, fileoff int64) {
|
||||||
ctxt.Out.SeekSet(fileoff)
|
ctxt.Out.SeekSet(fileoff)
|
||||||
@ -1554,9 +1644,10 @@ func (f *xcoffFile) emitRelocations(ctxt *Link, fileoff int64) {
|
|||||||
ctxt.Out.Write8(0)
|
ctxt.Out.Write8(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ldr := ctxt.loader
|
||||||
// relocsect relocates symbols from first in section sect, and returns
|
// relocsect relocates symbols from first in section sect, and returns
|
||||||
// the total number of relocations emitted.
|
// the total number of relocations emitted.
|
||||||
relocsect := func(sect *sym.Section, syms []*sym.Symbol, base uint64) uint32 {
|
relocsect := func(sect *sym.Section, syms []loader.Sym, base uint64) uint32 {
|
||||||
// ctxt.Logf("%s 0x%x\n", sect.Name, sect.Vaddr)
|
// ctxt.Logf("%s 0x%x\n", sect.Name, sect.Vaddr)
|
||||||
// If main section has no bits, nothing to relocate.
|
// If main section has no bits, nothing to relocate.
|
||||||
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
|
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
|
||||||
@ -1564,42 +1655,45 @@ func (f *xcoffFile) emitRelocations(ctxt *Link, fileoff int64) {
|
|||||||
}
|
}
|
||||||
sect.Reloff = uint64(ctxt.Out.Offset())
|
sect.Reloff = uint64(ctxt.Out.Offset())
|
||||||
for i, s := range syms {
|
for i, s := range syms {
|
||||||
if !s.Attr.Reachable() {
|
if !ldr.AttrReachable(s) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if uint64(s.Value) >= sect.Vaddr {
|
if uint64(ldr.SymValue(s)) >= sect.Vaddr {
|
||||||
syms = syms[i:]
|
syms = syms[i:]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
eaddr := int64(sect.Vaddr + sect.Length)
|
eaddr := int64(sect.Vaddr + sect.Length)
|
||||||
for _, s := range syms {
|
for _, s := range syms {
|
||||||
if !s.Attr.Reachable() {
|
if !ldr.AttrReachable(s) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if s.Value >= int64(eaddr) {
|
if ldr.SymValue(s) >= int64(eaddr) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relocation must be ordered by address, so s.R is ordered by Off.
|
// Relocation must be ordered by address, so create a list of sorted indices.
|
||||||
sort.Sort(byOffset(s.R))
|
relocs := ldr.ExtRelocs(s)
|
||||||
|
sorted := make([]int, relocs.Count())
|
||||||
|
for i := 0; i < relocs.Count(); i++ {
|
||||||
|
sorted[i] = i
|
||||||
|
}
|
||||||
|
sort.Slice(sorted, func(i, j int) bool {
|
||||||
|
return relocs.At(sorted[i]).Off() < relocs.At(sorted[j]).Off()
|
||||||
|
})
|
||||||
|
|
||||||
for ri := range s.R {
|
for _, ri := range sorted {
|
||||||
|
r := relocs.At(ri)
|
||||||
|
|
||||||
r := &s.R[ri]
|
if r.Xsym == 0 {
|
||||||
|
ldr.Errorf(s, "missing xsym in relocation")
|
||||||
if r.Done {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if r.Xsym == nil {
|
if ldr.SymDynid(r.Xsym) < 0 {
|
||||||
Errorf(s, "missing xsym in relocation")
|
ldr.Errorf(s, "reloc %s to non-coff symbol %s (outer=%s) %d %d", r.Type(), ldr.SymName(r.Sym()), ldr.SymName(r.Xsym), ldr.SymType(r.Sym()), ldr.SymDynid(r.Xsym))
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
if r.Xsym.Dynid < 0 {
|
if !thearch.Xcoffreloc1(ctxt.Arch, ctxt.Out, ldr, s, r, int64(uint64(ldr.SymValue(s)+int64(r.Off()))-base)) {
|
||||||
Errorf(s, "reloc %s to non-coff symbol %s (outer=%s) %d %d", r.Type.String(), r.Sym.Name, r.Xsym.Name, r.Sym.Type, r.Xsym.Dynid)
|
ldr.Errorf(s, "unsupported obj reloc %d(%s)/%d to %s", r.Type(), r.Type(), r.Siz(), ldr.SymName(r.Sym()))
|
||||||
}
|
|
||||||
if !thearch.Xcoffreloc1(ctxt.Arch, ctxt.Out, s, r, int64(uint64(s.Value+int64(r.Off))-base)) {
|
|
||||||
Errorf(s, "unsupported obj reloc %d(%s)/%d to %s", r.Type, r.Type.String(), r.Siz, r.Sym.Name)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1619,9 +1713,9 @@ func (f *xcoffFile) emitRelocations(ctxt *Link, fileoff int64) {
|
|||||||
for _, seg := range s.segs {
|
for _, seg := range s.segs {
|
||||||
for _, sect := range seg.Sections {
|
for _, sect := range seg.Sections {
|
||||||
if sect.Name == ".text" {
|
if sect.Name == ".text" {
|
||||||
n += relocsect(sect, ctxt.Textp, 0)
|
n += relocsect(sect, ctxt.Textp2, 0)
|
||||||
} else {
|
} else {
|
||||||
n += relocsect(sect, ctxt.datap, 0)
|
n += relocsect(sect, ctxt.datap2, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1631,9 +1725,9 @@ func (f *xcoffFile) emitRelocations(ctxt *Link, fileoff int64) {
|
|||||||
dwarfLoop:
|
dwarfLoop:
|
||||||
for i := 0; i < len(Segdwarf.Sections); i++ {
|
for i := 0; i < len(Segdwarf.Sections); i++ {
|
||||||
sect := Segdwarf.Sections[i]
|
sect := Segdwarf.Sections[i]
|
||||||
si := dwarfp[i]
|
si := dwarfp2[i]
|
||||||
if si.secSym() != sect.Sym ||
|
if si.secSym() != loader.Sym(sect.Sym2) ||
|
||||||
si.secSym().Sect != sect {
|
ldr.SymSect(si.secSym()) != sect {
|
||||||
panic("inconsistency between dwarfp and Segdwarf")
|
panic("inconsistency between dwarfp and Segdwarf")
|
||||||
}
|
}
|
||||||
for _, xcoffSect := range f.sections {
|
for _, xcoffSect := range f.sections {
|
||||||
@ -1655,17 +1749,16 @@ func xcoffCreateExportFile(ctxt *Link) (fname string) {
|
|||||||
fname = filepath.Join(*flagTmpdir, "export_file.exp")
|
fname = filepath.Join(*flagTmpdir, "export_file.exp")
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
|
||||||
for _, s := range ctxt.loader.Syms {
|
ldr := ctxt.loader
|
||||||
if s == nil {
|
for s, nsym := loader.Sym(1), loader.Sym(ldr.NSym()); s < nsym; s++ {
|
||||||
|
if !ldr.AttrCgoExport(s) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !s.Attr.CgoExport() {
|
extname := ldr.SymExtname(s)
|
||||||
|
if !strings.HasPrefix(extname, "._cgoexp_") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !strings.HasPrefix(s.Extname(), "._cgoexp_") {
|
if ldr.SymVersion(s) != 0 {
|
||||||
continue
|
|
||||||
}
|
|
||||||
if s.Version != 0 {
|
|
||||||
continue // Only export version 0 symbols. See the comment in doxcoff.
|
continue // Only export version 0 symbols. See the comment in doxcoff.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1673,7 +1766,7 @@ func xcoffCreateExportFile(ctxt *Link) (fname string) {
|
|||||||
// exported by cgo.
|
// exported by cgo.
|
||||||
// The corresponding Go symbol is:
|
// The corresponding Go symbol is:
|
||||||
// _cgoexp_hashcode_symname.
|
// _cgoexp_hashcode_symname.
|
||||||
name := strings.SplitN(s.Extname(), "_", 4)[3]
|
name := strings.SplitN(extname, "_", 4)[3]
|
||||||
|
|
||||||
buf.Write([]byte(name + "\n"))
|
buf.Write([]byte(name + "\n"))
|
||||||
}
|
}
|
||||||
@ -1684,5 +1777,4 @@ func xcoffCreateExportFile(ctxt *Link) (fname string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return fname
|
return fname
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -403,22 +403,22 @@ func addelfdynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s lo
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func xcoffreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
|
func xcoffreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtRelocView, sectoff int64) bool {
|
||||||
rs := r.Xsym
|
rs := r.Xsym
|
||||||
|
|
||||||
emitReloc := func(v uint16, off uint64) {
|
emitReloc := func(v uint16, off uint64) {
|
||||||
out.Write64(uint64(sectoff) + off)
|
out.Write64(uint64(sectoff) + off)
|
||||||
out.Write32(uint32(rs.Dynid))
|
out.Write32(uint32(ldr.SymDynid(rs)))
|
||||||
out.Write16(v)
|
out.Write16(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
var v uint16
|
var v uint16
|
||||||
switch r.Type {
|
switch r.Type() {
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
case objabi.R_ADDR, objabi.R_DWARFSECREF:
|
case objabi.R_ADDR, objabi.R_DWARFSECREF:
|
||||||
v = ld.XCOFF_R_POS
|
v = ld.XCOFF_R_POS
|
||||||
if r.Siz == 4 {
|
if r.Siz() == 4 {
|
||||||
v |= 0x1F << 8
|
v |= 0x1F << 8
|
||||||
} else {
|
} else {
|
||||||
v |= 0x3F << 8
|
v |= 0x3F << 8
|
||||||
@ -431,7 +431,7 @@ func xcoffreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se
|
|||||||
case objabi.R_POWER_TLS_LE:
|
case objabi.R_POWER_TLS_LE:
|
||||||
emitReloc(ld.XCOFF_R_TLS_LE|0x0F<<8, 2)
|
emitReloc(ld.XCOFF_R_TLS_LE|0x0F<<8, 2)
|
||||||
case objabi.R_CALLPOWER:
|
case objabi.R_CALLPOWER:
|
||||||
if r.Siz != 4 {
|
if r.Siz() != 4 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
emitReloc(ld.XCOFF_R_RBR|0x19<<8, 0)
|
emitReloc(ld.XCOFF_R_RBR|0x19<<8, 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user