[dev.link] cmd/link: enforce single level of 'outer' sym

Add code to the loader to enforce the invariant that there is only a
single level of 'outer' symbol nesting. That is, if outer(X) = Y, then
outer(Y) is always zero.

Revise foldSubSymbolOffset based on the new invariant, allowing it to
be inlined, and then fix the various "for s.Outer != nil" loops in the
linker to just use an "if" instead of a loop.

Change-Id: Ib895702bc6de52718248f09a5368b84cb2e0a3fa
Reviewed-on: https://go-review.googlesource.com/c/go/+/231137
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Than McIntosh 2020-04-30 09:04:08 -04:00
parent 1667b35740
commit 24814e2147
9 changed files with 32 additions and 50 deletions

View file

@ -1596,6 +1596,11 @@ func (l *Loader) SubSym(i Sym) Sym {
func (l *Loader) SetOuterSym(i Sym, o Sym) {
if o != 0 {
l.outer[i] = o
// relocsym's foldSubSymbolOffset requires that we only
// have a single level of containment-- enforce here.
if l.outer[o] != 0 {
panic("multiply nested outer sym")
}
} else {
delete(l.outer, i)
}
@ -2662,6 +2667,11 @@ func (l *Loader) migrateAttributes(src Sym, dst *sym.Symbol) {
// Convert outer relationship
if outer, ok := l.outer[src]; ok {
dst.Outer = l.Syms[outer]
// relocsym's foldSubSymbolOffset requires that we only
// have a single level of containment-- enforce here.
if l.outer[outer] != 0 {
panic("multiply nested outer syms")
}
}
// Set sub-symbol attribute. See the comment on the AttrSubSymbol