mirror of
https://github.com/golang/go
synced 2024-11-11 21:50:21 -07:00
cmd/link, runtime: put hasmain bit in moduledata
Currently we look to see if the main.main symbol address is in the module data text range. This requires access to the main.main symbol, which usually the runtime has, but does not when building a plugin. To avoid a dynamic relocation to main.main (which I haven't worked out how to have the linker generate on darwin), stop using the symbol. Instead record a boolean in the moduledata if the module has the main function. Fixes #22175 Change-Id: If313a118f17ab499d0a760bbc2519771ed654530 Reviewed-on: https://go-review.googlesource.com/69370 Run-TryBot: David Crawshaw <crawshaw@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
d06815ba3f
commit
c58b98b2d6
28
misc/cgo/testplugin/src/issue22175/main.go
Normal file
28
misc/cgo/testplugin/src/issue22175/main.go
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"plugin"
|
||||
)
|
||||
|
||||
func main() {
|
||||
p2, err := plugin.Open("issue22175_plugin1.so")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
f, err := p2.Lookup("F")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
got := f.(func() int)()
|
||||
const want = 971
|
||||
if got != want {
|
||||
fmt.Fprintf(os.Stderr, "issue22175: F()=%d, want %d", got, want)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
21
misc/cgo/testplugin/src/issue22175/plugin1.go
Normal file
21
misc/cgo/testplugin/src/issue22175/plugin1.go
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import "plugin"
|
||||
|
||||
func F() int {
|
||||
p2, err := plugin.Open("issue22175_plugin2.so")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
g, err := p2.Lookup("G")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return g.(func() int)()
|
||||
}
|
||||
|
||||
func main() {}
|
9
misc/cgo/testplugin/src/issue22175/plugin2.go
Normal file
9
misc/cgo/testplugin/src/issue22175/plugin2.go
Normal file
@ -0,0 +1,9 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
func G() int { return 971 }
|
||||
|
||||
func main() {}
|
@ -74,3 +74,9 @@ GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue19418 src/issue19418/main.
|
||||
|
||||
# Test for issue 19529
|
||||
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o plugin.so src/issue19529/plugin.go
|
||||
|
||||
# Test for issue 22175
|
||||
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue22175_plugin1.so src/issue22175/plugin1.go
|
||||
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue22175_plugin2.so src/issue22175/plugin2.go
|
||||
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue22175 src/issue22175/main.go
|
||||
./issue22175
|
||||
|
@ -641,6 +641,13 @@ func (ctxt *Link) symtab() {
|
||||
moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Shlibs)))
|
||||
}
|
||||
|
||||
hasmain := ctxt.BuildMode == BuildModeExe || ctxt.BuildMode == BuildModePIE
|
||||
if hasmain {
|
||||
moduledata.AddUint8(1)
|
||||
} else {
|
||||
moduledata.AddUint8(0)
|
||||
}
|
||||
|
||||
// The rest of moduledata is zero initialized.
|
||||
// When linking an object that does not contain the runtime we are
|
||||
// creating the moduledata from scratch and it does not have a
|
||||
|
@ -375,6 +375,8 @@ type moduledata struct {
|
||||
modulename string
|
||||
modulehashes []modulehash
|
||||
|
||||
hasmain uint8 // 1 if module contains the main function, 0 otherwise
|
||||
|
||||
gcdatamask, gcbssmask bitvector
|
||||
|
||||
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
||||
@ -472,9 +474,8 @@ func modulesinit() {
|
||||
// contains the main function.
|
||||
//
|
||||
// See Issue #18729.
|
||||
mainText := funcPC(main_main)
|
||||
for i, md := range *modules {
|
||||
if md.text <= mainText && mainText <= md.etext {
|
||||
if md.hasmain != 0 {
|
||||
(*modules)[0] = md
|
||||
(*modules)[i] = &firstmoduledata
|
||||
break
|
||||
|
Loading…
Reference in New Issue
Block a user