data := ldr.Data(symIdx)
return int64(decodeInuxi(arch, data[off+2*arch.PtrSize:], arch.PtrSize))
}
+
+// decodetypeStr2 returns the contents of an rtype's str field (a nameOff).
+func decodetypeStr2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) string {
+ relocs := ldr.Relocs(symIdx)
+ str := decodetypeName2(ldr, symIdx, &relocs, 4*arch.PtrSize+8)
+ data := ldr.Data(symIdx)
+ if data[2*arch.PtrSize+4]&tflagExtraStar != 0 {
+ return str[1:]
+ }
+ return str
+}
import (
"cmd/internal/objabi"
+ "cmd/link/internal/loader"
"cmd/link/internal/sym"
"sort"
)
type typelinkSortKey struct {
TypeStr string
- Type *sym.Symbol
+ Type loader.Sym
}
func (s byTypeStr) Less(i, j int) bool { return s[i].TypeStr < s[j].TypeStr }
// Types that should be added to the typelinks table are marked with the
// MakeTypelink attribute by the compiler.
func (ctxt *Link) typelink() {
+ ldr := ctxt.loader
typelinks := byTypeStr{}
- for _, s := range ctxt.Syms.Allsym {
- if s.Attr.Reachable() && s.Attr.MakeTypelink() {
- typelinks = append(typelinks, typelinkSortKey{decodetypeStr(ctxt.Arch, s), s})
+ for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
+ if ldr.AttrReachable(s) && ldr.IsTypelink(s) {
+ typelinks = append(typelinks, typelinkSortKey{decodetypeStr2(ldr, ctxt.Arch, s), s})
}
}
sort.Sort(typelinks)
- tl := ctxt.Syms.Lookup("runtime.typelink", 0)
- tl.Type = sym.STYPELINK
- tl.Attr |= sym.AttrReachable | sym.AttrLocal
- tl.Size = int64(4 * len(typelinks))
- tl.P = make([]byte, tl.Size)
- tl.R = make([]sym.Reloc, len(typelinks))
+ tl := ldr.CreateSymForUpdate("runtime.typelink", 0)
+ tl.SetType(sym.STYPELINK)
+ ldr.SetAttrReachable(tl.Sym(), true)
+ ldr.SetAttrLocal(tl.Sym(), true)
+ tl.SetSize(int64(4 * len(typelinks)))
+ tl.Grow(tl.Size())
+ relocs := tl.AddRelocs(len(typelinks))
for i, s := range typelinks {
- r := &tl.R[i]
- r.Sym = s.Type
- r.Off = int32(i * 4)
- r.Siz = 4
- r.Type = objabi.R_ADDROFF
+ r := relocs.At2(i)
+ r.SetSym(s.Type)
+ r.SetOff(int32(i * 4))
+ r.SetSiz(4)
+ r.SetType(objabi.R_ADDROFF)
}
}
// Returns the attributes of the i-th symbol.
func (l *Loader) SymAttr(i Sym) uint8 {
if l.IsExternal(i) {
- // TODO: do something? External symbols have different representation of attributes. For now, ReflectMethod is the only thing matters and it cannot be set by external symbol.
+ // TODO: do something? External symbols have different representation of attributes.
+ // For now, ReflectMethod, NoSplit, GoType, and Typelink are used and they cannot be
+ // set by external symbol.
return 0
}
r, li := l.toLocal(i)
return l.SymAttr(i)&goobj2.SymFlagGoType != 0
}
+// Returns whether this symbol should be included in typelink.
+func (l *Loader) IsTypelink(i Sym) bool {
+ return l.SymAttr(i)&goobj2.SymFlagTypelink != 0
+}
+
// Returns whether this is a "go.itablink.*" symbol.
func (l *Loader) IsItabLink(i Sym) bool {
if _, ok := l.itablink[i]; ok {