mirror of https://github.com/golang/go.git
cmd/link: support plugins with no exported symbols
A plugin with no exported symbols is still potentially very useful. Its init functions are called on load, and it so it can have visible side effects. Fixes #17681 Change-Id: Icdca31f48e5ab13c99020a2ef724f3de47dcd74b Reviewed-on: https://go-review.googlesource.com/32437 Run-TryBot: David Crawshaw <crawshaw@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
e22c79660d
commit
d0e408334b
|
|
@ -84,5 +84,13 @@ func main() {
|
||||||
log.Fatalf(`plugin1.F()=%d, want 17`, gotf)
|
log.Fatalf(`plugin1.F()=%d, want 17`, gotf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// plugin2 has no exported symbols, only an init function.
|
||||||
|
if _, err := plugin.Open("plugin2.so"); err != nil {
|
||||||
|
log.Fatalf("plugin.Open failed: %v", err)
|
||||||
|
}
|
||||||
|
if got, want := common.X, 2; got != want {
|
||||||
|
log.Fatalf("after loading plugin2, common.X=%d, want %d", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Println("PASS")
|
fmt.Println("PASS")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2016 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
|
||||||
|
|
||||||
|
// // No C code required.
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
import "common"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
common.X = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
panic("plugin1.main called")
|
||||||
|
}
|
||||||
|
|
@ -23,6 +23,7 @@ rm -rf pkg sub
|
||||||
mkdir sub
|
mkdir sub
|
||||||
|
|
||||||
GOPATH=$(pwd) go build -buildmode=plugin plugin1
|
GOPATH=$(pwd) go build -buildmode=plugin plugin1
|
||||||
|
GOPATH=$(pwd) go build -buildmode=plugin plugin2
|
||||||
GOPATH=$(pwd) go build -buildmode=plugin -o=sub/plugin1.so sub/plugin1
|
GOPATH=$(pwd) go build -buildmode=plugin -o=sub/plugin1.so sub/plugin1
|
||||||
GOPATH=$(pwd) go build host
|
GOPATH=$(pwd) go build host
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -252,8 +252,10 @@ func (d *deadcodepass) init() {
|
||||||
// We don't keep the go.plugin.exports symbol,
|
// We don't keep the go.plugin.exports symbol,
|
||||||
// but we do keep the symbols it refers to.
|
// but we do keep the symbols it refers to.
|
||||||
exports := d.ctxt.Syms.ROLookup("go.plugin.exports", 0)
|
exports := d.ctxt.Syms.ROLookup("go.plugin.exports", 0)
|
||||||
for _, r := range exports.R {
|
if exports != nil {
|
||||||
d.mark(r.Sym, nil)
|
for _, r := range exports.R {
|
||||||
|
d.mark(r.Sym, nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, name := range markextra {
|
for _, name := range markextra {
|
||||||
|
|
|
||||||
|
|
@ -588,8 +588,7 @@ func (ctxt *Link) symtab() {
|
||||||
adduint(ctxt, moduledata, uint64(nitablinks))
|
adduint(ctxt, moduledata, uint64(nitablinks))
|
||||||
adduint(ctxt, moduledata, uint64(nitablinks))
|
adduint(ctxt, moduledata, uint64(nitablinks))
|
||||||
// The ptab slice
|
// The ptab slice
|
||||||
if Buildmode == BuildmodePlugin {
|
if ptab := ctxt.Syms.ROLookup("go.plugin.tabs", 0); ptab != nil {
|
||||||
ptab := ctxt.Syms.ROLookup("go.plugin.tabs", 0)
|
|
||||||
ptab.Attr |= AttrReachable
|
ptab.Attr |= AttrReachable
|
||||||
ptab.Attr |= AttrLocal
|
ptab.Attr |= AttrLocal
|
||||||
ptab.Type = obj.SRODATA
|
ptab.Type = obj.SRODATA
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue