diff --git a/src/runtime/plugin.go b/src/runtime/plugin.go index 2e01650824..4a85a1f500 100644 --- a/src/runtime/plugin.go +++ b/src/runtime/plugin.go @@ -19,6 +19,22 @@ func plugin_lastmoduleinit() map[string]interface{} { throw("runtime: plugin already initialized") } + if fmd := &firstmoduledata; inRange(fmd.text, fmd.etext, md.text, md.etext) || + inRange(fmd.bss, fmd.ebss, md.bss, md.ebss) || + inRange(fmd.data, fmd.edata, md.data, md.edata) || + inRange(fmd.types, fmd.etypes, md.types, md.etypes) { + println("plugin: new module data overlaps with firstmoduledata") + println("\tfirstmoduledata.text-etext=", hex(fmd.text), "-", hex(fmd.etext)) + println("\tfirstmoduledata.bss-ebss=", hex(fmd.bss), "-", hex(fmd.ebss)) + println("\tfirstmoduledata.data-edata=", hex(fmd.data), "-", hex(fmd.edata)) + println("\tfirstmoduledata.types-etypes=", hex(fmd.types), "-", hex(fmd.etypes)) + println("\tmd.text-etext=", hex(md.text), "-", hex(md.etext)) + println("\tmd.bss-ebss=", hex(md.bss), "-", hex(md.ebss)) + println("\tmd.data-edata=", hex(md.data), "-", hex(md.edata)) + println("\tmd.types-etypes=", hex(md.types), "-", hex(md.etypes)) + throw("plugin: new module data overlaps with firstmoduledata") + } + // Initialize the freshly loaded module. typelinksinit() md.gcdatamask = progToPointerMask((*byte)(unsafe.Pointer(md.gcdata)), md.edata-md.data) @@ -55,6 +71,11 @@ func plugin_lastmoduleinit() map[string]interface{} { return syms } +// 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) +} + // A ptabEntry is generated by the compiler for each exported function // and global variable in the main package of a plugin. It is used to // initialize the plugin module's symbol map.