Commit 956e9e6c authored by Michael Hudson-Doyle's avatar Michael Hudson-Doyle

cmd/link: do not add duplicate symbols to Allsym

When building shared libraries, all symbols on Allsym are marked reachable.
What I didn't realize was that this includes the ".dup" symbols created when
"dupok" symbols are read from multiple package files. This breaks now because
deadcode makes some assumptions that fail for these ".dup" symbols, but in any
case was a bad idea -- I suspect this change makes libstd.so a bunch smaller,
but creating it was broken before this CL so I can't be sure.

This change simply stops adding these symbols to Allsym, which might make some
of the many iterations over Allsym the linker does a touch quicker, although
that's not the motivation here.

Add a test that no symbols called ".dup" makes it into the runtime shared
library.

Fixes #14841

Change-Id: I65dd6e88d150a770db2d01b75cfe5db5fd4f8d25
Reviewed-on: https://go-review.googlesource.com/20780
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent b2b5e779
......@@ -203,6 +203,26 @@ func TestNoTextrel(t *testing.T) {
}
}
// The shared library does not contain symbols called ".dup"
func TestNoDupSymbols(t *testing.T) {
sopath := filepath.Join(gorootInstallDir, soname)
f, err := elf.Open(sopath)
if err != nil {
t.Fatal("elf.Open failed: ", err)
}
defer f.Close()
syms, err := f.Symbols()
if err != nil {
t.Errorf("error reading symbols %v", err)
return
}
for _, s := range syms {
if s.Name == ".dup" {
t.Fatalf("%s contains symbol called .dup", sopath)
}
}
}
// The install command should have created a "shlibname" file for the
// listed packages (and runtime/cgo, and math on arm) indicating the
// name of the shared library containing it.
......
......@@ -348,7 +348,7 @@ func decodetype_methods(s *LSym) []methodsig {
numMethods := int(decode_inuxi(s.P[off+2*Thearch.Ptrsize:], Thearch.Intsize))
r := decode_reloc(s, int32(off+Thearch.Ptrsize))
if r.Sym != s {
panic(fmt.Sprintf("method slice pointer in %q leads to a different symbol", s.Name))
panic(fmt.Sprintf("method slice pointer in %s leads to a different symbol %s", s, r.Sym))
}
off = int(r.Add) // array of reflect.method values
sizeofMethod := 5 * Thearch.Ptrsize // sizeof reflect.method in program
......
......@@ -175,8 +175,6 @@ func ldobjfile(ctxt *Link, f *obj.Biobuf, pkg string, length int64, pn string) {
}
}
var readsym_ndup int
func readsym(ctxt *Link, f *obj.Biobuf, pkg string, pn string) {
if obj.Bgetc(f) != 0xfe {
log.Fatalf("readsym out of sync")
......@@ -211,8 +209,7 @@ func readsym(ctxt *Link, f *obj.Biobuf, pkg string, pn string) {
}
if len(s.P) > 0 {
dup = s
s = linknewsym(ctxt, ".dup", readsym_ndup)
readsym_ndup++ // scratch
s = linknewsym(ctxt, ".dup", -1)
}
}
......
......@@ -173,7 +173,11 @@ func linknewsym(ctxt *Link, symb string, v int) *LSym {
s.Version = int16(v)
ctxt.Nsymbol++
ctxt.Allsym = append(ctxt.Allsym, s)
if v != -1 {
ctxt.Allsym = append(ctxt.Allsym, s)
} else if v < -1 {
ctxt.Diag("invalid version %d in linknewsym", v)
}
return s
}
......
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