github.com/pkujhd/goloader@v0.0.0-20240411034752-1a28096bd7bd/init.1.21.go (about) 1 //go:build go1.21 && !go1.23 2 // +build go1.21,!go1.23 3 4 package goloader 5 6 import ( 7 "unsafe" 8 9 "github.com/pkujhd/goloader/obj" 10 "github.com/pkujhd/goloader/objabi/reloctype" 11 ) 12 13 type initTask struct { 14 state uint32 // 0 = uninitialized, 1 = in progress, 2 = done 15 nfns uint32 16 // followed by nfns pcs, uintptr sized, one per init function to run 17 } 18 19 const ( 20 _InitTaskSuffix = "..inittask" 21 ) 22 23 func getInitFuncName(packagename string) string { 24 return obj.PathToPrefix(packagename) + _InitTaskSuffix 25 } 26 27 //go:linkname doInit1 runtime.doInit1 28 func doInit1(t unsafe.Pointer) // t should be a *runtime.initTask 29 30 func (linker *Linker) doInitialize(symPtr, symbolMap map[string]uintptr) error { 31 for _, pkg := range linker.Packages { 32 name := getInitFuncName(pkg.PkgPath) 33 if ptr, ok := symbolMap[name]; ok { 34 for _, loc := range linker.SymMap[name].Reloc { 35 if loc.Type == reloctype.R_INITORDER { 36 if locPtr, ok := symPtr[loc.SymName]; ok { 37 doInit1(adduintptr(locPtr, 0)) 38 } else if locPtr, ok := symbolMap[loc.SymName]; ok { 39 doInit1(adduintptr(locPtr, 0)) 40 } 41 } 42 } 43 task := *(*initTask)(adduintptr(ptr, 0)) 44 if task.nfns == 0 { 45 continue 46 } 47 doInit1(adduintptr(ptr, 0)) 48 } 49 } 50 return nil 51 }