Commit f00bfb38 authored by Than McIntosh's avatar Than McIntosh Committed by Brad Fitzpatrick

cmd/link: split off 'Dynimp' string fields to reduce sym.Symbol size

The linker's sym.Symbol struct contains two string fields, "Dynimplib"
and "Dynimpvers" that are used only in very specific circumstances
(for many symbols, such as DWARF syms, they are wasted space). Split
these two off into a separate struct, then point to an instance of
that struct when needed. This reduces the size of sym.Symbol so as to
save space in the common case.

Updates #26186

Change-Id: Id9c74824e78423a215c8cbc105b72665525a1eff
Reviewed-on: https://go-review.googlesource.com/121916Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
parent 32bc0976
......@@ -1030,8 +1030,8 @@ func elfdynhash(ctxt *Link) {
continue
}
if sy.Dynimpvers != "" {
need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib, sy.Dynimpvers)
if sy.Dynimpvers() != "" {
need[sy.Dynid] = addelflib(&needlib, sy.Dynimplib(), sy.Dynimpvers())
}
name := sy.Extname
......@@ -2287,8 +2287,8 @@ func elfadddynsym(ctxt *Link, s *sym.Symbol) {
/* size of object */
d.AddUint64(ctxt.Arch, uint64(s.Size))
if ctxt.Arch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib != "" && !seenlib[s.Dynimplib] {
Elfwritedynent(ctxt, ctxt.Syms.Lookup(".dynamic", 0), DT_NEEDED, uint64(Addstring(ctxt.Syms.Lookup(".dynstr", 0), s.Dynimplib)))
if ctxt.Arch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib() != "" && !seenlib[s.Dynimplib()] {
Elfwritedynent(ctxt, ctxt.Syms.Lookup(".dynamic", 0), DT_NEEDED, uint64(Addstring(ctxt.Syms.Lookup(".dynstr", 0), s.Dynimplib())))
}
} else {
s.Dynid = int32(Nelfsym)
......
......@@ -155,9 +155,9 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
}
s := ctxt.Syms.Lookup(local, 0)
if s.Type == 0 || s.Type == sym.SXREF || s.Type == sym.SHOSTOBJ {
s.Dynimplib = lib
s.SetDynimplib(lib)
s.Extname = remote
s.Dynimpvers = q
s.SetDynimpvers(q)
if s.Type != sym.SHOSTOBJ {
s.Type = sym.SDYNIMPORT
}
......@@ -198,10 +198,9 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
// export overrides import, for openbsd/cgo.
// see issue 4878.
if s.Dynimplib != "" {
s.Dynimplib = ""
if s.Dynimplib() != "" {
s.ResetDyninfo()
s.Extname = ""
s.Dynimpvers = ""
s.Type = 0
}
......
......@@ -416,7 +416,7 @@ func (ctxt *Link) loadlib() {
// cgo_import_static and cgo_import_dynamic,
// then we want to make it cgo_import_dynamic
// now.
if s.Extname != "" && s.Dynimplib != "" && !s.Attr.CgoExport() {
if s.Extname != "" && s.Dynimplib() != "" && !s.Attr.CgoExport() {
s.Type = sym.SDYNIMPORT
} else {
s.Type = 0
......
......@@ -989,7 +989,7 @@ func initdynimport(ctxt *Link) *Dll {
continue
}
for d = dr; d != nil; d = d.next {
if d.name == s.Dynimplib {
if d.name == s.Dynimplib() {
m = new(Imp)
break
}
......@@ -997,7 +997,7 @@ func initdynimport(ctxt *Link) *Dll {
if d == nil {
d = new(Dll)
d.name = s.Dynimplib
d.name = s.Dynimplib()
d.next = dr
dr = d
m = new(Imp)
......
......@@ -805,7 +805,7 @@ func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length i
s.Type = sect.sym.Type
s.Attr |= sym.AttrSubSymbol
if !s.Attr.CgoExportDynamic() {
s.Dynimplib = "" // satisfy dynimport
s.SetDynimplib("") // satisfy dynimport
}
s.Value = int64(elfsym.value)
s.Size = int64(elfsym.size)
......
......@@ -644,7 +644,7 @@ func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length i
s.Outer = outer
s.Value = int64(machsym.value - sect.addr)
if !s.Attr.CgoExportDynamic() {
s.Dynimplib = "" // satisfy dynimport
s.SetDynimplib("") // satisfy dynimport
}
if outer.Type == sym.STEXT {
if s.Attr.External() && !s.Attr.DuplicateOK() {
......
......@@ -31,21 +31,25 @@ type Symbol struct {
// ElfType is set for symbols read from shared libraries by ldshlibsyms. It
// is not set for symbols defined by the packages being linked or by symbols
// read by ldelf (and so is left as elf.STT_NOTYPE).
ElfType elf.SymType
Sub *Symbol
Outer *Symbol
Gotype *Symbol
File string
Dynimplib string
Dynimpvers string
Sect *Section
FuncInfo *FuncInfo
Lib *Library // Package defining this symbol
ElfType elf.SymType
Sub *Symbol
Outer *Symbol
Gotype *Symbol
File string
dyninfo *dynimp
Sect *Section
FuncInfo *FuncInfo
Lib *Library // Package defining this symbol
// P contains the raw symbol data.
P []byte
R []Reloc
}
type dynimp struct {
dynimplib string
dynimpvers string
}
func (s *Symbol) String() string {
if s.Version == 0 {
return s.Name
......@@ -264,6 +268,40 @@ func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64
return off + wid
}
func (s *Symbol) Dynimplib() string {
if s.dyninfo == nil {
return ""
}
return s.dyninfo.dynimplib
}
func (s *Symbol) Dynimpvers() string {
if s.dyninfo == nil {
return ""
}
return s.dyninfo.dynimpvers
}
func (s *Symbol) SetDynimplib(lib string) {
if s.dyninfo == nil {
s.dyninfo = &dynimp{dynimplib: lib}
} else {
s.dyninfo.dynimplib = lib
}
}
func (s *Symbol) SetDynimpvers(vers string) {
if s.dyninfo == nil {
s.dyninfo = &dynimp{dynimpvers: vers}
} else {
s.dyninfo.dynimpvers = vers
}
}
func (s *Symbol) ResetDyninfo() {
s.dyninfo = nil
}
// SortSub sorts a linked-list (by Sub) of *Symbol by Value.
// Used for sub-symbols when loading host objects (see e.g. ldelf.go).
func SortSub(l *Symbol) *Symbol {
......
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