From: Than McIntosh Date: Tue, 30 Jun 2020 14:22:13 +0000 (-0400) Subject: [dev.link] cmd/link: skip symtab entries for selected file local symbols X-Git-Tag: go1.16beta1~1378^2~58 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=8aa036e9135f6f24ab6a5f250a4fba47a5d3a083;p=gostls13.git [dev.link] cmd/link: skip symtab entries for selected file local symbols Don't emit symbol table entries for compiler-generated file-local symbols (this category includes .stmp_* temporaries and *.stkobj symbols). Note that user-written static symbols within assembler sources will still be added to the symbol table. Apply the same test when emitting DWARF for global variables. Change-Id: I4db77a2750a0b575e051dfea895c4742cf6709a6 Reviewed-on: https://go-review.googlesource.com/c/go/+/240539 Run-TryBot: Than McIntosh TryBot-Result: Gobot Gobot Reviewed-by: Cherry Zhang --- diff --git a/src/cmd/internal/goobj2/objfile.go b/src/cmd/internal/goobj2/objfile.go index 433eafa559..938362901a 100644 --- a/src/cmd/internal/goobj2/objfile.go +++ b/src/cmd/internal/goobj2/objfile.go @@ -241,6 +241,7 @@ const SymABIstatic = ^uint16(0) const ( ObjFlagShared = 1 << iota // this object is built with -shared ObjFlagNeedNameExpansion // the linker needs to expand `"".` to package path in symbol names + ObjFlagFromAssembly // object is from asm src, not go ) // Sym.Flag @@ -742,3 +743,4 @@ func (r *Reader) Flags() uint32 { func (r *Reader) Shared() bool { return r.Flags()&ObjFlagShared != 0 } func (r *Reader) NeedNameExpansion() bool { return r.Flags()&ObjFlagNeedNameExpansion != 0 } +func (r *Reader) FromAssembly() bool { return r.Flags()&ObjFlagFromAssembly != 0 } diff --git a/src/cmd/internal/obj/objfile2.go b/src/cmd/internal/obj/objfile2.go index b12b6fe84c..fbd2395d1f 100644 --- a/src/cmd/internal/obj/objfile2.go +++ b/src/cmd/internal/obj/objfile2.go @@ -41,6 +41,9 @@ func WriteObjFile(ctxt *Link, b *bio.Writer, pkgpath string) { if pkgpath == "" { flags |= goobj2.ObjFlagNeedNameExpansion } + if ctxt.IsAsm { + flags |= goobj2.ObjFlagFromAssembly + } h := goobj2.Header{ Magic: goobj2.Magic, Fingerprint: ctxt.Fingerprint, diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go index d15cde4e38..a574472aa4 100644 --- a/src/cmd/link/internal/ld/dwarf.go +++ b/src/cmd/link/internal/ld/dwarf.go @@ -1887,11 +1887,12 @@ func dwarfGenerateDebugInfo(ctxt *Link) { if d.ldr.SymGoType(idx) == 0 { continue } - - sn := d.ldr.SymName(idx) - if ctxt.LinkMode != LinkExternal && isStaticTemp(sn) { + // Skip file local symbols (this includes static tmps, stack + // object symbols, and local symbols in assembler src files). + if d.ldr.IsFileLocal(idx) { continue } + sn := d.ldr.SymName(idx) if sn == "" { // skip aux symbols continue diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go index b5f4288b6c..fddf85f1c5 100644 --- a/src/cmd/link/internal/ld/symtab.go +++ b/src/cmd/link/internal/ld/symtab.go @@ -196,7 +196,14 @@ func genelfsym(ctxt *Link, elfbind int) { return false } // FIXME: avoid having to do name inspections here. + // NB: the restrictions below on file local symbols are a bit + // arbitrary -- if it turns out we need nameless static + // symbols they could be relaxed/removed. sn := ldr.SymName(s) + if (sn == "" || sn[0] == '.') && ldr.IsFileLocal(s) { + panic(fmt.Sprintf("unexpected file local symbol %d %s<%d>\n", + s, sn, ldr.SymVersion(s))) + } if (sn == "" || sn[0] == '.') && !ldr.IsFileLocal(s) { return false } @@ -499,15 +506,14 @@ func (ctxt *Link) symtab() []sym.SymKind { nsym := loader.Sym(ldr.NSym()) symGroupType := make([]sym.SymKind, nsym) for s := loader.Sym(1); s < nsym; s++ { - name := ldr.SymName(s) - if !ctxt.IsExternal() && isStaticTemp(name) { + if !ctxt.IsExternal() && ldr.IsFileLocal(s) && !ldr.IsFromAssembly(s) { ldr.SetAttrNotInSymbolTable(s, true) } - if !ldr.AttrReachable(s) || ldr.AttrSpecial(s) || (ldr.SymType(s) != sym.SRODATA && ldr.SymType(s) != sym.SGOFUNC) { continue } + name := ldr.SymName(s) switch { case strings.HasPrefix(name, "type."): if !ctxt.DynlinkingGo() { @@ -768,10 +774,3 @@ func (ctxt *Link) symtab() []sym.SymKind { } return symGroupType } - -func isStaticTemp(name string) bool { - if i := strings.LastIndex(name, "/"); i >= 0 { - name = name[i:] - } - return strings.Contains(name, "..stmp_") -} diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go index 3de0ab34b4..28847ad17a 100644 --- a/src/cmd/link/internal/loader/loader.go +++ b/src/cmd/link/internal/loader/loader.go @@ -683,7 +683,19 @@ func (l *Loader) SymVersion(i Sym) int { return int(abiToVer(r.Sym(li).ABI(), r.version)) } -func (l *Loader) IsFileLocal(i Sym) bool { return l.SymVersion(i) >= sym.SymVerStatic } +func (l *Loader) IsFileLocal(i Sym) bool { + return l.SymVersion(i) >= sym.SymVerStatic +} + +// IsFromAssembly returns true if this symbol is derived from an +// object file generated by the Go assembler. +func (l *Loader) IsFromAssembly(i Sym) bool { + if l.IsExternal(i) { + return false + } + r, _ := l.toLocal(i) + return r.FromAssembly() +} // Returns the type of the i-th symbol. func (l *Loader) SymType(i Sym) sym.SymKind {