]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link, plugin: always encode path
authorDavid Crawshaw <crawshaw@golang.org>
Sat, 21 Oct 2017 11:29:46 +0000 (07:29 -0400)
committerDavid Crawshaw <crawshaw@golang.org>
Thu, 26 Oct 2017 15:08:37 +0000 (15:08 +0000)
Both the linker and the plugin package were inconsistent
about when they applied the path encoding defined in
objabi.PathToPrefix. As a result, only some symbols from
a package path that required encoding were being found.

So always encoding the path.

Fixes #22295

Change-Id: Ife86c79ca20b2e9307008ed83885e193d32b7dc4
Reviewed-on: https://go-review.googlesource.com/72390
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/issue22295.pkg/main.go [new file with mode: 0644]
misc/cgo/testplugin/src/issue22295.pkg/plugin.go [new file with mode: 0644]
misc/cgo/testplugin/test.bash
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/deadcode.go
src/cmd/link/internal/ld/symtab.go
src/plugin/plugin_dlopen.go

diff --git a/misc/cgo/testplugin/src/issue22295.pkg/main.go b/misc/cgo/testplugin/src/issue22295.pkg/main.go
new file mode 100644 (file)
index 0000000..6cb186e
--- /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.
+
+// +build ignore
+
+package main
+
+import (
+       "log"
+       "plugin"
+)
+
+func main() {
+       p, err := plugin.Open("issue.22295.so")
+       if err != nil {
+               log.Fatal(err)
+       }
+       f, err := p.Lookup("F")
+       if err != nil {
+               log.Fatal(err)
+       }
+       const want = 2503
+       got := f.(func() int)()
+       if got != want {
+               log.Fatalf("got %d, want %d", got, want)
+       }
+}
diff --git a/misc/cgo/testplugin/src/issue22295.pkg/plugin.go b/misc/cgo/testplugin/src/issue22295.pkg/plugin.go
new file mode 100644 (file)
index 0000000..46b08a4
--- /dev/null
@@ -0,0 +1,16 @@
+// 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
+
+var f *int
+
+func init() {
+       f = new(int)
+       *f = 2503
+}
+
+func F() int { return *f }
+
+func main() {}
index eed7fc451b3411f1ab9bcdb86a3f1a42cd243542..18e3803bf42aee1d2deec227e764885ba6d39cd2 100755 (executable)
@@ -80,3 +80,8 @@ GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue22175_pl
 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
+
+# Test for issue 22295
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue.22295.so issue22295.pkg
+GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue22295 src/issue22295.pkg/main.go
+./issue22295
index 3572d7309dbce0da1abe97ff2e3509e4108d6aec..459a75e8acb116a58e377905601843bf99dafc4c 100644 (file)
@@ -782,10 +782,11 @@ func addstrdata1(ctxt *Link, arg string) {
        if eq < 0 || dot < 0 {
                Exitf("-X flag requires argument of the form importpath.name=value")
        }
-       pkg := objabi.PathToPrefix(arg[:dot])
+       pkg := arg[:dot]
        if ctxt.BuildMode == BuildModePlugin && pkg == "main" {
                pkg = *flagPluginPath
        }
+       pkg = objabi.PathToPrefix(pkg)
        addstrdata(ctxt, pkg+arg[dot:eq], arg[eq+1:])
 }
 
index c065146fcd28684a37761b546137c9cb27be5524..600c49aa129025c77f8945254fdc2b20086a929e 100644 (file)
@@ -230,7 +230,7 @@ func (d *deadcodepass) init() {
                        }
                        names = append(names, *flagEntrySymbol)
                        if d.ctxt.BuildMode == BuildModePlugin {
-                               names = append(names, *flagPluginPath+".init", *flagPluginPath+".main", "go.plugin.tabs")
+                               names = append(names, objabi.PathToPrefix(*flagPluginPath)+".init", objabi.PathToPrefix(*flagPluginPath)+".main", "go.plugin.tabs")
 
                                // We don't keep the go.plugin.exports symbol,
                                // but we do keep the symbols it refers to.
index 20ac6b7139c08dbc8d7eccbd5ccda4a2742d45c9..bb8c1992ba877ad2055271a9fa2aead4b859f6c7 100644 (file)
@@ -586,7 +586,7 @@ func (ctxt *Link) symtab() {
                moduledata.AddUint(ctxt.Arch, 0)
        }
        if ctxt.BuildMode == BuildModePlugin {
-               addgostring(ctxt, moduledata, "go.link.thispluginpath", *flagPluginPath)
+               addgostring(ctxt, moduledata, "go.link.thispluginpath", objabi.PathToPrefix(*flagPluginPath))
 
                pkghashes := ctxt.Syms.Lookup("go.link.pkghashes", 0)
                pkghashes.Attr |= sym.AttrReachable
index 37380989d7f57061c3d3960317c23c9dae820ac3..47f2b29a80b8dcd51f5cb2620aa9fcd9d069707b 100644 (file)
@@ -49,37 +49,6 @@ func lastIndexByte(s string, c byte) int {
        return -1
 }
 
-// pathToPrefix converts raw string to the prefix that will be used in the symbol
-// table. If modifying, modify the version in internal/obj/sym.go as well.
-func pathToPrefix(s string) string {
-       slash := lastIndexByte(s, '/')
-       // check for chars that need escaping
-       n := 0
-       for r := 0; r < len(s); r++ {
-               if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
-                       n++
-               }
-       }
-
-       // quick exit
-       if n == 0 {
-               return s
-       }
-
-       // escape
-       const hex = "0123456789abcdef"
-       p := make([]byte, 0, len(s)+2*n)
-       for r := 0; r < len(s); r++ {
-               if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
-                       p = append(p, '%', hex[c>>4], hex[c&0xF])
-               } else {
-                       p = append(p, c)
-               }
-       }
-
-       return string(p)
-}
-
 func open(name string) (*Plugin, error) {
        cPath := make([]byte, C.PATH_MAX+1)
        cRelName := make([]byte, len(name)+1)
@@ -153,7 +122,7 @@ func open(name string) (*Plugin, error) {
                        symName = symName[1:]
                }
 
-               fullName := pathToPrefix(pluginpath) + "." + symName
+               fullName := pluginpath + "." + symName
                cname := make([]byte, len(fullName)+1)
                copy(cname, fullName)