"cmd/link/internal/loader"
"cmd/link/internal/sym"
"encoding/binary"
+ "fmt"
"io/ioutil"
"math/bits"
"path/filepath"
// xcoffLoaderReloc holds information about a relocation made by the loader.
type xcoffLoaderReloc struct {
- sym *sym.Symbol
sym2 loader.Sym
roff int32
rtype uint16
}
// xcoffAlign returns the log base 2 of the symbol's alignment.
-func xcoffAlign(x *sym.Symbol, t SymbolType) uint8 {
- align := x.Align
+func xcoffAlign(ldr *loader.Loader, x loader.Sym, t SymbolType) uint8 {
+ align := ldr.SymAlign(x)
if align == 0 {
if t == TextSym {
align = int32(Funcalign)
} else {
- align = symalign(x)
+ align = symalign2(ldr, x)
}
}
return logBase2(int(align))
// Currently, a new file is in fact a new package. It seems to be OK, but it might change
// in the future.
func (f *xcoffFile) writeSymbolNewFile(ctxt *Link, name string, firstEntry uint64, extnum int16) {
+ ldr := ctxt.loader
/* C_FILE */
s := &XcoffSymEnt64{
Noffset: uint32(f.stringTable.add(".file")),
dwsize = getDwsectCUSize(sect.Name, name)
// .debug_abbrev is common to all packages and not found with the previous function
if sect.Name == ".debug_abbrev" {
- s := ctxt.Syms.ROLookup(sect.Name, 0)
- dwsize = uint64(s.Size)
+ dwsize = uint64(ldr.SymSize(loader.Sym(sect.Sym2)))
}
} else {
// Dwarf relocations need the symbol number of .dw* symbols.
// It doesn't need to know it for each package, one is enough.
// currSymSrcFile.csectAux == nil means first package.
- dws := ctxt.Syms.Lookup(sect.Name, 0)
- dws.Dynid = int32(f.symbolCount)
+ ldr.SetSymDynid(loader.Sym(sect.Sym2), int32(f.symbolCount))
if sect.Name == ".debug_frame" && ctxt.LinkMode != LinkExternal {
// CIE size must be added to the first package.
// Write symbol representing a .text function.
// The symbol table is split with C_FILE corresponding to each package
// 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.
syms := []xcoffSym{}
// 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
// in the current file.
// 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 currSymSrcFile.name != "" {
Exitf("undefined global symbol found inside another file")
}
} else {
// 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 {
// update previous file values
xfile.updatePreviousFile(ctxt, false)
- currSymSrcFile.name = symPkg(ctxt, x)
- f.writeSymbolNewFile(ctxt, symPkg(ctxt, x), uint64(x.Value), xfile.getXCOFFscnum(x.Sect))
+ currSymSrcFile.name = ldr.SymPkg(x)
+ f.writeSymbolNewFile(ctxt, ldr.SymPkg(x), uint64(ldr.SymValue(x)), xfile.getXCOFFscnum(ldr.SymSect(x)))
} else {
// With external linking, ld will crash if there is several
// .FILE and DWARF debugging enable, somewhere during
// TODO(aix); remove once ld has been fixed or the triggering
// relocation has been found and fixed.
if currSymSrcFile.name == "" {
- currSymSrcFile.name = symPkg(ctxt, x)
- f.writeSymbolNewFile(ctxt, "go_functions", uint64(x.Value), xfile.getXCOFFscnum(x.Sect))
+ currSymSrcFile.name = ldr.SymPkg(x)
+ f.writeSymbolNewFile(ctxt, "go_functions", uint64(ldr.SymValue(x)), xfile.getXCOFFscnum(ldr.SymSect(x)))
}
}
s := &XcoffSymEnt64{
Nsclass: C_EXT,
- Noffset: uint32(xfile.stringTable.add(x.Extname())),
- Nvalue: uint64(x.Value),
- Nscnum: f.getXCOFFscnum(x.Sect),
+ Noffset: uint32(xfile.stringTable.add(ldr.SymExtname(x))),
+ Nvalue: uint64(ldr.SymValue(x)),
+ Nscnum: f.getXCOFFscnum(ldr.SymSect(x)),
Ntype: SYM_TYPE_FUNC,
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
}
- x.Dynid = int32(xfile.symbolCount)
+ ldr.SetSymDynid(x, int32(xfile.symbolCount))
syms = append(syms, s)
// Update current csect size
- currSymSrcFile.csectSize += x.Size
+ currSymSrcFile.csectSize += ldr.SymSize(x)
// create auxiliary entries
a2 := &XcoffAuxFcn64{
- Xfsize: uint32(x.Size),
+ Xfsize: uint32(ldr.SymSize(x)),
Xlnnoptr: 0, // TODO
Xendndx: xfile.symbolCount + 3, // this symbol + 2 aux entries
Xauxtype: _AUX_FCN,
Xsmtyp: XTY_LD, // label definition (based on C)
Xauxtype: _AUX_CSECT,
}
- a4.Xsmtyp |= uint8(xcoffAlign(x, TextSym) << 3)
+ a4.Xsmtyp |= uint8(xcoffAlign(ldr, x, TextSym) << 3)
syms = append(syms, a4)
return syms
}
// 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
// Can be a symbol entry or a auxiliary entry
syms := []xcoffSym{}
+ ldr := ctxt.loader
+ name := ldr.SymName(x)
+ if t == UndefinedSym {
+ name = ldr.SymExtname(x)
+ }
+
switch t {
default:
return
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
syms = xfile.writeSymbolFunc(ctxt, x)
} else {
// Only runtime.text and runtime.etext come through this way
- if x.Name != "runtime.text" && x.Name != "runtime.etext" && x.Name != "go.buildid" {
- Exitf("putaixsym: unknown text symbol %s", x.Name)
+ if name != "runtime.text" && name != "runtime.etext" && name != "go.buildid" {
+ Exitf("putaixsym: unknown text symbol %s", name)
}
s := &XcoffSymEnt64{
Nsclass: C_HIDEXT,
- Noffset: uint32(xfile.stringTable.add(str)),
- Nvalue: uint64(x.Value),
- Nscnum: xfile.getXCOFFscnum(x.Sect),
+ Noffset: uint32(xfile.stringTable.add(name)),
+ Nvalue: uint64(ldr.SymValue(x)),
+ Nscnum: xfile.getXCOFFscnum(ldr.SymSect(x)),
Ntype: SYM_TYPE_FUNC,
Nnumaux: 1,
}
- x.Dynid = int32(xfile.symbolCount)
+ ldr.SetSymDynid(x, int32(xfile.symbolCount))
syms = append(syms, s)
- size := uint64(x.Size)
+ size := uint64(ldr.SymSize(x))
a4 := &XcoffAuxCSect64{
Xauxtype: _AUX_CSECT,
Xscnlenlo: uint32(size & 0xFFFFFFFF),
Xsmclas: XMC_PR,
Xsmtyp: XTY_SD,
}
- a4.Xsmtyp |= uint8(xcoffAlign(x, TextSym) << 3)
+ a4.Xsmtyp |= uint8(xcoffAlign(ldr, x, TextSym) << 3)
syms = append(syms, a4)
-
}
case DataSym, BSSSym:
s := &XcoffSymEnt64{
Nsclass: C_EXT,
- Noffset: uint32(xfile.stringTable.add(str)),
- Nvalue: uint64(x.Value),
- Nscnum: xfile.getXCOFFscnum(x.Sect),
+ Noffset: uint32(xfile.stringTable.add(name)),
+ Nvalue: uint64(ldr.SymValue(x)),
+ Nscnum: xfile.getXCOFFscnum(ldr.SymSect(x)),
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
// which are related to the assembly generated
// to access such symbols.
s.Nsclass = C_HIDEXT
}
- x.Dynid = int32(xfile.symbolCount)
+ ldr.SetSymDynid(x, int32(xfile.symbolCount))
syms = append(syms, s)
// Create auxiliary entry
// the data and bss symbols of one file/package.
// However, it's easier to just have a csect for each symbol.
// It might change
- size := uint64(x.Size)
+ size := uint64(ldr.SymSize(x))
a4 := &XcoffAuxCSect64{
Xauxtype: _AUX_CSECT,
Xscnlenlo: uint32(size & 0xFFFFFFFF),
Xscnlenhi: uint32(size >> 32),
}
- if x.Type >= sym.STYPE && x.Type <= sym.SPCLNTAB {
- if ctxt.LinkMode == LinkExternal && strings.HasPrefix(x.Sect.Name, ".data.rel.ro") {
+ if ty := ldr.SymType(x); ty >= sym.STYPE && ty <= sym.SPCLNTAB {
+ if ctxt.IsExternal() && strings.HasPrefix(ldr.SymSect(x).Name, ".data.rel.ro") {
// During external linking, read-only datas with relocation
// must be in .data.
a4.Xsmclas = XMC_RW
// Read only data
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
- } else if x.Name == "TOC" {
+ } else if ldr.SymName(x) == "TOC" {
a4.Xsmclas = XMC_TC0
} else {
a4.Xsmclas = XMC_RW
a4.Xsmtyp |= XTY_CM
}
- a4.Xsmtyp |= uint8(xcoffAlign(x, t) << 3)
+ a4.Xsmtyp |= uint8(xcoffAlign(ldr, x, t) << 3)
syms = append(syms, a4)
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
}
s := &XcoffSymEnt64{
Nsclass: C_EXT,
- Noffset: uint32(xfile.stringTable.add(str)),
+ Noffset: uint32(xfile.stringTable.add(name)),
Nnumaux: 1,
}
- x.Dynid = int32(xfile.symbolCount)
+ ldr.SetSymDynid(x, int32(xfile.symbolCount))
syms = append(syms, s)
a4 := &XcoffAuxCSect64{
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
// syscall functions, except __n_pthreads which is a variable.
// TODO(aix): Find a way to detect variables imported by cgo.
case TLSSym:
s := &XcoffSymEnt64{
Nsclass: C_EXT,
- Noffset: uint32(xfile.stringTable.add(str)),
- Nscnum: xfile.getXCOFFscnum(x.Sect),
- Nvalue: uint64(x.Value),
+ Noffset: uint32(xfile.stringTable.add(name)),
+ Nscnum: xfile.getXCOFFscnum(ldr.SymSect(x)),
+ Nvalue: uint64(ldr.SymValue(x)),
Nnumaux: 1,
}
- x.Dynid = int32(xfile.symbolCount)
+ ldr.SetSymDynid(x, int32(xfile.symbolCount))
syms = append(syms, s)
- size := uint64(x.Size)
+ size := uint64(ldr.SymSize(x))
a4 := &XcoffAuxCSect64{
Xauxtype: _AUX_CSECT,
Xsmclas: XMC_UL,
// 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.
func (f *xcoffFile) asmaixsym(ctxt *Link) {
+ ldr := ctxt.loader
// Get correct size for symbols wrapping others symbols like go.string.*
// sym.Size can be used directly as the symbols have already been written.
for name, size := range outerSymSize {
- sym := ctxt.Syms.ROLookup(name, 0)
- if sym == nil {
+ sym := ldr.Lookup(name, 0)
+ if sym == 0 {
Errorf(nil, "unknown outer symbol with name %s", name)
} else {
- sym.Size = size
+ s := ldr.MakeSymbolUpdater(sym)
+ s.SetSize(size)
+ }
+ }
+
+ // 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++
}
- genasmsym(ctxt, putaixsym)
+ 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)
}
Lsymoff: LDHDRSZ_64,
}
+ ldr := ctxt.loader
/* Symbol table */
for _, s := range f.loaderSymbols {
lds := &XcoffLdSym64{
Lsmtype: s.smtype,
Lsmclas: s.smclas,
}
- sym := ctxt.loader.Syms[s.sym]
+ sym := s.sym
switch s.smtype {
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:
- lds.Lvalue = uint64(sym.Value)
- lds.Lscnum = f.getXCOFFscnum(sym.Sect)
+ lds.Lvalue = uint64(ldr.SymValue(sym))
+ lds.Lscnum = f.getXCOFFscnum(ldr.SymSect(sym))
case XTY_IMP:
- lds.Lifile = int32(f.dynLibraries[sym.Dynimplib()] + 1)
+ lds.Lifile = int32(f.dynLibraries[ldr.SymDynimplib(sym)] + 1)
}
ldstr := &XcoffLdStr64{
- size: uint16(len(sym.Name) + 1), // + null terminator
- name: sym.Name,
+ size: uint16(len(ldr.SymName(sym)) + 1), // + null terminator
+ name: ldr.SymName(sym),
}
stlen += uint32(2 + ldstr.size) // 2 = sizeof ldstr.size
symtab = append(symtab, lds)
off := hdr.Lrldoff // current offset is the same of reloc offset
/* Reloc */
- ep := ctxt.Syms.ROLookup(*flagEntrySymbol, 0)
+ ep := ldr.Lookup(*flagEntrySymbol, 0)
xldr := &XcoffLdRel64{
- Lvaddr: uint64(ep.Value),
+ Lvaddr: uint64(ldr.SymValue(ep)),
Lrtype: 0x3F00,
- Lrsecnm: f.getXCOFFscnum(ep.Sect),
+ Lrsecnm: f.getXCOFFscnum(ldr.SymSect(ep)),
Lsymndx: 0,
}
off += 16
off += uint64(16 * len(f.loaderReloc))
for _, r := range f.loaderReloc {
- symp := r.sym
- if symp == nil {
- symp = ctxt.loader.Syms[r.sym2]
+ symp := r.sym2
+ if symp == 0 {
+ panic("unexpected 0 sym value")
}
xldr = &XcoffLdRel64{
- Lvaddr: uint64(symp.Value + int64(r.roff)),
+ Lvaddr: uint64(ldr.SymValue(symp) + int64(r.roff)),
Lrtype: r.rtype,
Lsymndx: r.symndx,
}
- if symp.Sect != nil {
- xldr.Lrsecnm = f.getXCOFFscnum(symp.Sect)
+ if ldr.SymSect(symp) != nil {
+ xldr.Lrsecnm = f.getXCOFFscnum(ldr.SymSect(symp))
}
reloctab = append(reloctab, xldr)
}
if ctxt.BuildMode == BuildModeExe && ctxt.LinkMode == LinkInternal {
+ ldr := ctxt.loader
f.xfhdr.Fopthdr = AOUTHSZ_EXEC64
f.xfhdr.Fflags = F_EXEC
f.xahdr.Ovstamp = 1 // based on dump -o
f.xahdr.Omagic = 0x10b
copy(f.xahdr.Omodtype[:], "1L")
- entry := ctxt.Syms.ROLookup(*flagEntrySymbol, 0)
- f.xahdr.Oentry = uint64(entry.Value)
- f.xahdr.Osnentry = f.getXCOFFscnum(entry.Sect)
- toc := ctxt.Syms.ROLookup("TOC", 0)
- f.xahdr.Otoc = uint64(toc.Value)
- f.xahdr.Osntoc = f.getXCOFFscnum(toc.Sect)
+ entry := ldr.Lookup(*flagEntrySymbol, 0)
+ f.xahdr.Oentry = uint64(ldr.SymValue(entry))
+ f.xahdr.Osnentry = f.getXCOFFscnum(ldr.SymSect(entry))
+ toc := ldr.Lookup("TOC", 0)
+ f.xahdr.Otoc = uint64(ldr.SymValue(toc))
+ f.xahdr.Osntoc = f.getXCOFFscnum(ldr.SymSect(toc))
f.xahdr.Oalgntext = int16(logBase2(int(Funcalign)))
f.xahdr.Oalgndata = 0x5
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.
func (f *xcoffFile) emitRelocations(ctxt *Link, fileoff int64) {
ctxt.Out.SeekSet(fileoff)
ctxt.Out.Write8(0)
}
+ ldr := ctxt.loader
// relocsect relocates symbols from first in section sect, and returns
// 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)
// If main section has no bits, nothing to relocate.
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
}
sect.Reloff = uint64(ctxt.Out.Offset())
for i, s := range syms {
- if !s.Attr.Reachable() {
+ if !ldr.AttrReachable(s) {
continue
}
- if uint64(s.Value) >= sect.Vaddr {
+ if uint64(ldr.SymValue(s)) >= sect.Vaddr {
syms = syms[i:]
break
}
}
eaddr := int64(sect.Vaddr + sect.Length)
for _, s := range syms {
- if !s.Attr.Reachable() {
+ if !ldr.AttrReachable(s) {
continue
}
- if s.Value >= int64(eaddr) {
+ if ldr.SymValue(s) >= int64(eaddr) {
break
}
- // Relocation must be ordered by address, so s.R is ordered by Off.
- sort.Sort(byOffset(s.R))
-
- for ri := range s.R {
+ // Relocation must be ordered by address, so create a list of sorted indices.
+ 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()
+ })
- r := &s.R[ri]
+ for _, ri := range sorted {
+ r := relocs.At(ri)
- if r.Done {
- continue
- }
- if r.Xsym == nil {
- Errorf(s, "missing xsym in relocation")
+ if r.Xsym == 0 {
+ ldr.Errorf(s, "missing xsym in relocation")
continue
}
- if r.Xsym.Dynid < 0 {
- 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)
+ if ldr.SymDynid(r.Xsym) < 0 {
+ 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))
}
- 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)
+ if !thearch.Xcoffreloc1(ctxt.Arch, ctxt.Out, ldr, s, r, int64(uint64(ldr.SymValue(s)+int64(r.Off()))-base)) {
+ ldr.Errorf(s, "unsupported obj reloc %d(%s)/%d to %s", r.Type(), r.Type(), r.Siz(), ldr.SymName(r.Sym()))
}
}
}
for _, seg := range s.segs {
for _, sect := range seg.Sections {
if sect.Name == ".text" {
- n += relocsect(sect, ctxt.Textp, 0)
+ n += relocsect(sect, ctxt.Textp2, 0)
} else {
- n += relocsect(sect, ctxt.datap, 0)
+ n += relocsect(sect, ctxt.datap2, 0)
}
}
}
dwarfLoop:
for i := 0; i < len(Segdwarf.Sections); i++ {
sect := Segdwarf.Sections[i]
- si := dwarfp[i]
- if si.secSym() != sect.Sym ||
- si.secSym().Sect != sect {
+ si := dwarfp2[i]
+ if si.secSym() != loader.Sym(sect.Sym2) ||
+ ldr.SymSect(si.secSym()) != sect {
panic("inconsistency between dwarfp and Segdwarf")
}
for _, xcoffSect := range f.sections {
fname = filepath.Join(*flagTmpdir, "export_file.exp")
var buf bytes.Buffer
- for _, s := range ctxt.loader.Syms {
- if s == nil {
- continue
- }
- if !s.Attr.CgoExport() {
+ ldr := ctxt.loader
+ for s, nsym := loader.Sym(1), loader.Sym(ldr.NSym()); s < nsym; s++ {
+ if !ldr.AttrCgoExport(s) {
continue
}
- if !strings.HasPrefix(s.Extname(), "._cgoexp_") {
+ extname := ldr.SymExtname(s)
+ if !strings.HasPrefix(extname, "._cgoexp_") {
continue
}
- if s.Version != 0 {
+ if ldr.SymVersion(s) != 0 {
continue // Only export version 0 symbols. See the comment in doxcoff.
}
// exported by cgo.
// The corresponding Go symbol is:
// _cgoexp_hashcode_symname.
- name := strings.SplitN(s.Extname(), "_", 4)[3]
+ name := strings.SplitN(extname, "_", 4)[3]
buf.Write([]byte(name + "\n"))
}
}
return fname
-
}