func Load(l *loader.Loader, arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length int64, pn string, flags uint32) ([]*sym.Symbol, uint32, error) {
newSym := func(name string, version int) *sym.Symbol {
+ return l.Create(name, syms)
+ }
+ lookup := func(name string, version int) *sym.Symbol {
return l.LookupOrCreate(name, version, syms)
}
- return load(arch, syms.IncVersion(), newSym, newSym, f, pkg, length, pn, flags)
+ return load(arch, syms.IncVersion(), newSym, lookup, f, pkg, length, pn, flags)
}
func LoadOld(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length int64, pn string, flags uint32) ([]*sym.Symbol, uint32, error) {
// local names and hidden global names are unique
// and should only be referenced by their index, not name, so we
// don't bother to add them into the hash table
+ // FIXME: pass empty string here for name? This would
+ // reduce mem use, but also (possibly) make it harder
+ // to debug problems.
s = newSym(elfsym.name, localSymVersion)
s.Attr |= sym.AttrVisibilityHidden
FlagStrictDups = 1 << iota
)
+// anonVersion is used to tag symbols created by loader.Create.
+const anonVersion = -1
+
func NewLoader(flags uint32) *Loader {
nbuiltin := goobj2.NBuiltin()
return &Loader{
l.Syms[oldI] = nil
}
- // For now, add all symbols to ctxt.Syms.
+ // Add symbols to the ctxt.Syms lookup table. This explicitly
+ // skips things created via loader.Create (marked with
+ // anonVersion), since if we tried to add these we'd wind up with
+ // collisions.
for _, s := range l.Syms {
- if s != nil && s.Name != "" {
+ if s != nil && s.Name != "" && s.Version != anonVersion {
syms.Add(s)
}
}
-
}
// addNewSym adds a new sym.Symbol to the i-th index in the list of symbols.
return s
}
+// Create creates a symbol with the specified name, but does not
+// insert it into any lookup table (hence it is possible to create a
+// symbol name with name X when there is already an existing symbol
+// named X entered into the loader). This method is intended for
+// static/hidden symbols discovered while loading host objects.
+func (l *Loader) Create(name string, syms *sym.Symbols) *sym.Symbol {
+ i := l.max + 1
+ l.max++
+ if l.extStart == 0 {
+ l.extStart = i
+ }
+
+ // Note the use of anonVersion -- this is to mark the symbol so that
+ // it can be skipped when ExtractSymbols is adding ext syms to the
+ // sym.Symbols hash.
+ l.extSyms = append(l.extSyms, nameVer{name, anonVersion})
+ l.growSyms(int(i))
+ s := syms.Newsym(name, -1)
+ l.Syms[i] = s
+ return s
+}
+
func loadObjFull(l *Loader, r *oReader) {
lib := r.unit.Lib
istart := l.startIndex(r)