]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: add source file contents to plugin hash
authorDavid Crawshaw <crawshaw@golang.org>
Sat, 2 Sep 2017 14:31:52 +0000 (10:31 -0400)
committerDavid Crawshaw <crawshaw@golang.org>
Sat, 9 Sep 2017 15:58:20 +0000 (15:58 +0000)
It is common to have multiple plugins built from ephemeral
source files all with the same name:

# generate main.go
go build -buildmode=plugin -o=p1.so main.go
# rm main.go, generate new main.go
go build -buildmode=plugin -o=p2.so main.go
...

These different plugins currently have the same build ID,
and hence the same package path. This means only one can be
loaded.

To remove this restriction, this commit adds the contents of the
main package source files to the plugin hash.

Fixes #19358

Change-Id: Icd42024b085feb29c09c2771aaecb85f8b528dd3
Reviewed-on: https://go-review.googlesource.com/61170
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/test.bash
misc/cgo/testplugin/unnamed1/main.go [moved from misc/cgo/testplugin/unnamed1.go with 100% similarity]
misc/cgo/testplugin/unnamed2/main.go [moved from misc/cgo/testplugin/unnamed2.go with 100% similarity]
src/cmd/go/internal/load/pkg.go
src/cmd/go/internal/work/build.go

index 69df5bd2bfaca9fd350720b219eb84e08b8440f5..7e982c89615f42eed608290af5a81e5f9e880f07 100755 (executable)
@@ -27,8 +27,8 @@ GOPATH=$(pwd) go build -buildmode=plugin plugin1
 GOPATH=$(pwd) go build -buildmode=plugin plugin2
 GOPATH=$(pwd)/altpath go build -buildmode=plugin plugin-mismatch
 GOPATH=$(pwd) go build -buildmode=plugin -o=sub/plugin1.so sub/plugin1
-GOPATH=$(pwd) go build -buildmode=plugin unnamed1.go
-GOPATH=$(pwd) go build -buildmode=plugin unnamed2.go
+GOPATH=$(pwd) go build -buildmode=plugin -o=unnamed1.so unnamed1/main.go
+GOPATH=$(pwd) go build -buildmode=plugin -o=unnamed2.so unnamed2/main.go
 GOPATH=$(pwd) go build host
 
 LD_LIBRARY_PATH=$(pwd) ./host
index be31ef5615ad67ec29862afa3e3f2fc9dfd0e61a..2f5a7a801824e34eb62722832285eb574e9dae91 100644 (file)
@@ -1671,15 +1671,8 @@ func isStale(p *Package) (bool, string) {
        return false, ""
 }
 
-// computeBuildID computes the build ID for p, leaving it in p.Internal.BuildID.
-// Build ID is a hash of the information we want to detect changes in.
-// See the long comment in isStale for details.
-func computeBuildID(p *Package) {
-       h := sha1.New()
-
-       // Include the list of files compiled as part of the package.
-       // This lets us detect removed files. See issue 3895.
-       inputFiles := str.StringList(
+func pkgInputFiles(p *Package) []string {
+       return str.StringList(
                p.GoFiles,
                p.CgoFiles,
                p.CFiles,
@@ -1692,6 +1685,40 @@ func computeBuildID(p *Package) {
                p.SwigFiles,
                p.SwigCXXFiles,
        )
+}
+
+// PluginPath computes the package path for a plugin main package.
+//
+// This is typically the import path of the main package p, unless the
+// plugin is being built directly from source files. In that case we
+// combine the package build ID with the contents of the main package
+// source files. This allows us to identify two different plugins
+// built from two source files with the same name.
+func PluginPath(p *Package) string {
+       if p.ImportPath != "command-line-arguments" {
+               return p.ImportPath
+       }
+       h := sha1.New()
+       fmt.Fprintf(h, "build ID: %s\n", p.Internal.BuildID)
+       for _, file := range str.StringList(p.GoFiles, p.CgoFiles, p.SFiles) {
+               data, err := ioutil.ReadFile(filepath.Join(p.Dir, file))
+               if err != nil {
+                       base.Fatalf("go: %s", err)
+               }
+               h.Write(data)
+       }
+       return fmt.Sprintf("plugin/unnamed-%x", h.Sum(nil))
+}
+
+// computeBuildID computes the build ID for p, leaving it in p.Internal.BuildID.
+// Build ID is a hash of the information we want to detect changes in.
+// See the long comment in isStale for details.
+func computeBuildID(p *Package) {
+       h := sha1.New()
+
+       // Include the list of files compiled as part of the package.
+       // This lets us detect removed files. See issue 3895.
+       inputFiles := pkgInputFiles(p)
        for _, file := range inputFiles {
                fmt.Fprintf(h, "file %s\n", file)
        }
index 0395311ef63712a31f19a5ed471e455242029a2f..6b9c5114736835c91fb8bebfabb4163ca124df5d 100644 (file)
@@ -2200,9 +2200,7 @@ func (gcToolchain) gc(b *Builder, p *load.Package, archive, objdir string, asmhd
 
        pkgpath := p.ImportPath
        if cfg.BuildBuildmode == "plugin" {
-               if pkgpath == "command-line-arguments" {
-                       pkgpath = "plugin/unnamed-" + p.Internal.BuildID
-               }
+               pkgpath = load.PluginPath(p)
        } else if p.Name == "main" {
                pkgpath = "main"
        }
@@ -2536,11 +2534,7 @@ func (gcToolchain) ld(b *Builder, root *Action, out string, allactions []*Action
                ldflags = append(ldflags, "-s", "-w")
        }
        if cfg.BuildBuildmode == "plugin" {
-               pluginpath := root.Package.ImportPath
-               if pluginpath == "command-line-arguments" {
-                       pluginpath = "plugin/unnamed-" + root.Package.Internal.BuildID
-               }
-               ldflags = append(ldflags, "-pluginpath", pluginpath)
+               ldflags = append(ldflags, "-pluginpath", load.PluginPath(root.Package))
        }
 
        // If the user has not specified the -extld option, then specify the