d.reflectSeen = d.reflectSeen || d.ldr.IsReflectMethod(symIdx)
+ isgotype := d.ldr.IsGoType(symIdx)
relocs := d.ldr.Relocs(symIdx)
- symRelocs = relocs.ReadAll(symRelocs)
+ // For non-type symbols, we only need the target and the reloc
+ // type, so don't read other fields.
+ // For type symbols we may need all fields for interface
+ // satisfaction check.
+ // TODO: we don't even need the reloc type for non-type non-dwarf
+ // symbols.
+ if isgotype {
+ symRelocs = relocs.ReadAll(symRelocs)
+ } else {
+ symRelocs = relocs.ReadSyms(symRelocs)
+ }
- if d.ldr.IsGoType(symIdx) {
+ if isgotype {
p := d.ldr.Data(symIdx)
if len(p) != 0 && decodetypeKind(d.ctxt.Arch, p)&kindMask == kindInterface {
for _, sig := range d.decodeIfaceMethods2(d.ldr, d.ctxt.Arch, symIdx, symRelocs) {
d.mark(d.ldr.SubSym(symIdx), symIdx)
if len(methods) != 0 {
+ if !isgotype {
+ panic("method found on non-type symbol")
+ }
// Decode runtime type information for type methods
// to help work out which methods can be called
// dynamically via interfaces.
flags uint32 // read from object file
pkgprefix string
syms []Sym // Sym's global index, indexed by local index
+ ndef int // cache goobj2.Reader.NSym()
}
type objIdx struct {
symsByName [2]map[string]Sym // map symbol name to index, two maps are for ABI0 and ABIInternal
extStaticSyms map[nameVer]Sym // externally defined static symbols, keyed by name
- extReader *oReader // a dummy oReader, for external symbols
+ extReader *oReader // a dummy oReader, for external symbols
payloadBatch []extSymPayload
payloads []*extSymPayload // contents of linker-materialized external syms
values []int64 // symbol values, indexed by global sym index
}
return 0
case goobj2.PkgIdxNone:
- i := int(s.SymIdx) + r.NSym()
+ i := int(s.SymIdx) + r.ndef
return r.syms[i]
case goobj2.PkgIdxBuiltin:
return l.builtinSyms[s.SymIdx]
}
r, li := l.toLocal(i)
osym := goobj2.Sym{}
- osym.Read(r.Reader, r.SymOff(li))
+ osym.ReadFlag(r.Reader, r.SymOff(li))
return osym.Flag
}
// into a larger bitmap during preload.
r, li := l.toLocal(i)
osym := goobj2.Sym{}
- osym.Read(r.Reader, r.SymOff(li))
+ osym.ReadFlag(r.Reader, r.SymOff(li))
return osym.Dupok()
}
return l.attrDuplicateOK.has(l.extIndex(i))
dst = dst[:0]
r, li := l.toLocal(symIdx)
+ a := goobj2.Aux{}
for i := 0; i < naux; i++ {
- a := goobj2.Aux{}
- a.Read(r.Reader, r.AuxOff(li, i))
+ a.ReadSym(r.Reader, r.AuxOff(li, i))
dst = append(dst, l.resolve(r, a.Sym))
}
// specified slice. If the slice capacity is not large enough, a new
// larger slice will be allocated. Final slice is returned.
func (relocs *Relocs) ReadAll(dst []Reloc) []Reloc {
+ return relocs.readAll(dst, false)
+}
+
+// ReadSyms method reads all relocation target symbols and reloc types
+// for a symbol into the specified slice. It is like ReadAll but only
+// fill in the Sym and Type fields.
+func (relocs *Relocs) ReadSyms(dst []Reloc) []Reloc {
+ return relocs.readAll(dst, true)
+}
+
+func (relocs *Relocs) readAll(dst []Reloc, onlySymType bool) []Reloc {
if relocs.Count == 0 {
return dst[:0]
}
}
off := relocs.r.RelocOff(relocs.li, 0)
+ rel := goobj2.Reloc{}
for i := 0; i < relocs.Count; i++ {
- rel := goobj2.Reloc{}
- rel.Read(relocs.r.Reader, off)
+ if onlySymType {
+ rel.ReadSymType(relocs.r.Reader, off)
+ } else {
+ rel.Read(relocs.r.Reader, off)
+ }
off += uint32(rel.Size())
target := relocs.l.resolve(relocs.r, rel.Sym)
dst = append(dst, Reloc{
pkgprefix := objabi.PathToPrefix(lib.Pkg) + "."
ndef := r.NSym()
nnonpkgdef := r.NNonpkgdef()
- or := &oReader{r, unit, localSymVersion, r.Flags(), pkgprefix, make([]Sym, ndef + nnonpkgdef + r.NNonpkgref())}
+ or := &oReader{r, unit, localSymVersion, r.Flags(), pkgprefix, make([]Sym, ndef+nnonpkgdef+r.NNonpkgref()), ndef}
// Autolib
lib.ImportStrings = append(lib.ImportStrings, r.Autolib()...)
nr := 0
for i, n := 0, r.NSym()+r.NNonpkgdef(); i < n; i++ {
gi := r.syms[i]
- if r2, i2 := l.toLocal(gi); r2 != r || i2 != i{
+ if r2, i2 := l.toLocal(gi); r2 != r || i2 != i {
continue // come from a different object
}
osym := goobj2.Sym{}
rslice := []Reloc{}
for si := Sym(1); si < Sym(len(l.objSyms)); si++ {
relocs := l.Relocs(si)
- rslice = relocs.ReadAll(rslice)
+ rslice = relocs.ReadSyms(rslice)
for ri := 0; ri < relocs.Count; ri++ {
r := &rslice[ri]
if r.Sym != 0 && l.SymType(r.Sym) == sym.SXREF && l.RawSymName(r.Sym) != ".got" {