]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link, runtime: put hasmain bit in moduledata
authorDavid Crawshaw <crawshaw@golang.org>
Mon, 9 Oct 2017 20:04:44 +0000 (16:04 -0400)
committerDavid Crawshaw <crawshaw@golang.org>
Fri, 13 Oct 2017 01:13:33 +0000 (01:13 +0000)
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>
misc/cgo/testplugin/src/issue22175/main.go [new file with mode: 0644]
misc/cgo/testplugin/src/issue22175/plugin1.go [new file with mode: 0644]
misc/cgo/testplugin/src/issue22175/plugin2.go [new file with mode: 0644]
misc/cgo/testplugin/test.bash
src/cmd/link/internal/ld/symtab.go
src/runtime/symtab.go

diff --git a/misc/cgo/testplugin/src/issue22175/main.go b/misc/cgo/testplugin/src/issue22175/main.go
new file mode 100644 (file)
index 0000000..9be9bab
--- /dev/null
@@ -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)
+       }
+}
diff --git a/misc/cgo/testplugin/src/issue22175/plugin1.go b/misc/cgo/testplugin/src/issue22175/plugin1.go
new file mode 100644 (file)
index 0000000..5ae6cb6
--- /dev/null
@@ -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() {}
diff --git a/misc/cgo/testplugin/src/issue22175/plugin2.go b/misc/cgo/testplugin/src/issue22175/plugin2.go
new file mode 100644 (file)
index 0000000..f387a19
--- /dev/null
@@ -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() {}
index 6c13aa5fd79e8fb166408f5ee135d2c4acd1de2b..dbc28b19aa242f46edf528d80cb8e23422af5fad 100755 (executable)
@@ -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
index 0a819fcd2364c7e4a2d5b5cc3d33a9051e34ee81..c77298e870cfa343718a6a90b22697de4eb07728 100644 (file)
@@ -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
index 542c29ecd677b03d0654fbe70bb8564cc4c58b17..2f426c7bf151b574f7de4d22fafb6e51e59f9246 100644 (file)
@@ -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