]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/link: mark unexported methods for plugins
authorCherry Mui <cherryyz@google.com>
Wed, 16 Mar 2022 17:07:57 +0000 (13:07 -0400)
committerCherry Mui <cherryyz@google.com>
Wed, 16 Mar 2022 20:10:07 +0000 (20:10 +0000)
When plugin is used, we already mark all exported methods
reachable. However, when the plugin and the host program share
a common package, an unexported method could also be reachable
from both the plugin and the host via interfaces. We need to mark
them as well.

Fixes #51621.

Change-Id: I1a70d3f96b66b803f2d0ab14d00ed0df276ea500
Reviewed-on: https://go-review.googlesource.com/c/go/+/393365
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
misc/cgo/testplugin/plugin_test.go
misc/cgo/testplugin/testdata/method3/main.go [new file with mode: 0644]
misc/cgo/testplugin/testdata/method3/p/p.go [new file with mode: 0644]
misc/cgo/testplugin/testdata/method3/plugin.go [new file with mode: 0644]
src/cmd/link/internal/ld/deadcode.go

index 10c5db2646b14824aa6c387569270c57eeb87678..53e79a462653992be5a77ca3c24e3f5c955786fc 100644 (file)
@@ -283,6 +283,12 @@ func TestMethod2(t *testing.T) {
        run(t, "./method2.exe")
 }
 
+func TestMethod3(t *testing.T) {
+       goCmd(t, "build", "-buildmode=plugin", "-o", "method3.so", "./method3/plugin.go")
+       goCmd(t, "build", "-o", "method3.exe", "./method3/main.go")
+       run(t, "./method3.exe")
+}
+
 func TestIssue44956(t *testing.T) {
        goCmd(t, "build", "-buildmode=plugin", "-o", "issue44956p1.so", "./issue44956/plugin1.go")
        goCmd(t, "build", "-buildmode=plugin", "-o", "issue44956p2.so", "./issue44956/plugin2.go")
diff --git a/misc/cgo/testplugin/testdata/method3/main.go b/misc/cgo/testplugin/testdata/method3/main.go
new file mode 100644 (file)
index 0000000..a3a5171
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2022 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.
+
+// An unexported method can be reachable from the plugin via interface
+// when a package is shared. So it need to be live.
+
+package main
+
+import (
+       "plugin"
+
+       "testplugin/method3/p"
+)
+
+var i p.I
+
+func main() {
+       pl, err := plugin.Open("method3.so")
+       if err != nil {
+               panic(err)
+       }
+
+       f, err := pl.Lookup("F")
+       if err != nil {
+               panic(err)
+       }
+
+       f.(func())()
+
+       i = p.T(123)
+}
diff --git a/misc/cgo/testplugin/testdata/method3/p/p.go b/misc/cgo/testplugin/testdata/method3/p/p.go
new file mode 100644 (file)
index 0000000..3846bc0
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2022 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 p
+
+type T int
+
+func (T) m() { println("m") }
+
+type I interface { m() }
+
+func F() {
+       i.m()
+}
+
+var i I = T(123)
diff --git a/misc/cgo/testplugin/testdata/method3/plugin.go b/misc/cgo/testplugin/testdata/method3/plugin.go
new file mode 100644 (file)
index 0000000..bd25b31
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2022 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 "testplugin/method3/p"
+
+func main() {}
+
+func F() { p.F() }
index dba22323b0c5ea664c9e63056b0e1285e10e1f2d..3ba4b06f4a5fe1cd00697625895e965054e3196d 100644 (file)
@@ -355,7 +355,7 @@ func deadcode(ctxt *Link) {
                // in the last pass.
                rem := d.markableMethods[:0]
                for _, m := range d.markableMethods {
-                       if (d.reflectSeen && m.isExported()) || d.ifaceMethod[m.m] || d.genericIfaceMethod[m.m.name] {
+                       if (d.reflectSeen && (m.isExported() || d.dynlink)) || d.ifaceMethod[m.m] || d.genericIfaceMethod[m.m.name] {
                                d.markMethod(m)
                        } else {
                                rem = append(rem, m)