[dev.link] cmd/link: dostrdata and fieldtrack with new syms

Move the wavefront past fieldtrack and dostrdata.

Change-Id: Ia327ece0202e24031fec7e1f70b40e15fbb4f728
Reviewed-on: https://go-review.googlesource.com/c/go/+/219226
Run-TryBot: Jeremy Faller <jeremy@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Jeremy Faller 2020-02-12 17:20:00 -05:00
parent 112a7cb82c
commit 860f12a2fc
8 changed files with 67 additions and 83 deletions

View file

@ -37,6 +37,7 @@ import (
"cmd/internal/gcprog" "cmd/internal/gcprog"
"cmd/internal/objabi" "cmd/internal/objabi"
"cmd/internal/sys" "cmd/internal/sys"
"cmd/link/internal/loader"
"cmd/link/internal/sym" "cmd/link/internal/sym"
"compress/zlib" "compress/zlib"
"encoding/binary" "encoding/binary"
@ -927,48 +928,39 @@ func addstrdata1(ctxt *Link, arg string) {
} }
// addstrdata sets the initial value of the string variable name to value. // addstrdata sets the initial value of the string variable name to value.
func addstrdata(ctxt *Link, name, value string) { func addstrdata(arch *sys.Arch, l *loader.Loader, name, value string) {
s := ctxt.Syms.ROLookup(name, 0) s := l.Lookup(name, 0)
if s == nil || s.Gotype == nil { if s == 0 {
// Not defined in the loaded packages.
return return
} }
if s.Gotype.Name != "type.string" { if goType := l.SymGoType(s); goType == 0 {
Errorf(s, "cannot set with -X: not a var of type string (%s)", s.Gotype.Name) return
} else if typeName := l.SymName(goType); typeName != "type.string" {
Errorf(nil, "%s: cannot set with -X: not a var of type string (%s)", name, typeName)
return return
} }
if s.Type == sym.SBSS { bld, s := l.MakeSymbolUpdater(s)
s.Type = sym.SDATA if bld.Type() == sym.SBSS {
bld.SetType(sym.SDATA)
} }
p := fmt.Sprintf("%s.str", s.Name) p := fmt.Sprintf("%s.str", name)
sp := ctxt.Syms.Lookup(p, 0) sbld, sp := l.MakeSymbolUpdater(l.LookupOrCreateSym(p, 0))
Addstring(sp, value) sbld.Addstring(value)
sp.Type = sym.SRODATA sbld.SetType(sym.SRODATA)
s.Size = 0 bld.SetSize(0)
s.P = s.P[:0] bld.SetData(make([]byte, 0, arch.PtrSize*2))
if s.Attr.ReadOnly() { bld.SetReadOnly(false)
s.P = make([]byte, 0, ctxt.Arch.PtrSize*2) bld.SetRelocs(nil)
s.Attr.Set(sym.AttrReadOnly, false) bld.AddAddrPlus(arch, sp, 0)
} bld.AddUint(arch, uint64(len(value)))
s.R = s.R[:0]
reachable := s.Attr.Reachable()
s.AddAddr(ctxt.Arch, sp)
s.AddUint(ctxt.Arch, uint64(len(value)))
// addstring, addaddr, etc., mark the symbols as reachable.
// In this case that is not necessarily true, so stick to what
// we know before entering this function.
s.Attr.Set(sym.AttrReachable, reachable)
sp.Attr.Set(sym.AttrReachable, reachable)
} }
func (ctxt *Link) dostrdata() { func (ctxt *Link) dostrdata() {
for _, name := range strnames { for _, name := range strnames {
addstrdata(ctxt, name, strdata[name]) addstrdata(ctxt.Arch, ctxt.loader, name, strdata[name])
} }
} }

View file

@ -10,6 +10,7 @@ import (
"bytes" "bytes"
"cmd/internal/bio" "cmd/internal/bio"
"cmd/internal/objabi" "cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/loader" "cmd/link/internal/loader"
"cmd/link/internal/sym" "cmd/link/internal/sym"
"encoding/json" "encoding/json"
@ -345,36 +346,36 @@ func Adddynsym(ctxt *Link, s *sym.Symbol) {
} }
} }
func fieldtrack(ctxt *Link) { func fieldtrack(arch *sys.Arch, l *loader.Loader) {
// record field tracking references
var buf bytes.Buffer var buf bytes.Buffer
for _, s := range ctxt.Syms.Allsym { for i := loader.Sym(1); i < loader.Sym(l.NSym()); i++ {
if strings.HasPrefix(s.Name, "go.track.") { if name := l.SymName(i); strings.HasPrefix(name, "go.track.") {
s.Attr |= sym.AttrSpecial // do not lay out in data segment bld, s := l.MakeSymbolUpdater(i)
s.Attr |= sym.AttrNotInSymbolTable bld.SetSpecial(true)
if s.Attr.Reachable() { bld.SetNotInSymbolTable(true)
buf.WriteString(s.Name[9:]) if bld.Reachable() {
for p := ctxt.Reachparent[s]; p != nil; p = ctxt.Reachparent[p] { buf.WriteString(name[9:])
for p := l.Reachparent[s]; p != 0; p = l.Reachparent[p] {
buf.WriteString("\t") buf.WriteString("\t")
buf.WriteString(p.Name) buf.WriteString(l.SymName(p))
} }
buf.WriteString("\n") buf.WriteString("\n")
}
s.Type = sym.SCONST bld.SetType(sym.SCONST)
s.Value = 0 bld.SetValue(0)
}
} }
} }
if *flagFieldTrack == "" { if *flagFieldTrack == "" {
return return
} }
s := ctxt.Syms.ROLookup(*flagFieldTrack, 0) s := l.Lookup(*flagFieldTrack, 0)
if s == nil || !s.Attr.Reachable() { if s == 0 || !l.AttrReachable(s) {
return return
} }
s.Type = sym.SDATA bld, _ := l.MakeSymbolUpdater(s)
addstrdata(ctxt, *flagFieldTrack, buf.String()) bld.SetType(sym.SDATA)
addstrdata(arch, l, *flagFieldTrack, buf.String())
} }
func (ctxt *Link) addexport() { func (ctxt *Link) addexport() {

View file

@ -733,7 +733,7 @@ func (ctxt *Link) mangleTypeSym() {
for _, s := range ctxt.Syms.Allsym { for _, s := range ctxt.Syms.Allsym {
newName := typeSymbolMangle(s.Name) newName := typeSymbolMangle(s.Name)
if newName != s.Name { if newName != s.Name {
ctxt.Syms.Rename(s.Name, newName, int(s.Version), ctxt.Reachparent) ctxt.Syms.Rename(s.Name, newName, int(s.Version))
} }
} }
} }
@ -2618,26 +2618,10 @@ func (ctxt *Link) loadlibfull() {
} }
// Pull the symbols out. // Pull the symbols out.
ctxt.loader.ExtractSymbols(ctxt.Syms) ctxt.loader.ExtractSymbols(ctxt.Syms, ctxt.Reachparent)
setupdynexp(ctxt) setupdynexp(ctxt)
// Populate ctxt.Reachparent if appropriate.
if ctxt.Reachparent != nil {
for i := 0; i < len(ctxt.loader.Reachparent); i++ {
p := ctxt.loader.Reachparent[i]
if p == 0 {
continue
}
if p == loader.Sym(i) {
panic("self-cycle in reachparent")
}
sym := ctxt.loader.Syms[i]
psym := ctxt.loader.Syms[p]
ctxt.Reachparent[sym] = psym
}
}
// Drop the cgodata reference. // Drop the cgodata reference.
ctxt.cgodata = nil ctxt.cgodata = nil

View file

@ -234,18 +234,19 @@ func Main(arch *sys.Arch, theArch Arch) {
bench.Start("linksetup") bench.Start("linksetup")
ctxt.linksetup() ctxt.linksetup()
bench.Start("dostrdata")
ctxt.dostrdata()
if objabi.Fieldtrack_enabled != 0 {
bench.Start("fieldtrack")
fieldtrack(ctxt.Arch, ctxt.loader)
}
bench.Start("loadlibfull") bench.Start("loadlibfull")
ctxt.loadlibfull() // XXX do it here for now ctxt.loadlibfull() // XXX do it here for now
bench.Start("dostrdata")
ctxt.dostrdata()
bench.Start("dwarfGenerateDebugInfo") bench.Start("dwarfGenerateDebugInfo")
dwarfGenerateDebugInfo(ctxt) dwarfGenerateDebugInfo(ctxt)
if objabi.Fieldtrack_enabled != 0 {
bench.Start("fieldtrack")
fieldtrack(ctxt)
}
bench.Start("mangleTypeSym") bench.Start("mangleTypeSym")
ctxt.mangleTypeSym() ctxt.mangleTypeSym()
bench.Start("callgraph") bench.Start("callgraph")

View file

@ -1186,7 +1186,7 @@ func (ctxt *Link) doxcoff() {
if ctxt.LinkMode == LinkExternal { if ctxt.LinkMode == LinkExternal {
// Change rt0_go name to match name in runtime/cgo:main(). // Change rt0_go name to match name in runtime/cgo:main().
rt0 := ctxt.Syms.ROLookup("runtime.rt0_go", 0) rt0 := ctxt.Syms.ROLookup("runtime.rt0_go", 0)
ctxt.Syms.Rename(rt0.Name, "runtime_rt0_go", 0, ctxt.Reachparent) ctxt.Syms.Rename(rt0.Name, "runtime_rt0_go", 0)
for _, s := range ctxt.Syms.Allsym { for _, s := range ctxt.Syms.Allsym {
if !s.Attr.CgoExport() { if !s.Attr.CgoExport() {
@ -1198,7 +1198,7 @@ func (ctxt *Link) doxcoff() {
// On AIX, a exported function must have two symbols: // On AIX, a exported function must have two symbols:
// - a .text symbol which must start with a ".". // - a .text symbol which must start with a ".".
// - a .data symbol which is a function descriptor. // - a .data symbol which is a function descriptor.
ctxt.Syms.Rename(s.Name, "."+name, 0, ctxt.Reachparent) ctxt.Syms.Rename(s.Name, "."+name, 0)
desc := ctxt.Syms.Lookup(name, 0) desc := ctxt.Syms.Lookup(name, 0)
desc.Type = sym.SNOPTRDATA desc.Type = sym.SNOPTRDATA

View file

@ -423,7 +423,6 @@ func (l *Loader) IsExternal(i Sym) bool {
return l.isExtReader(r) return l.isExtReader(r)
} }
func (l *Loader) isExtReader(r *oReader) bool { func (l *Loader) isExtReader(r *oReader) bool {
return r == l.extReader return r == l.extReader
} }
@ -1708,7 +1707,7 @@ func (l *Loader) LoadFull(arch *sys.Arch, syms *sym.Symbols) {
// ExtractSymbols grabs the symbols out of the loader for work that hasn't been // ExtractSymbols grabs the symbols out of the loader for work that hasn't been
// ported to the new symbol type. // ported to the new symbol type.
func (l *Loader) ExtractSymbols(syms *sym.Symbols) { func (l *Loader) ExtractSymbols(syms *sym.Symbols, rp map[*sym.Symbol]*sym.Symbol) {
// Add symbols to the ctxt.Syms lookup table. This explicitly skips things // Add symbols to the ctxt.Syms lookup table. This explicitly skips things
// created via loader.Create (marked with versions less than zero), since // created via loader.Create (marked with versions less than zero), since
// if we tried to add these we'd wind up with collisions. We do, however, // if we tried to add these we'd wind up with collisions. We do, however,
@ -1731,6 +1730,13 @@ func (l *Loader) ExtractSymbols(syms *sym.Symbols) {
s.Version = int16(anonVerReplacement) s.Version = int16(anonVerReplacement)
} }
} }
for i, s := range l.Reachparent {
if i == 0 {
continue
}
rp[l.Syms[i]] = l.Syms[s]
}
} }
// allocSym allocates a new symbol backing. // allocSym allocates a new symbol backing.

View file

@ -73,6 +73,7 @@ func (sb *SymbolBuilder) CgoExportDynamic() bool { return sb.l.AttrCgoExportDyna
func (sb *SymbolBuilder) Dynimplib() string { return sb.l.SymDynimplib(sb.symIdx) } func (sb *SymbolBuilder) Dynimplib() string { return sb.l.SymDynimplib(sb.symIdx) }
func (sb *SymbolBuilder) Dynimpvers() string { return sb.l.SymDynimpvers(sb.symIdx) } func (sb *SymbolBuilder) Dynimpvers() string { return sb.l.SymDynimpvers(sb.symIdx) }
func (sb *SymbolBuilder) SubSym() Sym { return sb.l.SubSym(sb.symIdx) } func (sb *SymbolBuilder) SubSym() Sym { return sb.l.SubSym(sb.symIdx) }
func (sb *SymbolBuilder) GoType() Sym { return sb.l.SymGoType(sb.symIdx) }
// Setters for symbol properties. // Setters for symbol properties.
@ -89,6 +90,11 @@ func (sb *SymbolBuilder) SetDynimplib(value string) { sb.l.SetSymDynimplib(sb.s
func (sb *SymbolBuilder) SetDynimpvers(value string) { sb.l.SetSymDynimpvers(sb.symIdx, value) } func (sb *SymbolBuilder) SetDynimpvers(value string) { sb.l.SetSymDynimpvers(sb.symIdx, value) }
func (sb *SymbolBuilder) SetPlt(value int32) { sb.l.SetPlt(sb.symIdx, value) } func (sb *SymbolBuilder) SetPlt(value int32) { sb.l.SetPlt(sb.symIdx, value) }
func (sb *SymbolBuilder) SetGot(value int32) { sb.l.SetGot(sb.symIdx, value) } func (sb *SymbolBuilder) SetGot(value int32) { sb.l.SetGot(sb.symIdx, value) }
func (sb *SymbolBuilder) SetSpecial(value bool) { sb.l.SetAttrSpecial(sb.symIdx, value) }
func (sb *SymbolBuilder) SetNotInSymbolTable(value bool) {
sb.l.SetAttrNotInSymbolTable(sb.symIdx, value)
}
func (sb *SymbolBuilder) AddBytes(data []byte) { func (sb *SymbolBuilder) AddBytes(data []byte) {
sb.setReachable() sb.setReachable()

View file

@ -105,7 +105,7 @@ func (syms *Symbols) IncVersion() int {
} }
// Rename renames a symbol. // Rename renames a symbol.
func (syms *Symbols) Rename(old, new string, v int, reachparent map[*Symbol]*Symbol) { func (syms *Symbols) Rename(old, new string, v int) {
s := syms.hash[v][old] s := syms.hash[v][old]
oldExtName := s.Extname() oldExtName := s.Extname()
s.Name = new s.Name = new
@ -120,15 +120,9 @@ func (syms *Symbols) Rename(old, new string, v int, reachparent map[*Symbol]*Sym
} else { } else {
if s.Type == 0 { if s.Type == 0 {
dup.Attr |= s.Attr dup.Attr |= s.Attr
if s.Attr.Reachable() && reachparent != nil {
reachparent[dup] = reachparent[s]
}
*s = *dup *s = *dup
} else if dup.Type == 0 { } else if dup.Type == 0 {
s.Attr |= dup.Attr s.Attr |= dup.Attr
if dup.Attr.Reachable() && reachparent != nil {
reachparent[s] = reachparent[dup]
}
*dup = *s *dup = *s
syms.hash[v][new] = s syms.hash[v][new] = s
} }