]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: pass plugin package name to compile -p
authorDavid Crawshaw <crawshaw@golang.org>
Fri, 1 Sep 2017 15:20:33 +0000 (11:20 -0400)
committerDavid Crawshaw <crawshaw@golang.org>
Fri, 1 Sep 2017 18:27:59 +0000 (18:27 +0000)
When compiling a plugin, package main gets a new name so as not to
conflict with the main package in the host binary, or any other
plugins. It is already defined by cmd/go, and used by cmd/link when
filling out the "" package placeholder in symbols.

With this CL, the plugin-specific name for main is also passed to
cmd/compile's -p flag. This is used to fill out the pkgpath field
of types, and ensures that two types defined in two different plugin
mains with the same name will not be mistaken for one another at
runtime.

Fixes #21386

Change-Id: I8a646d8d7451caff533fe0007343ea8b8e1704ed
Reviewed-on: https://go-review.googlesource.com/60910
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/host/host.go
misc/cgo/testplugin/src/plugin1/plugin1.go
misc/cgo/testplugin/src/plugin2/plugin2.go
src/cmd/go/internal/work/build.go

index 898f44efa154e967e026aefbbe14607d67259cca..bba9a621667e9169765ce2e45516948c632a5997 100644 (file)
@@ -126,10 +126,12 @@ func main() {
                log.Fatalf(`plugin1.F()=%d, want 17`, gotf)
        }
 
-       // plugin2 has no exported symbols, only an init function.
-       if _, err := plugin.Open("plugin2.so"); err != nil {
+       p2, err := plugin.Open("plugin2.so")
+       if err != nil {
                log.Fatalf("plugin.Open failed: %v", err)
        }
+       // Check that plugin2's init function was called, and
+       // that it modifies the same global variable as the host.
        if got, want := common.X, 2; got != want {
                log.Fatalf("after loading plugin2, common.X=%d, want %d", got, want)
        }
@@ -142,6 +144,15 @@ func main() {
                log.Fatalf(`plugin.Open("plugin-mismatch.so"): error does not mention "different version": %v`, s)
        }
 
+       // Test that unexported types with the same names in
+       // different plugins do not interfere with each other.
+       //
+       // See Issue #21386.
+       UnexportedNameReuse, _ := p.Lookup("UnexportedNameReuse")
+       UnexportedNameReuse.(func())()
+       UnexportedNameReuse, _ = p2.Lookup("UnexportedNameReuse")
+       UnexportedNameReuse.(func())()
+
        testUnnamed()
 
        fmt.Println("PASS")
index edcef2c77e9167fa6548b534bafc0d9dc2c4a319..0a9fa2f2c1f0bf4b7e445467a7d4b6b5bb4a5f5d 100644 (file)
@@ -7,7 +7,10 @@ package main
 // // No C code required.
 import "C"
 
-import "common"
+import (
+       "common"
+       "reflect"
+)
 
 func F() int {
        _ = make([]byte, 1<<21) // trigger stack unwind, Issue #18190.
@@ -33,6 +36,21 @@ func init() {
        call(g)
 }
 
+type sameNameReusedInPlugins struct {
+       X string
+}
+
+type sameNameHolder struct {
+       F *sameNameReusedInPlugins
+}
+
+func UnexportedNameReuse() {
+       h := sameNameHolder{}
+       v := reflect.ValueOf(&h).Elem().Field(0)
+       newval := reflect.New(v.Type().Elem())
+       v.Set(newval)
+}
+
 func main() {
        panic("plugin1.main called")
 }
index 9c507fc36581c7676052ed444c463198aa3621a4..a67f2de27a7f824a318b79b71364c16670a9f557 100644 (file)
@@ -13,6 +13,7 @@ import "C"
 
 import (
        "common"
+       "reflect"
        "strings"
 )
 
@@ -22,6 +23,21 @@ func init() {
        common.X = 2
 }
 
+type sameNameReusedInPlugins struct {
+       X string
+}
+
+type sameNameHolder struct {
+       F *sameNameReusedInPlugins
+}
+
+func UnexportedNameReuse() {
+       h := sameNameHolder{}
+       v := reflect.ValueOf(&h).Elem().Field(0)
+       newval := reflect.New(v.Type().Elem())
+       v.Set(newval)
+}
+
 func main() {
        panic("plugin1.main called")
 }
index 2659058931f9304f4f2dc2ba48a5383405d6ca6f..d6c7f0bcff0aabd34b5e3551bba696b54e3f7dc2 100644 (file)
@@ -2198,10 +2198,15 @@ func (gcToolchain) gc(b *Builder, p *load.Package, archive, objdir string, asmhd
                ofile = objdir + out
        }
 
-       gcargs := []string{"-p", p.ImportPath}
-       if p.Name == "main" {
-               gcargs[1] = "main"
+       pkgpath := p.ImportPath
+       if cfg.BuildBuildmode == "plugin" {
+               if pkgpath == "command-line-arguments" {
+                       pkgpath = "plugin/unnamed-" + p.Internal.BuildID
+               }
+       } else if p.Name == "main" {
+               pkgpath = "main"
        }
+       gcargs := []string{"-p", pkgpath}
        if p.Standard {
                gcargs = append(gcargs, "-std")
        }