mirror of
https://github.com/golang/go
synced 2024-11-26 22:21:27 -07:00
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/11117 Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
b1be121791
commit
a5f57d7950
@ -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) {
|
||||
|
8
misc/cgo/testshared/src/execgo/exe.go
Normal file
8
misc/cgo/testshared/src/execgo/exe.go
Normal file
@ -0,0 +1,8 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user