github.com/eh-steve/goloader@v0.0.0-20240111193454-90ff3cfdae39/init.1.13.go (about) 1 //go:build go1.13 && !go1.21 2 // +build go1.13,!go1.21 3 4 package goloader 5 6 import ( 7 "cmd/objfile/objabi" 8 "strings" 9 "unsafe" 10 ) 11 12 const ( 13 _InitTaskSuffix = "..inittask" 14 ) 15 16 func getInitFuncName(packagename string) string { 17 return objabi.PathToPrefix(packagename) + _InitTaskSuffix 18 } 19 20 // doInit is defined in package runtime 21 // 22 //go:linkname doInit runtime.doInit 23 func doInit(t unsafe.Pointer) // t should be a *runtime.initTask 24 25 type initTask struct { 26 state uintptr // 0 = uninitialized, 1 = in progress, 2 = done 27 ndeps uintptr 28 nfns uintptr 29 } 30 31 func (linker *Linker) doInitialize(codeModule *CodeModule, symbolMap map[string]uintptr) error { 32 for _, name := range linker.initFuncs { 33 if taskPtr, ok := symbolMap[name]; ok && taskPtr != 0 { // taskPtr may be nil if the inittask wasn't seen in the host symtab (probably a no-op and therefore eliminated) 34 shouldSkipDedup := false 35 for _, pkgPath := range linker.options.SkipTypeDeduplicationForPackages { 36 if strings.HasPrefix(name, pkgPath) { 37 shouldSkipDedup = true 38 } 39 } 40 if shouldSkipDedup { 41 x := (*initTask)(unsafe.Pointer(taskPtr)) 42 x.state = 0 // Reset the inittask state in order to rerun the init function for the new version of the package 43 } 44 doInit(adduintptr(taskPtr, 0)) 45 } 46 } 47 return nil 48 }