Commit 09df9b06 authored by Than McIntosh's avatar Than McIntosh

cmd/link: split out Extname into cold portion of sym.Symbol

Create a new "AuxSymbol" struct into which 'cold' or 'infrequently
set' symbol fields are located. Move the Extname field from the
main Symbol struct to AuxSymbol.

Updates #26186

Change-Id: I9e795fb0cc48f978e2818475fa073ed9f2db202d
Reviewed-on: https://go-review.googlesource.com/125476Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 289dce24
...@@ -1034,7 +1034,7 @@ func elfdynhash(ctxt *Link) { ...@@ -1034,7 +1034,7 @@ func elfdynhash(ctxt *Link) {
need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib(), sy.Dynimpvers()) need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib(), sy.Dynimpvers())
} }
name := sy.Extname name := sy.Extname()
hc := elfhash(name) hc := elfhash(name)
b := hc % uint32(nbucket) b := hc % uint32(nbucket)
...@@ -2254,7 +2254,7 @@ func elfadddynsym(ctxt *Link, s *sym.Symbol) { ...@@ -2254,7 +2254,7 @@ func elfadddynsym(ctxt *Link, s *sym.Symbol) {
d := ctxt.Syms.Lookup(".dynsym", 0) d := ctxt.Syms.Lookup(".dynsym", 0)
name := s.Extname name := s.Extname()
d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name))) d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
/* type */ /* type */
...@@ -2297,7 +2297,7 @@ func elfadddynsym(ctxt *Link, s *sym.Symbol) { ...@@ -2297,7 +2297,7 @@ func elfadddynsym(ctxt *Link, s *sym.Symbol) {
d := ctxt.Syms.Lookup(".dynsym", 0) d := ctxt.Syms.Lookup(".dynsym", 0)
/* name */ /* name */
name := s.Extname name := s.Extname()
d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name))) d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
......
...@@ -156,7 +156,7 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) { ...@@ -156,7 +156,7 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
s := ctxt.Syms.Lookup(local, 0) s := ctxt.Syms.Lookup(local, 0)
if s.Type == 0 || s.Type == sym.SXREF || s.Type == sym.SHOSTOBJ { if s.Type == 0 || s.Type == sym.SXREF || s.Type == sym.SHOSTOBJ {
s.SetDynimplib(lib) s.SetDynimplib(lib)
s.Extname = remote s.SetExtname(remote)
s.SetDynimpvers(q) s.SetDynimpvers(q)
if s.Type != sym.SHOSTOBJ { if s.Type != sym.SHOSTOBJ {
s.Type = sym.SDYNIMPORT s.Type = sym.SDYNIMPORT
...@@ -200,15 +200,15 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) { ...@@ -200,15 +200,15 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
// see issue 4878. // see issue 4878.
if s.Dynimplib() != "" { if s.Dynimplib() != "" {
s.ResetDyninfo() s.ResetDyninfo()
s.Extname = "" s.SetExtname("")
s.Type = 0 s.Type = 0
} }
if !s.Attr.CgoExport() { if !s.Attr.CgoExport() {
s.Extname = remote s.SetExtname(remote)
dynexp = append(dynexp, s) dynexp = append(dynexp, s)
} else if s.Extname != remote { } else if s.Extname() != remote {
fmt.Fprintf(os.Stderr, "%s: conflicting cgo_export directives: %s as %s and %s\n", os.Args[0], s.Name, s.Extname, remote) fmt.Fprintf(os.Stderr, "%s: conflicting cgo_export directives: %s as %s and %s\n", os.Args[0], s.Name, s.Extname(), remote)
nerrors++ nerrors++
return return
} }
...@@ -276,7 +276,7 @@ func Adddynsym(ctxt *Link, s *sym.Symbol) { ...@@ -276,7 +276,7 @@ func Adddynsym(ctxt *Link, s *sym.Symbol) {
if ctxt.IsELF { if ctxt.IsELF {
elfadddynsym(ctxt, s) elfadddynsym(ctxt, s)
} else if ctxt.HeadType == objabi.Hdarwin { } else if ctxt.HeadType == objabi.Hdarwin {
Errorf(s, "adddynsym: missed symbol (Extname=%s)", s.Extname) Errorf(s, "adddynsym: missed symbol (Extname=%s)", s.Extname())
} else if ctxt.HeadType == objabi.Hwindows { } else if ctxt.HeadType == objabi.Hwindows {
// already taken care of // already taken care of
} else { } else {
......
...@@ -435,7 +435,7 @@ func (ctxt *Link) loadlib() { ...@@ -435,7 +435,7 @@ func (ctxt *Link) loadlib() {
// cgo_import_static and cgo_import_dynamic, // cgo_import_static and cgo_import_dynamic,
// then we want to make it cgo_import_dynamic // then we want to make it cgo_import_dynamic
// now. // now.
if s.Extname != "" && s.Dynimplib() != "" && !s.Attr.CgoExport() { if s.Extname() != "" && s.Dynimplib() != "" && !s.Attr.CgoExport() {
s.Type = sym.SDYNIMPORT s.Type = sym.SDYNIMPORT
} else { } else {
s.Type = 0 s.Type = 0
...@@ -2116,7 +2116,7 @@ func genasmsym(ctxt *Link, put func(*Link, *sym.Symbol, string, SymbolType, int6 ...@@ -2116,7 +2116,7 @@ func genasmsym(ctxt *Link, put func(*Link, *sym.Symbol, string, SymbolType, int6
if !s.Attr.Reachable() { if !s.Attr.Reachable() {
continue continue
} }
put(ctxt, s, s.Extname, UndefinedSym, 0, nil) put(ctxt, s, s.Extname(), UndefinedSym, 0, nil)
case sym.STLSBSS: case sym.STLSBSS:
if ctxt.LinkMode == LinkExternal { if ctxt.LinkMode == LinkExternal {
......
...@@ -724,7 +724,7 @@ func (x machoscmp) Less(i, j int) bool { ...@@ -724,7 +724,7 @@ func (x machoscmp) Less(i, j int) bool {
return k1 < k2 return k1 < k2
} }
return s1.Extname < s2.Extname return s1.Extname() < s2.Extname()
} }
func machogenasmsym(ctxt *Link) { func machogenasmsym(ctxt *Link) {
...@@ -763,7 +763,7 @@ func machoShouldExport(ctxt *Link, s *sym.Symbol) bool { ...@@ -763,7 +763,7 @@ func machoShouldExport(ctxt *Link, s *sym.Symbol) bool {
if !ctxt.DynlinkingGo() || s.Attr.Local() { if !ctxt.DynlinkingGo() || s.Attr.Local() {
return false return false
} }
if ctxt.BuildMode == BuildModePlugin && strings.HasPrefix(s.Extname, objabi.PathToPrefix(*flagPluginPath)) { if ctxt.BuildMode == BuildModePlugin && strings.HasPrefix(s.Extname(), objabi.PathToPrefix(*flagPluginPath)) {
return true return true
} }
if strings.HasPrefix(s.Name, "go.itab.") { if strings.HasPrefix(s.Name, "go.itab.") {
...@@ -798,13 +798,13 @@ func machosymtab(ctxt *Link) { ...@@ -798,13 +798,13 @@ func machosymtab(ctxt *Link) {
// symbols like crosscall2 are in pclntab and end up // symbols like crosscall2 are in pclntab and end up
// pointing at the host binary, breaking unwinding. // pointing at the host binary, breaking unwinding.
// See Issue #18190. // See Issue #18190.
cexport := !strings.Contains(s.Extname, ".") && (ctxt.BuildMode != BuildModePlugin || onlycsymbol(s)) cexport := !strings.Contains(s.Extname(), ".") && (ctxt.BuildMode != BuildModePlugin || onlycsymbol(s))
if cexport || export { if cexport || export {
symstr.AddUint8('_') symstr.AddUint8('_')
} }
// replace "·" as ".", because DTrace cannot handle it. // replace "·" as ".", because DTrace cannot handle it.
Addstring(symstr, strings.Replace(s.Extname, "·", ".", -1)) Addstring(symstr, strings.Replace(s.Extname(), "·", ".", -1))
if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ { if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ {
symtab.AddUint8(0x01) // type N_EXT, external symbol symtab.AddUint8(0x01) // type N_EXT, external symbol
......
...@@ -1040,14 +1040,15 @@ func initdynimport(ctxt *Link) *Dll { ...@@ -1040,14 +1040,15 @@ func initdynimport(ctxt *Link) *Dll {
// of uinptrs this function consumes. Store the argsize and discard // of uinptrs this function consumes. Store the argsize and discard
// the %n suffix if any. // the %n suffix if any.
m.argsize = -1 m.argsize = -1
if i := strings.IndexByte(s.Extname, '%'); i >= 0 { extName := s.Extname()
if i := strings.IndexByte(extName, '%'); i >= 0 {
var err error var err error
m.argsize, err = strconv.Atoi(s.Extname[i+1:]) m.argsize, err = strconv.Atoi(extName[i+1:])
if err != nil { if err != nil {
Errorf(s, "failed to parse stdcall decoration: %v", err) Errorf(s, "failed to parse stdcall decoration: %v", err)
} }
m.argsize *= ctxt.Arch.PtrSize m.argsize *= ctxt.Arch.PtrSize
s.Extname = s.Extname[:i] s.SetExtname(extName[:i])
} }
m.s = s m.s = s
...@@ -1061,7 +1062,7 @@ func initdynimport(ctxt *Link) *Dll { ...@@ -1061,7 +1062,7 @@ func initdynimport(ctxt *Link) *Dll {
for m = d.ms; m != nil; m = m.next { for m = d.ms; m != nil; m = m.next {
m.s.Type = sym.SDATA m.s.Type = sym.SDATA
m.s.Grow(int64(ctxt.Arch.PtrSize)) m.s.Grow(int64(ctxt.Arch.PtrSize))
dynName := m.s.Extname dynName := m.s.Extname()
// only windows/386 requires stdcall decoration // only windows/386 requires stdcall decoration
if ctxt.Arch.Family == sys.I386 && m.argsize >= 0 { if ctxt.Arch.Family == sys.I386 && m.argsize >= 0 {
dynName += fmt.Sprintf("@%d", m.argsize) dynName += fmt.Sprintf("@%d", m.argsize)
...@@ -1132,7 +1133,7 @@ func addimports(ctxt *Link, datsect *peSection) { ...@@ -1132,7 +1133,7 @@ func addimports(ctxt *Link, datsect *peSection) {
for m := d.ms; m != nil; m = m.next { for m := d.ms; m != nil; m = m.next {
m.off = uint64(pefile.nextSectOffset) + uint64(ctxt.Out.Offset()) - uint64(startoff) m.off = uint64(pefile.nextSectOffset) + uint64(ctxt.Out.Offset()) - uint64(startoff)
ctxt.Out.Write16(0) // hint ctxt.Out.Write16(0) // hint
strput(ctxt.Out, m.s.Extname) strput(ctxt.Out, m.s.Extname())
} }
} }
...@@ -1217,7 +1218,7 @@ type byExtname []*sym.Symbol ...@@ -1217,7 +1218,7 @@ type byExtname []*sym.Symbol
func (s byExtname) Len() int { return len(s) } func (s byExtname) Len() int { return len(s) }
func (s byExtname) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s byExtname) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s byExtname) Less(i, j int) bool { return s[i].Extname < s[j].Extname } func (s byExtname) Less(i, j int) bool { return s[i].Extname() < s[j].Extname() }
func initdynexport(ctxt *Link) { func initdynexport(ctxt *Link) {
nexport = 0 nexport = 0
...@@ -1242,7 +1243,7 @@ func addexports(ctxt *Link) { ...@@ -1242,7 +1243,7 @@ func addexports(ctxt *Link) {
size := binary.Size(&e) + 10*nexport + len(*flagOutfile) + 1 size := binary.Size(&e) + 10*nexport + len(*flagOutfile) + 1
for i := 0; i < nexport; i++ { for i := 0; i < nexport; i++ {
size += len(dexport[i].Extname) + 1 size += len(dexport[i].Extname()) + 1
} }
if nexport == 0 { if nexport == 0 {
...@@ -1286,7 +1287,7 @@ func addexports(ctxt *Link) { ...@@ -1286,7 +1287,7 @@ func addexports(ctxt *Link) {
for i := 0; i < nexport; i++ { for i := 0; i < nexport; i++ {
out.Write32(uint32(v)) out.Write32(uint32(v))
v += len(dexport[i].Extname) + 1 v += len(dexport[i].Extname()) + 1
} }
// put EXPORT Ordinal Table // put EXPORT Ordinal Table
...@@ -1298,7 +1299,7 @@ func addexports(ctxt *Link) { ...@@ -1298,7 +1299,7 @@ func addexports(ctxt *Link) {
out.WriteStringN(*flagOutfile, len(*flagOutfile)+1) out.WriteStringN(*flagOutfile, len(*flagOutfile)+1)
for i := 0; i < nexport; i++ { for i := 0; i < nexport; i++ {
out.WriteStringN(dexport[i].Extname, len(dexport[i].Extname)+1) out.WriteStringN(dexport[i].Extname(), len(dexport[i].Extname())+1)
} }
sect.pad(out, uint32(size)) sect.pad(out, uint32(size))
} }
......
...@@ -23,7 +23,7 @@ func TestSizeof(t *testing.T) { ...@@ -23,7 +23,7 @@ func TestSizeof(t *testing.T) {
_32bit uintptr // size on 32bit platforms _32bit uintptr // size on 32bit platforms
_64bit uintptr // size on 64bit platforms _64bit uintptr // size on 64bit platforms
}{ }{
{Symbol{}, 132, 216}, {Symbol{}, 124, 200},
} }
for _, tt := range tests { for _, tt := range tests {
......
...@@ -15,7 +15,6 @@ import ( ...@@ -15,7 +15,6 @@ import (
// Symbol is an entry in the symbol table. // Symbol is an entry in the symbol table.
type Symbol struct { type Symbol struct {
Name string Name string
Extname string
Type SymKind Type SymKind
Version int16 Version int16
Attr Attribute Attr Attribute
...@@ -36,7 +35,7 @@ type Symbol struct { ...@@ -36,7 +35,7 @@ type Symbol struct {
Outer *Symbol Outer *Symbol
Gotype *Symbol Gotype *Symbol
File string File string
dyninfo *dynimp auxinfo *AuxSymbol
Sect *Section Sect *Section
FuncInfo *FuncInfo FuncInfo *FuncInfo
Lib *Library // Package defining this symbol Lib *Library // Package defining this symbol
...@@ -45,7 +44,9 @@ type Symbol struct { ...@@ -45,7 +44,9 @@ type Symbol struct {
R []Reloc R []Reloc
} }
type dynimp struct { // AuxSymbol contains less-frequently used sym.Symbol fields.
type AuxSymbol struct {
extname string
dynimplib string dynimplib string
dynimpvers string dynimpvers string
} }
...@@ -268,38 +269,62 @@ func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64 ...@@ -268,38 +269,62 @@ func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64
return off + wid return off + wid
} }
func (s *Symbol) makeAuxInfo() {
if s.auxinfo == nil {
s.auxinfo = &AuxSymbol{extname: s.Name}
}
}
func (s *Symbol) Extname() string {
if s.auxinfo == nil {
return s.Name
}
return s.auxinfo.extname
}
func (s *Symbol) SetExtname(n string) {
if s.auxinfo == nil {
if s.Name == n {
return
}
s.makeAuxInfo()
}
s.auxinfo.extname = n
}
func (s *Symbol) Dynimplib() string { func (s *Symbol) Dynimplib() string {
if s.dyninfo == nil { if s.auxinfo == nil {
return "" return ""
} }
return s.dyninfo.dynimplib return s.auxinfo.dynimplib
} }
func (s *Symbol) Dynimpvers() string { func (s *Symbol) Dynimpvers() string {
if s.dyninfo == nil { if s.auxinfo == nil {
return "" return ""
} }
return s.dyninfo.dynimpvers return s.auxinfo.dynimpvers
} }
func (s *Symbol) SetDynimplib(lib string) { func (s *Symbol) SetDynimplib(lib string) {
if s.dyninfo == nil { if s.auxinfo == nil {
s.dyninfo = &dynimp{dynimplib: lib} s.makeAuxInfo()
} else {
s.dyninfo.dynimplib = lib
} }
s.auxinfo.dynimplib = lib
} }
func (s *Symbol) SetDynimpvers(vers string) { func (s *Symbol) SetDynimpvers(vers string) {
if s.dyninfo == nil { if s.auxinfo == nil {
s.dyninfo = &dynimp{dynimpvers: vers} s.makeAuxInfo()
} else {
s.dyninfo.dynimpvers = vers
} }
s.auxinfo.dynimpvers = vers
} }
func (s *Symbol) ResetDyninfo() { func (s *Symbol) ResetDyninfo() {
s.dyninfo = nil if s.auxinfo != nil {
s.auxinfo.dynimplib = ""
s.auxinfo.dynimpvers = ""
}
} }
// SortSub sorts a linked-list (by Sub) of *Symbol by Value. // SortSub sorts a linked-list (by Sub) of *Symbol by Value.
......
...@@ -77,7 +77,6 @@ func (syms *Symbols) Lookup(name string, v int) *Symbol { ...@@ -77,7 +77,6 @@ func (syms *Symbols) Lookup(name string, v int) *Symbol {
return s return s
} }
s = syms.Newsym(name, v) s = syms.Newsym(name, v)
s.Extname = s.Name
m[name] = s m[name] = s
return s return s
} }
...@@ -97,9 +96,10 @@ func (syms *Symbols) IncVersion() int { ...@@ -97,9 +96,10 @@ 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, reachparent map[*Symbol]*Symbol) {
s := syms.hash[v][old] s := syms.hash[v][old]
oldExtName := s.Extname()
s.Name = new s.Name = new
if s.Extname == old { if oldExtName == old {
s.Extname = new s.SetExtname(new)
} }
delete(syms.hash[v], old) delete(syms.hash[v], old)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment