diff --git a/misc/cgo/testplugin/src/host/host.go b/misc/cgo/testplugin/src/host/host.go index 0fe28663c7..636655aa5c 100644 --- a/misc/cgo/testplugin/src/host/host.go +++ b/misc/cgo/testplugin/src/host/host.go @@ -84,5 +84,13 @@ func main() { 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") } diff --git a/misc/cgo/testplugin/src/plugin2/plugin2.go b/misc/cgo/testplugin/src/plugin2/plugin2.go new file mode 100644 index 0000000000..6c23a5e633 --- /dev/null +++ b/misc/cgo/testplugin/src/plugin2/plugin2.go @@ -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") +} diff --git a/misc/cgo/testplugin/test.bash b/misc/cgo/testplugin/test.bash index 7a40934e0e..322d43901d 100755 --- a/misc/cgo/testplugin/test.bash +++ b/misc/cgo/testplugin/test.bash @@ -23,6 +23,7 @@ rm -rf pkg sub mkdir sub 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 host diff --git a/src/cmd/link/internal/ld/deadcode.go b/src/cmd/link/internal/ld/deadcode.go index 7ecc5b1ec2..ac64813228 100644 --- a/src/cmd/link/internal/ld/deadcode.go +++ b/src/cmd/link/internal/ld/deadcode.go @@ -252,8 +252,10 @@ func (d *deadcodepass) init() { // We don't keep the go.plugin.exports symbol, // but we do keep the symbols it refers to. exports := d.ctxt.Syms.ROLookup("go.plugin.exports", 0) - for _, r := range exports.R { - d.mark(r.Sym, nil) + if exports != nil { + for _, r := range exports.R { + d.mark(r.Sym, nil) + } } } for _, name := range markextra { diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go index ef96c04067..323136c6f9 100644 --- a/src/cmd/link/internal/ld/symtab.go +++ b/src/cmd/link/internal/ld/symtab.go @@ -588,8 +588,7 @@ func (ctxt *Link) symtab() { adduint(ctxt, moduledata, uint64(nitablinks)) adduint(ctxt, moduledata, uint64(nitablinks)) // The ptab slice - if Buildmode == BuildmodePlugin { - ptab := ctxt.Syms.ROLookup("go.plugin.tabs", 0) + if ptab := ctxt.Syms.ROLookup("go.plugin.tabs", 0); ptab != nil { ptab.Attr |= AttrReachable ptab.Attr |= AttrLocal ptab.Type = obj.SRODATA