From 25992d025f01d27bd7e38d45daa95e420d56ece5 Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Wed, 22 Apr 2020 11:35:03 -0400 Subject: [PATCH] [dev.link] cmd/link/internal/loader: preprocess numeric constants earlier Change the timing for preprocessing of integer/floating point constant symbols so that we populate them with content at an earlier stage. This is needed to allow them can be picked up by the loader-API version of dodata(). Change-Id: Icf09f4f4b318b4f77e11d4a0f0a9cbecd76a1d6b Reviewed-on: https://go-review.googlesource.com/c/go/+/229438 Run-TryBot: Than McIntosh TryBot-Result: Gobot Gobot Reviewed-by: Cherry Zhang Reviewed-by: Jeremy Faller --- src/cmd/link/internal/ld/lib.go | 2 +- src/cmd/link/internal/loader/loader.go | 39 ++++++++++++++------------ 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 4bc7187292f..429c2641fb9 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -561,7 +561,7 @@ func (ctxt *Link) loadlib() { } // Add non-package symbols and references of externally defined symbols. - ctxt.loader.LoadNonpkgSyms(ctxt.Syms) + ctxt.loader.LoadNonpkgSyms(ctxt.Arch) // Load symbols from shared libraries, after all Go object symbols are loaded. for _, lib := range ctxt.Library { diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go index 1dbe4dfe3cb..fd329f56087 100644 --- a/src/cmd/link/internal/loader/loader.go +++ b/src/cmd/link/internal/loader/loader.go @@ -1804,26 +1804,27 @@ func (l *Loader) preloadSyms(r *oReader, kind int) { // Add non-package symbols and references to external symbols (which are always // named). -func (l *Loader) LoadNonpkgSyms(syms *sym.Symbols) { +func (l *Loader) LoadNonpkgSyms(arch *sys.Arch) { for _, o := range l.objs[1:] { l.preloadSyms(o.r, nonPkgDef) } for _, o := range l.objs[1:] { - loadObjRefs(l, o.r, syms) + loadObjRefs(l, o.r, arch) } } -func loadObjRefs(l *Loader, r *oReader, syms *sym.Symbols) { +func loadObjRefs(l *Loader, r *oReader, arch *sys.Arch) { ndef := r.NSym() + r.NNonpkgdef() for i, n := 0, r.NNonpkgref(); i < n; i++ { osym := r.Sym(ndef + i) name := strings.Replace(osym.Name(r.Reader), "\"\".", r.pkgprefix, -1) v := abiToVer(osym.ABI(), r.version) r.syms[ndef+i] = l.LookupOrCreateSym(name, v) + gi := r.syms[ndef+i] if osym.Local() { - gi := r.syms[ndef+i] l.SetAttrLocal(gi, true) } + l.preprocess(arch, gi, name) } } @@ -1841,24 +1842,29 @@ func abiToVer(abi uint16, localSymVersion int) int { return v } -func preprocess(arch *sys.Arch, s *sym.Symbol) { - if s.Name != "" && s.Name[0] == '$' && len(s.Name) > 5 && s.Type == 0 && len(s.P) == 0 { - x, err := strconv.ParseUint(s.Name[5:], 16, 64) +// preprocess looks for integer/floating point constant symbols whose +// content is encoded into the symbol name, and promotes them into +// real symbols with RODATA type and a payload that matches the +// encoded content. +func (l *Loader) preprocess(arch *sys.Arch, s Sym, name string) { + if name != "" && name[0] == '$' && len(name) > 5 && l.SymType(s) == 0 && len(l.Data(s)) == 0 { + x, err := strconv.ParseUint(name[5:], 16, 64) if err != nil { - log.Panicf("failed to parse $-symbol %s: %v", s.Name, err) + log.Panicf("failed to parse $-symbol %s: %v", name, err) } - s.Type = sym.SRODATA - s.Attr |= sym.AttrLocal - switch s.Name[:5] { + su := l.MakeSymbolUpdater(s) + su.SetType(sym.SRODATA) + su.SetLocal(true) + switch name[:5] { case "$f32.": if uint64(uint32(x)) != x { - log.Panicf("$-symbol %s too large: %d", s.Name, x) + log.Panicf("$-symbol %s too large: %d", name, x) } - s.AddUint32(arch, uint32(x)) + su.AddUint32(arch, uint32(x)) case "$f64.", "$i64.": - s.AddUint64(arch, x) + su.AddUint64(arch, x) default: - log.Panicf("unrecognized $-symbol: %s", s.Name) + log.Panicf("unrecognized $-symbol: %s", name) } } } @@ -1929,9 +1935,6 @@ func (l *Loader) LoadFull(arch *sys.Arch, syms *sym.Symbols) { // Transfer over attributes. l.migrateAttributes(i, s) - - // Preprocess symbol. May set 'AttrLocal'. - preprocess(arch, s) } // load contents of defined symbols