diff options
| author | Todd Neal <todd@tneal.org> | 2017-04-25 19:32:48 -0400 |
|---|---|---|
| committer | Todd Neal <todd@tneal.org> | 2017-04-26 00:54:54 +0000 |
| commit | 7a92395ddd8354e49d2a928c99027a1a321ea716 (patch) | |
| tree | e7605714058de1432ae197db4c0b8aa1662a492f /src/plugin/plugin_dlopen.go | |
| parent | 819d1cce6e1cfc4439219a22f9356f6885546029 (diff) | |
| download | go-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/plugin_dlopen.go')
| -rw-r--r-- | src/plugin/plugin_dlopen.go | 43 |
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 { |
