Skip to content

Commit e4c01f0

Browse files
committed
cmd/link: additional fixes for -newobj and "ld -r" ELF host objects
The previous fix for this issue (CL 208479) was not general enough; this patch revises it to handle more cases. The problem with the original fix was that once a sym.Symbol is created for a given static symbol and given a bogus anonymous version of -1, we hit problems if some other non-anonymous symbol (created by host object loading) had relocations targeting the static symbol. In this patch instead of assigning a fixed anonymous version of -1 to such symbols, each time loader.Create is invoked we create a new (unique) anonymous version for the sym.Symbol, then enter the result into the loader's extStaticSyms map, permitting it to be found in lookups when processing relocation targets. NB: this code will hopefully get a lot simpler once we can move host object loading away from early sym.Symbol creation. Updates #35779. Change-Id: I450ff577e17549025565d355d6707a2d28a5a617 Reviewed-on: https://go-review.googlesource.com/c/go/+/208778 Run-TryBot: Than McIntosh <[email protected]> Reviewed-by: Cherry Zhang <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent bf3ee57 commit e4c01f0

File tree

1 file changed

+33
-18
lines changed

1 file changed

+33
-18
lines changed

src/cmd/link/internal/loader/loader.go

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ type Loader struct {
111111

112112
Syms []*sym.Symbol // indexed symbols. XXX we still make sym.Symbol for now.
113113

114+
anonVersion int // most recently assigned ext static sym pseudo-version
115+
114116
Reachable bitmap // bitmap of reachable symbols, indexed by global index
115117

116118
// Used to implement field tracking; created during deadcode if
@@ -130,9 +132,6 @@ const (
130132
FlagStrictDups = 1 << iota
131133
)
132134

133-
// anonVersion is used to tag symbols created by loader.Create.
134-
const anonVersion = -1
135-
136135
func NewLoader(flags uint32) *Loader {
137136
nbuiltin := goobj2.NBuiltin()
138137
return &Loader{
@@ -350,7 +349,7 @@ func (l *Loader) resolve(r *oReader, s goobj2.SymRef) Sym {
350349
// This is more like Syms.ROLookup than Lookup -- it doesn't create
351350
// new symbol.
352351
func (l *Loader) Lookup(name string, ver int) Sym {
353-
if ver >= sym.SymVerStatic {
352+
if ver >= sym.SymVerStatic || ver < 0 {
354353
return l.extStaticSyms[nameVer{name, ver}]
355354
}
356355
return l.symsByName[ver][name]
@@ -846,13 +845,22 @@ func (l *Loader) ExtractSymbols(syms *sym.Symbols) {
846845
}
847846

848847
// Add symbols to the ctxt.Syms lookup table. This explicitly
849-
// skips things created via loader.Create (marked with
850-
// anonVersion), since if we tried to add these we'd wind up with
851-
// collisions.
848+
// skips things created via loader.Create (marked with versions
849+
// less than zero), since if we tried to add these we'd wind up
850+
// with collisions. Along the way, update the version from the
851+
// negative anon version to something larger than sym.SymVerStatic
852+
// (needed so that sym.symbol.IsFileLocal() works properly).
853+
anonVerReplacement := syms.IncVersion()
852854
for _, s := range l.Syms {
853-
if s != nil && s.Name != "" && s.Version != anonVersion {
855+
if s == nil {
856+
continue
857+
}
858+
if s.Name != "" && s.Version >= 0 {
854859
syms.Add(s)
855860
}
861+
if s.Version < 0 {
862+
s.Version = int16(anonVerReplacement)
863+
}
856864
}
857865
}
858866

@@ -985,25 +993,32 @@ func (l *Loader) LookupOrCreate(name string, version int, syms *sym.Symbols) *sy
985993
return s
986994
}
987995

988-
// Create creates a symbol with the specified name, but does not
989-
// insert it into any lookup table (hence it is possible to create a
990-
// symbol name with name X when there is already an existing symbol
991-
// named X entered into the loader). This method is intended for
992-
// static/hidden symbols discovered while loading host objects.
996+
// Create creates a symbol with the specified name, returning a
997+
// sym.Symbol object for it. This method is intended for static/hidden
998+
// symbols discovered while loading host objects. We can see more than
999+
// one instance of a given static symbol with the same name/version,
1000+
// so we can't add them to the lookup tables "as is". Instead assign
1001+
// them fictitious (unique) versions, starting at -1 and decreasing by
1002+
// one for each newly created symbol, and record them in the
1003+
// extStaticSyms hash.
9931004
func (l *Loader) Create(name string, syms *sym.Symbols) *sym.Symbol {
9941005
i := l.max + 1
9951006
l.max++
9961007
if l.extStart == 0 {
9971008
l.extStart = i
9981009
}
9991010

1000-
// Note the use of anonVersion -- this is to mark the symbol so that
1001-
// it can be skipped when ExtractSymbols is adding ext syms to the
1002-
// sym.Symbols hash.
1003-
l.extSyms = append(l.extSyms, nameVer{name, anonVersion})
1011+
// Assign a new unique negative version -- this is to mark the
1012+
// symbol so that it can be skipped when ExtractSymbols is adding
1013+
// ext syms to the sym.Symbols hash.
1014+
l.anonVersion--
1015+
ver := l.anonVersion
1016+
l.extSyms = append(l.extSyms, nameVer{name, ver})
10041017
l.growSyms(int(i))
1005-
s := syms.Newsym(name, -1)
1018+
s := syms.Newsym(name, ver)
10061019
l.Syms[i] = s
1020+
l.extStaticSyms[nameVer{name, ver}] = i
1021+
10071022
return s
10081023
}
10091024

0 commit comments

Comments
 (0)