first version of plugins working

Add a caveat about -trimpath too.

Fixes #18.
pull/22/head
Daniel Martí 4 years ago
parent 012d5d6b34
commit 7321b29efe

@ -66,3 +66,6 @@ to document the current shortcomings of this tool.
* Functions implemented outside Go, such as assembly, aren't garbled since we
currently only transform the input Go source.
* Since `garble` forces `-trimpath`, plugins built with `-garble` must be loaded
from Go programs built with `-trimpath` too.

@ -477,13 +477,22 @@ func transformGo(file *ast.File, info *types.Info) *ast.File {
if pkg == nil {
return true // universe scope
}
if vr, ok := obj.(*types.Var); ok && vr.Embedded() {
// ObjectOf returns the field for embedded struct
// fields, not the type it uses. Use the type.
obj = objOf(obj.Type())
pkg = obj.Pkg()
}
if pkg.Name() == "main" && obj.Exported() && obj.Parent() == pkg.Scope() {
// TODO: only do this when -buildmode is plugin? what
// about other -buildmode options?
return true // could be a Go plugin API
}
// log.Printf("%#v %T", node, obj)
switch x := obj.(type) {
case *types.Var:
if x.Embedded() {
obj = objOf(obj.Type())
pkg = obj.Pkg()
} else if x.IsField() && x.Exported() {
if x.IsField() && x.Exported() {
// might be used for reflection, e.g.
// encoding/json without struct tags
return true

@ -0,0 +1,54 @@
garble build -buildmode=plugin ./plugin
binsubstr plugin.so 'PublicVar' 'PublicFunc'
! binsubstr plugin.so 'privateFunc'
# Note that we need -trimpath; see the caveat section in the README.
go build -trimpath
exec ./main
cmp stdout main.stdout
binsubstr main$exe 'PublicVar' 'PublicFunc'
! binsubstr plugin.so 'privateFunc'
[short] stop # no need to verify this with -short
go build -buildmode=plugin ./plugin
binsubstr plugin.so 'PublicVar' 'PublicFunc' 'privateFunc'
go build
exec ./main
cmp stdout main.stdout
-- go.mod --
module test/main
-- plugin/main.go --
package main
import "fmt"
var PublicVar int
func privateFunc(n int) { fmt.Printf("Hello, number %d\n", n) }
func PublicFunc() { privateFunc(PublicVar) }
-- main.go --
package main
import "plugin"
func main() {
p, err := plugin.Open("plugin.so")
if err != nil {
panic(err)
}
v, err := p.Lookup("PublicVar")
if err != nil {
panic(err)
}
f, err := p.Lookup("PublicFunc")
if err != nil {
panic(err)
}
*v.(*int) = 7
f.(func())()
}
-- main.stdout --
Hello, number 7

@ -30,6 +30,12 @@ type Embedding struct {
Embedded
}
type embedded int
type embedding struct {
embedded
}
func main() {
switch V := V.(type) {
case int:

Loading…
Cancel
Save