Commit a5f57d79 authored by Michael Hudson-Doyle's avatar Michael Hudson-Doyle Committed by Ian Lance Taylor

cmd/link: when reading symbols from a shared library, allow duplicates when they are both in bss

This makes the behaviour match what happens when duplicate symbols are read
from regular object files and fixes errors about cgoAlwaysFalse when linking
an executable that uses cgo against a shared library.

Change-Id: Ibb8cd8fe3f7813cde504b7483f1e857868d7e063
Reviewed-on: https://go-review.googlesource.com/11117Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
parent b1be1217
......@@ -309,6 +309,13 @@ func TestTrivialExecutable(t *testing.T) {
AssertHasRPath(t, "./bin/trivial", gorootInstallDir)
}
// Build an executable that uses cgo linked against the shared runtime and check it
// runs.
func TestCgoExecutable(t *testing.T) {
goCmd(t, "install", "-linkshared", "execgo")
run(t, "cgo executable", "./bin/execgo")
}
// Build a GOPATH package into a shared library that links against the goroot runtime
// and an executable that links against both.
func TestGopathShlib(t *testing.T) {
......
package main
/*
*/
import "C"
func main() {
}
......@@ -1290,25 +1290,34 @@ func ldshlibsyms(shlib string) {
Diag("cannot read symbols from shared library: %s", libpath)
return
}
for _, s := range syms {
if elf.ST_TYPE(s.Info) == elf.STT_NOTYPE || elf.ST_TYPE(s.Info) == elf.STT_SECTION {
for _, elfsym := range syms {
if elf.ST_TYPE(elfsym.Info) == elf.STT_NOTYPE || elf.ST_TYPE(elfsym.Info) == elf.STT_SECTION {
continue
}
lsym := Linklookup(Ctxt, s.Name, 0)
lsym := Linklookup(Ctxt, elfsym.Name, 0)
if lsym.Type != 0 && lsym.Type != obj.SDYNIMPORT && lsym.Dupok == 0 {
Diag(
"Found duplicate symbol %s reading from %s, first found in %s",
s.Name, shlib, lsym.File)
if (lsym.Type != obj.SBSS && lsym.Type != obj.SNOPTRBSS) || len(lsym.R) != 0 || len(lsym.P) != 0 || f.Sections[elfsym.Section].Type != elf.SHT_NOBITS {
Diag("Found duplicate symbol %s reading from %s, first found in %s", elfsym.Name, shlib, lsym.File)
}
if lsym.Size > int64(elfsym.Size) {
// If the existing symbol is a BSS value that is
// larger than the one read from the shared library,
// keep references to that. Conversely, if the
// version from the shared libray is larger, we want
// to make all references be to that.
continue
}
}
lsym.Type = obj.SDYNIMPORT
lsym.ElfType = elf.ST_TYPE(s.Info)
if s.Section != elf.SHN_UNDEF {
lsym.ElfType = elf.ST_TYPE(elfsym.Info)
lsym.Size = int64(elfsym.Size)
if elfsym.Section != elf.SHN_UNDEF {
// Set .File for the library that actually defines the symbol.
lsym.File = libpath
// The decodetype_* functions in decodetype.go need access to
// the type data.
if strings.HasPrefix(lsym.Name, "type.") && !strings.HasPrefix(lsym.Name, "type..") {
lsym.P = readelfsymboldata(f, &s)
lsym.P = readelfsymboldata(f, &elfsym)
}
}
}
......
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