aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/plugin.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/plugin.go')
-rw-r--r--src/runtime/plugin.go32
1 files changed, 32 insertions, 0 deletions
diff --git a/src/runtime/plugin.go b/src/runtime/plugin.go
index 845bf76e92..80869e1b1c 100644
--- a/src/runtime/plugin.go
+++ b/src/runtime/plugin.go
@@ -51,6 +51,9 @@ func plugin_lastmoduleinit() (path string, syms map[string]interface{}, mismatch
modulesinit()
typelinksinit()
+ pluginftabverify(md)
+ moduledataverify1(md)
+
lock(&ifaceLock)
for _, i := range md.itablinks {
additab(i, true, false)
@@ -82,6 +85,35 @@ func plugin_lastmoduleinit() (path string, syms map[string]interface{}, mismatch
return md.pluginpath, syms, ""
}
+func pluginftabverify(md *moduledata) {
+ badtable := false
+ for i := 0; i < len(md.ftab); i++ {
+ entry := md.ftab[i].entry
+ if md.minpc <= entry && entry <= md.maxpc {
+ continue
+ }
+
+ f := (*_func)(unsafe.Pointer(&md.pclntable[md.ftab[i].funcoff]))
+ name := funcname(f)
+
+ // A common bug is f.entry has a relocation to a duplicate
+ // function symbol, meaning if we search for its PC we get
+ // a valid entry with a name that is useful for debugging.
+ name2 := "none"
+ entry2 := uintptr(0)
+ f2 := findfunc(entry)
+ if f2 != nil {
+ name2 = funcname(f2)
+ entry2 = f2.entry
+ }
+ badtable = true
+ println("ftab entry outside pc range: ", hex(entry), "/", hex(entry2), ": ", name, "/", name2)
+ }
+ if badtable {
+ throw("runtime: plugin has bad symbol table")
+ }
+}
+
// inRange reports whether v0 or v1 are in the range [r0, r1].
func inRange(r0, r1, v0, v1 uintptr) bool {
return (v0 >= r0 && v0 <= r1) || (v1 >= r0 && v1 <= r1)