mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[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:
parent
112a7cb82c
commit
860f12a2fc
8 changed files with 67 additions and 83 deletions
|
|
@ -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])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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() {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue