aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/plugin.go
diff options
context:
space:
mode:
authorDavid Crawshaw <crawshaw@golang.org>2016-10-30 15:31:21 -0400
committerDavid Crawshaw <crawshaw@golang.org>2016-10-31 04:48:42 +0000
commit9da7058466c8c9f32e1481f28d57732832ee3b30 (patch)
tree4efee9a2f4753fe894765b9f2409b23c4fdfe4fb /src/runtime/plugin.go
parent590fce48849cc7f81b890d6e9b6120fc6681e19a (diff)
downloadgo-9da7058466c8c9f32e1481f28d57732832ee3b30.tar.xz
cmd/link, plugin: use full plugin path for symbols
Plumb the import path of a plugin package through to the linker, and use it as the prefix on the exported symbol names. Before this we used the basename of the plugin file as the prefix, which could conflict and result in multiple loaded plugins sharing symbols that are distinct. Fixes #17155 Fixes #17579 Change-Id: I7ce966ca82d04e8507c0bcb8ea4ad946809b1ef5 Reviewed-on: https://go-review.googlesource.com/32355 Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/runtime/plugin.go')
-rw-r--r--src/runtime/plugin.go41
1 files changed, 24 insertions, 17 deletions
diff --git a/src/runtime/plugin.go b/src/runtime/plugin.go
index 4a85a1f500..91fc275a65 100644
--- a/src/runtime/plugin.go
+++ b/src/runtime/plugin.go
@@ -7,7 +7,7 @@ package runtime
import "unsafe"
//go:linkname plugin_lastmoduleinit plugin.lastmoduleinit
-func plugin_lastmoduleinit() map[string]interface{} {
+func plugin_lastmoduleinit() (path string, syms map[string]interface{}) {
md := firstmoduledata.next
if md == nil {
throw("runtime: no plugin module data")
@@ -19,20 +19,27 @@ func plugin_lastmoduleinit() map[string]interface{} {
throw("runtime: plugin already initialized")
}
- if fmd := &firstmoduledata; inRange(fmd.text, fmd.etext, md.text, md.etext) ||
- inRange(fmd.bss, fmd.ebss, md.bss, md.ebss) ||
- inRange(fmd.data, fmd.edata, md.data, md.edata) ||
- inRange(fmd.types, fmd.etypes, md.types, md.etypes) {
- println("plugin: new module data overlaps with firstmoduledata")
- println("\tfirstmoduledata.text-etext=", hex(fmd.text), "-", hex(fmd.etext))
- println("\tfirstmoduledata.bss-ebss=", hex(fmd.bss), "-", hex(fmd.ebss))
- println("\tfirstmoduledata.data-edata=", hex(fmd.data), "-", hex(fmd.edata))
- println("\tfirstmoduledata.types-etypes=", hex(fmd.types), "-", hex(fmd.etypes))
- println("\tmd.text-etext=", hex(md.text), "-", hex(md.etext))
- println("\tmd.bss-ebss=", hex(md.bss), "-", hex(md.ebss))
- println("\tmd.data-edata=", hex(md.data), "-", hex(md.edata))
- println("\tmd.types-etypes=", hex(md.types), "-", hex(md.etypes))
- throw("plugin: new module data overlaps with firstmoduledata")
+ for pmd := &firstmoduledata; pmd != md; pmd = pmd.next {
+ if pmd.pluginpath == md.pluginpath {
+ println("plugin: plugin", md.pluginpath, "already loaded")
+ throw("plugin: plugin already loaded")
+ }
+
+ if inRange(pmd.text, pmd.etext, md.text, md.etext) ||
+ inRange(pmd.bss, pmd.ebss, md.bss, md.ebss) ||
+ inRange(pmd.data, pmd.edata, md.data, md.edata) ||
+ inRange(pmd.types, pmd.etypes, md.types, md.etypes) {
+ println("plugin: new module data overlaps with previous moduledata")
+ println("\tpmd.text-etext=", hex(pmd.text), "-", hex(pmd.etext))
+ println("\tpmd.bss-ebss=", hex(pmd.bss), "-", hex(pmd.ebss))
+ println("\tpmd.data-edata=", hex(pmd.data), "-", hex(pmd.edata))
+ println("\tpmd.types-etypes=", hex(pmd.types), "-", hex(pmd.etypes))
+ println("\tmd.text-etext=", hex(md.text), "-", hex(md.etext))
+ println("\tmd.bss-ebss=", hex(md.bss), "-", hex(md.ebss))
+ println("\tmd.data-edata=", hex(md.data), "-", hex(md.edata))
+ println("\tmd.types-etypes=", hex(md.types), "-", hex(md.etypes))
+ throw("plugin: new module data overlaps with previous moduledata")
+ }
}
// Initialize the freshly loaded module.
@@ -54,7 +61,7 @@ func plugin_lastmoduleinit() map[string]interface{} {
// Because functions are handled specially in the plugin package,
// function symbol names are prefixed here with '.' to avoid
// a dependency on the reflect package.
- syms := make(map[string]interface{}, len(md.ptab))
+ syms = make(map[string]interface{}, len(md.ptab))
for _, ptab := range md.ptab {
symName := resolveNameOff(unsafe.Pointer(md.types), ptab.name)
t := (*_type)(unsafe.Pointer(md.types)).typeOff(ptab.typ)
@@ -68,7 +75,7 @@ func plugin_lastmoduleinit() map[string]interface{} {
}
syms[name] = val
}
- return syms
+ return md.pluginpath, syms
}
// inRange reports whether v0 or v1 are in the range [r0, r1].