aboutsummaryrefslogtreecommitdiff
path: root/src/plugin
diff options
context:
space:
mode:
authorTodd Neal <todd@tneal.org>2017-04-25 19:32:48 -0400
committerTodd Neal <todd@tneal.org>2017-04-26 00:54:54 +0000
commit7a92395ddd8354e49d2a928c99027a1a321ea716 (patch)
treee7605714058de1432ae197db4c0b8aa1662a492f /src/plugin
parent819d1cce6e1cfc4439219a22f9356f6885546029 (diff)
downloadgo-7a92395ddd8354e49d2a928c99027a1a321ea716.tar.xz
plugin: resolve plugin import path issue
Resolve import paths to get plugin symbol prefixes. Fixes #19534 Change-Id: Ic25d83e72465ba8f6be0337218a1627b5dc702dc Reviewed-on: https://go-review.googlesource.com/40994 Run-TryBot: Todd Neal <todd@tneal.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Crawshaw <crawshaw@golang.org>
Diffstat (limited to 'src/plugin')
-rw-r--r--src/plugin/plugin_dlopen.go43
1 files changed, 42 insertions, 1 deletions
diff --git a/src/plugin/plugin_dlopen.go b/src/plugin/plugin_dlopen.go
index 72e219e337..3237598f06 100644
--- a/src/plugin/plugin_dlopen.go
+++ b/src/plugin/plugin_dlopen.go
@@ -39,6 +39,47 @@ import (
"unsafe"
)
+// avoid a dependency on strings
+func lastIndexByte(s string, c byte) int {
+ for i := len(s) - 1; i >= 0; i-- {
+ if s[i] == c {
+ return i
+ }
+ }
+ 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 := (*C.char)(C.malloc(C.PATH_MAX + 1))
defer C.free(unsafe.Pointer(cPath))
@@ -103,7 +144,7 @@ func open(name string) (*Plugin, error) {
delete(syms, symName)
symName = symName[1:]
}
- cname := C.CString(pluginpath + "." + symName)
+ cname := C.CString(pathToPrefix(pluginpath) + "." + symName)
p := C.pluginLookup(h, cname, &cErr)
C.free(unsafe.Pointer(cname))
if p == nil {