aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/link/internal/loader/loader.go
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2019-12-03 10:38:43 -0500
committerCherry Zhang <cherryyz@google.com>2019-12-03 10:38:43 -0500
commitf7672d39ca9eeb05d0605348290335698da98ae8 (patch)
tree7f5bfe50f6f913ad60c983ad73936dfc8d808567 /src/cmd/link/internal/loader/loader.go
parent27c0aeee3fc7ed35f9b2eac4725b9147902537da (diff)
parent2ac1ca9160f52907ce1cd04738c80b1c055b5ba6 (diff)
downloadgo-f7672d39ca9eeb05d0605348290335698da98ae8.tar.xz
[dev.link] all: merge branch 'master' into dev.link
Bring in Than's fix of #35779. The only merge conflict is cmd/link/internal/loadelf/ldelf.go, with a modification-deletion conflict. Change-Id: Id2fcfd2094a31120966a6ea9c462b4ec76646b10
Diffstat (limited to 'src/cmd/link/internal/loader/loader.go')
-rw-r--r--src/cmd/link/internal/loader/loader.go50
1 files changed, 46 insertions, 4 deletions
diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go
index 4fa0d5ddce..48ff5aecc8 100644
--- a/src/cmd/link/internal/loader/loader.go
+++ b/src/cmd/link/internal/loader/loader.go
@@ -111,6 +111,8 @@ type Loader struct {
Syms []*sym.Symbol // indexed symbols. XXX we still make sym.Symbol for now.
+ anonVersion int // most recently assigned ext static sym pseudo-version
+
Reachable bitmap // bitmap of reachable symbols, indexed by global index
// Used to implement field tracking; created during deadcode if
@@ -347,7 +349,7 @@ func (l *Loader) resolve(r *oReader, s goobj2.SymRef) Sym {
// This is more like Syms.ROLookup than Lookup -- it doesn't create
// new symbol.
func (l *Loader) Lookup(name string, ver int) Sym {
- if ver >= sym.SymVerStatic {
+ if ver >= sym.SymVerStatic || ver < 0 {
return l.extStaticSyms[nameVer{name, ver}]
}
return l.symsByName[ver][name]
@@ -842,13 +844,24 @@ func (l *Loader) ExtractSymbols(syms *sym.Symbols) {
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 versions
+ // less than zero), since if we tried to add these we'd wind up
+ // with collisions. Along the way, update the version from the
+ // negative anon version to something larger than sym.SymVerStatic
+ // (needed so that sym.symbol.IsFileLocal() works properly).
+ anonVerReplacement := syms.IncVersion()
for _, s := range l.Syms {
- if s != nil && s.Name != "" {
+ if s == nil {
+ continue
+ }
+ if s.Name != "" && s.Version >= 0 {
syms.Add(s)
}
+ if s.Version < 0 {
+ s.Version = int16(anonVerReplacement)
+ }
}
-
}
// addNewSym adds a new sym.Symbol to the i-th index in the list of symbols.
@@ -980,6 +993,35 @@ func (l *Loader) LookupOrCreate(name string, version int, syms *sym.Symbols) *sy
return s
}
+// Create creates a symbol with the specified name, returning a
+// sym.Symbol object for it. This method is intended for static/hidden
+// symbols discovered while loading host objects. We can see more than
+// one instance of a given static symbol with the same name/version,
+// so we can't add them to the lookup tables "as is". Instead assign
+// them fictitious (unique) versions, starting at -1 and decreasing by
+// one for each newly created symbol, and record them in the
+// extStaticSyms hash.
+func (l *Loader) Create(name string, syms *sym.Symbols) *sym.Symbol {
+ i := l.max + 1
+ l.max++
+ if l.extStart == 0 {
+ l.extStart = i
+ }
+
+ // Assign a new unique negative version -- this is to mark the
+ // symbol so that it can be skipped when ExtractSymbols is adding
+ // ext syms to the sym.Symbols hash.
+ l.anonVersion--
+ ver := l.anonVersion
+ l.extSyms = append(l.extSyms, nameVer{name, ver})
+ l.growSyms(int(i))
+ s := syms.Newsym(name, ver)
+ l.Syms[i] = s
+ l.extStaticSyms[nameVer{name, ver}] = i
+
+ return s
+}
+
func loadObjFull(l *Loader, r *oReader) {
lib := r.unit.Lib
istart := l.startIndex(r)