diff options
| author | David Crawshaw <crawshaw@golang.org> | 2016-08-26 08:50:50 -0400 |
|---|---|---|
| committer | David Crawshaw <crawshaw@golang.org> | 2016-09-16 17:54:40 +0000 |
| commit | 0cbb12f0bbaeb3893b3d011fdb1a270291747ab0 (patch) | |
| tree | 27aad9e8d195e1bc06a2f93b14cdec6839474d62 /src/runtime/plugin.go | |
| parent | c87528d7761e3f133fe238937019a18bf7cf0d3c (diff) | |
| download | go-0cbb12f0bbaeb3893b3d011fdb1a270291747ab0.tar.xz | |
plugin: new package for loading plugins
Includes a linux implementation.
Change-Id: Iacc2ed7da760ae9deebc928adf2b334b043b07ec
Reviewed-on: https://go-review.googlesource.com/27823
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/runtime/plugin.go')
| -rw-r--r-- | src/runtime/plugin.go | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/runtime/plugin.go b/src/runtime/plugin.go index f5f3aa2e5b..2e01650824 100644 --- a/src/runtime/plugin.go +++ b/src/runtime/plugin.go @@ -4,6 +4,57 @@ package runtime +import "unsafe" + +//go:linkname plugin_lastmoduleinit plugin.lastmoduleinit +func plugin_lastmoduleinit() map[string]interface{} { + md := firstmoduledata.next + if md == nil { + throw("runtime: no plugin module data") + } + for md.next != nil { + md = md.next + } + if md.typemap != nil { + throw("runtime: plugin already initialized") + } + + // Initialize the freshly loaded module. + typelinksinit() + md.gcdatamask = progToPointerMask((*byte)(unsafe.Pointer(md.gcdata)), md.edata-md.data) + md.gcbssmask = progToPointerMask((*byte)(unsafe.Pointer(md.gcbss)), md.ebss-md.bss) + + lock(&ifaceLock) + for _, i := range md.itablinks { + additab(i, true, false) + } + unlock(&ifaceLock) + + // Build a map of symbol names to symbols. Here in the runtime + // we fill out the first word of the interface, the type. We + // pass these zero value interfaces to the plugin package, + // where the symbol value is filled in (usually via cgo). + // + // 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)) + for _, ptab := range md.ptab { + symName := resolveNameOff(unsafe.Pointer(md.types), ptab.name) + t := (*_type)(unsafe.Pointer(md.types)).typeOff(ptab.typ) + var val interface{} + valp := (*[2]unsafe.Pointer)(unsafe.Pointer(&val)) + (*valp)[0] = unsafe.Pointer(t) + + name := symName.name() + if t.kind&kindMask == kindFunc { + name = "." + name + } + syms[name] = val + } + return syms +} + // A ptabEntry is generated by the compiler for each exported function // and global variable in the main package of a plugin. It is used to // initialize the plugin module's symbol map. |
