Commit d0e40833 authored by David Crawshaw's avatar David Crawshaw

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: default avatarIan Lance Taylor <iant@golang.org>
parent e22c7966
...@@ -84,5 +84,13 @@ func main() { ...@@ -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")
} }
// 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 ...@@ -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() { ...@@ -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() { ...@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment