// non-package symbols).
func (r *oReader) NAlldef() int { return r.ndef + r.nhashed64def + r.nhasheddef + r.NNonpkgdef() }
-type objIdx struct {
- r *oReader
- i Sym // start index
-}
-
// objSym represents a symbol in an object file. It is a tuple of
// the object and the symbol's local index.
// For external symbols, objidx is the index of l.extReader (extObj),
// overwriting/overwritten symbols, the second (or later) appearance
// of the symbol gets the same global index as the first appearance.
type Loader struct {
- start map[*oReader]Sym // map from object file to its start index
- objs []objIdx // sorted by start index (i.e. objIdx.i)
- extStart Sym // from this index on, the symbols are externally defined
- builtinSyms []Sym // global index of builtin symbols
+ objs []*oReader
+ extStart Sym // from this index on, the symbols are externally defined
+ builtinSyms []Sym // global index of builtin symbols
objSyms []objSym // global index mapping to local index
nbuiltin := goobj.NBuiltin()
extReader := &oReader{objidx: extObj}
ldr := &Loader{
- start: make(map[*oReader]Sym),
- objs: []objIdx{{}, {extReader, 0}}, // reserve index 0 for nil symbol, 1 for external symbols
- objSyms: make([]objSym, 1, 1), // This will get overwritten later.
+ objs: []*oReader{nil, extReader}, // reserve index 0 for nil symbol, 1 for external symbols
+ objSyms: make([]objSym, 1, 1), // This will get overwritten later.
extReader: extReader,
symsByName: [2]map[string]Sym{make(map[string]Sym, 80000), make(map[string]Sym, 50000)}, // preallocate ~2MB for ABI0 and ~1MB for ABI1 symbols
objByPkg: make(map[string]uint32),
return ldr
}
-// Add object file r, return the start index.
-func (l *Loader) addObj(pkg string, r *oReader) Sym {
- if _, ok := l.start[r]; ok {
- panic("already added")
- }
+// Add object file r
+func (l *Loader) addObj(pkg string, r *oReader) {
pkg = objabi.PathToPrefix(pkg) // the object file contains escaped package path
if _, ok := l.objByPkg[pkg]; !ok {
l.objByPkg[pkg] = r.objidx
}
- i := Sym(len(l.objSyms))
- l.start[r] = i
- l.objs = append(l.objs, objIdx{r, i})
- return i
+ l.objs = append(l.objs, r)
}
// Add a symbol from an object file, return the global index.
// Convert a global index to a local index.
func (l *Loader) toLocal(i Sym) (*oReader, uint32) {
- return l.objs[l.objSyms[i].objidx].r, l.objSyms[i].s
+ return l.objs[l.objSyms[i].objidx], l.objSyms[i].s
}
// Resolve a local symbol reference. Return global index.
case goobj.PkgIdxSelf:
rr = r
default:
- rr = l.objs[r.pkg[p]].r
+ rr = l.objs[r.pkg[p]]
}
return l.toGlobal(rr, s.SymIdx)
}
if l.IsExternal(i) {
pp := l.getPayload(i)
if pp.objidx != 0 {
- return l.objs[pp.objidx].r.ReadOnly()
+ return l.objs[pp.objidx].ReadOnly()
}
return false
}
if l.IsExternal(i) {
pp := l.getPayload(i)
if pp.objidx != 0 {
- r := l.objs[pp.objidx].r
+ r := l.objs[pp.objidx]
return r.unit
}
return nil
if l.IsExternal(i) {
pp := l.getPayload(i)
if pp.objidx != 0 {
- r := l.objs[pp.objidx].r
+ r := l.objs[pp.objidx]
return r.unit.Lib.Pkg
}
return ""
func (l *Loader) auxs(i Sym) (*oReader, []goobj.Aux) {
if l.IsExternal(i) {
pp := l.getPayload(i)
- return l.objs[pp.objidx].r, pp.auxs
+ return l.objs[pp.objidx], pp.auxs
} else {
r, li := l.toLocal(i)
return r, r.Auxs(li)
// This function was determined empirically by looking at the cmd/compile on
// Darwin, and picking factors for hashed and hashed64 syms.
var symSize, hashedSize, hashed64Size int
- for _, o := range l.objs[goObjStart:] {
- symSize += o.r.ndef + o.r.nhasheddef/2 + o.r.nhashed64def/2 + o.r.NNonpkgdef()
- hashedSize += o.r.nhasheddef / 2
- hashed64Size += o.r.nhashed64def / 2
+ for _, r := range l.objs[goObjStart:] {
+ symSize += r.ndef + r.nhasheddef/2 + r.nhashed64def/2 + r.NNonpkgdef()
+ hashedSize += r.nhasheddef / 2
+ hashed64Size += r.nhashed64def / 2
}
// Index 0 is invalid for symbols.
l.objSyms = make([]objSym, 1, symSize)
hashedSyms: make(map[goobj.HashType]symAndSize, hashedSize),
}
- for _, o := range l.objs[goObjStart:] {
- st.preloadSyms(o.r, pkgDef)
+ for _, r := range l.objs[goObjStart:] {
+ st.preloadSyms(r, pkgDef)
}
l.npkgsyms = l.NSym()
- for _, o := range l.objs[goObjStart:] {
- st.preloadSyms(o.r, hashed64Def)
- st.preloadSyms(o.r, hashedDef)
- st.preloadSyms(o.r, nonPkgDef)
+ for _, r := range l.objs[goObjStart:] {
+ st.preloadSyms(r, hashed64Def)
+ st.preloadSyms(r, hashedDef)
+ st.preloadSyms(r, nonPkgDef)
}
l.nhashedsyms = len(st.hashed64Syms) + len(st.hashedSyms)
- for _, o := range l.objs[goObjStart:] {
- loadObjRefs(l, o.r, arch)
+ for _, r := range l.objs[goObjStart:] {
+ loadObjRefs(l, r, arch)
}
l.values = make([]int64, l.NSym(), l.NSym()+1000) // +1000 make some room for external symbols
l.outer = make([]Sym, l.NSym(), l.NSym()+1000)
// Walk through all text symbols from Go object files and append
// them to their corresponding library's textp list.
- for _, o := range l.objs[goObjStart:] {
- r := o.r
+ for _, r := range l.objs[goObjStart:] {
lib := r.unit.Lib
for i, n := uint32(0), uint32(r.NAlldef()); i < n; i++ {
gi := l.toGlobal(r, i)
// For debugging.
func (l *Loader) Dump() {
fmt.Println("objs")
- for _, obj := range l.objs[goObjStart:] {
- if obj.r != nil {
- fmt.Println(obj.i, obj.r.unit.Lib)
+ for _, r := range l.objs[goObjStart:] {
+ if r != nil {
+ fmt.Println(r.unit.Lib)
}
}
fmt.Println("extStart:", l.extStart)