package  runtimeimport  (	"internal/abi" 	"unsafe" )func  plugin_lastmoduleinit path  string , syms  map [string ]any , initTasks  []*initTask , errstr  string ) {	var  md  *moduledata 	for  pmd  := firstmoduledata .next ; pmd  != nil ; pmd  = pmd .next  {		if  pmd .bad  {			md  = nil  			continue 		}		md  = pmd 	}	if  md  == nil  {		throw ("runtime: no plugin module data" )	}	if  md .pluginpath  == ""  {		throw ("runtime: plugin has empty pluginpath" )	}	if  md .typemap  != nil  {		return  "" , nil , nil , "plugin already loaded" 	}	for  _ , pmd  := range  activeModules () {		if  pmd .pluginpath  == md .pluginpath  {			md .bad  = true 			return  "" , nil , nil , "plugin already loaded" 		}		if  inRange (pmd .text , pmd .etext , md .text , md .etext ) ||			inRange (pmd .bss , pmd .ebss , md .bss , md .ebss ) ||			inRange (pmd .data , pmd .edata , md .data , md .edata ) ||			inRange (pmd .types , pmd .etypes , md .types , md .etypes ) {			println ("plugin: new module data overlaps with previous moduledata" )			println ("\tpmd.text-etext=" , hex (pmd .text ), "-" , hex (pmd .etext ))			println ("\tpmd.bss-ebss=" , hex (pmd .bss ), "-" , hex (pmd .ebss ))			println ("\tpmd.data-edata=" , hex (pmd .data ), "-" , hex (pmd .edata ))			println ("\tpmd.types-etypes=" , hex (pmd .types ), "-" , hex (pmd .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 previous moduledata" )		}	}	for  _ , pkghash  := range  md .pkghashes  {		if  pkghash .linktimehash  != *pkghash .runtimehash  {			md .bad  = true 			return  "" , nil , nil , "plugin was built with a different version of package "  + pkghash .modulename 		}	}		modulesinit ()	typelinksinit ()	pluginftabverify (md )	moduledataverify1 (md )	lock (&itabLock )	for  _ , i  := range  md .itablinks  {		itabAdd (i )	}	unlock (&itabLock )		syms  = make (map [string ]any , len (md .ptab ))	for  _ , ptab  := range  md .ptab  {		symName  := resolveNameOff (unsafe .Pointer (md .types ), ptab .name )		t  := toRType ((*_type )(unsafe .Pointer (md .types ))).typeOff (ptab .typ ) 		var  val  any 		valp  := (*[2 ]unsafe .Pointer )(unsafe .Pointer (&val ))		(*valp )[0 ] = unsafe .Pointer (t )		name  := symName .Name ()		if  t .Kind_ &abi .KindMask  == abi .Func  {			name  = "."  + name 		}		syms [name ] = val 	}	return  md .pluginpath , syms , md .inittasks , "" }func  pluginftabverify md  *moduledata ) {	badtable  := false 	for  i  := 0 ; i  < len (md .ftab ); i ++ {		entry  := md .textAddr (md .ftab [i ].entryoff )		if  md .minpc  <= entry  && entry  <= md .maxpc  {			continue 		}		f  := funcInfo {(*_func )(unsafe .Pointer (&md .pclntable [md .ftab [i ].funcoff ])), md }		name  := funcname (f )				name2  := "none" 		entry2  := uintptr (0 )		f2  := findfunc (entry )		if  f2 .valid () {			name2  = funcname (f2 )			entry2  = f2 .entry ()		}		badtable  = true 		println ("ftab entry" , hex (entry ), "/" , hex (entry2 ), ": " ,			name , "/" , name2 , "outside pc range:[" , hex (md .minpc ), "," , hex (md .maxpc ), "], modulename=" , md .modulename , ", pluginpath=" , md .pluginpath )	}	if  badtable  {		throw ("runtime: plugin has bad symbol table" )	}}func  inRange r0 , r1 , v0 , v1  uintptr ) bool  {	return  (v0  >= r0  && v0  <= r1 ) || (v1  >= r0  && v1  <= r1 )}type  ptabEntry  struct  {	name  nameOff 	typ   typeOff } The pages are generated with Golds v0.7.6 . (GOOS=linux GOARCH=amd64)
Golds  is a Go 101  project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101  (reachable from the left QR code) to get the latest news of Golds .