mirror of https://github.com/golang/go.git
cmd/compile: mark plugin-exported types as used in interface
Plugin exports symbols as interfaces. Mark their types as used in interfaces, so their methods will be kept alive by the linker. Fixes #42579. Change-Id: If1b5aacc21510c20c25f88bb131bca61db6f1d56 Reviewed-on: https://go-review.googlesource.com/c/go/+/269819 Trust: Cherry Zhang <cherryyz@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
f423d616b1
commit
86954d5246
|
|
@ -196,3 +196,17 @@ func TestIssue25756(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMethod(t *testing.T) {
|
||||||
|
// Exported symbol's method must be live.
|
||||||
|
goCmd(t, "build", "-buildmode=plugin", "-o", "plugin.so", "./method/plugin.go")
|
||||||
|
goCmd(t, "build", "-o", "method.exe", "./method/main.go")
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
cmd := exec.CommandContext(ctx, "./method.exe")
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("%s: %v\n%s", strings.Join(cmd.Args, " "), err, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright 2020 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.
|
||||||
|
|
||||||
|
// Issue 42579: methods of symbols exported from plugin must be live.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"plugin"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
p, err := plugin.Open("plugin.so")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
x, err := p.Lookup("X")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
reflect.ValueOf(x).Elem().MethodByName("M").Call(nil)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
// Copyright 2020 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
|
||||||
|
|
||||||
|
func main() {}
|
||||||
|
|
||||||
|
type T int
|
||||||
|
|
||||||
|
func (T) M() { println("M") }
|
||||||
|
|
||||||
|
var X T
|
||||||
|
|
@ -1591,8 +1591,12 @@ func dumptabs() {
|
||||||
// typ typeOff // pointer to symbol
|
// typ typeOff // pointer to symbol
|
||||||
// }
|
// }
|
||||||
nsym := dname(p.s.Name, "", nil, true)
|
nsym := dname(p.s.Name, "", nil, true)
|
||||||
|
tsym := dtypesym(p.t)
|
||||||
ot = dsymptrOff(s, ot, nsym)
|
ot = dsymptrOff(s, ot, nsym)
|
||||||
ot = dsymptrOff(s, ot, dtypesym(p.t))
|
ot = dsymptrOff(s, ot, tsym)
|
||||||
|
// Plugin exports symbols as interfaces. Mark their types
|
||||||
|
// as UsedInIface.
|
||||||
|
tsym.Set(obj.AttrUsedInIface, true)
|
||||||
}
|
}
|
||||||
ggloblsym(s, int32(ot), int16(obj.RODATA))
|
ggloblsym(s, int32(ot), int16(obj.RODATA))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue