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  }