-
Notifications
You must be signed in to change notification settings - Fork 58
/
init.1.21.go
98 lines (85 loc) · 2.22 KB
/
init.1.21.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//go:build go1.21 && !go1.24
// +build go1.21,!go1.24
package goloader
import (
"unsafe"
"github.com/pkujhd/goloader/obj"
)
type initTask struct {
state uint32 // 0 = uninitialized, 1 = in progress, 2 = done
nfns uint32
// followed by nfns pcs, uintptr sized, one per init function to run
}
const (
_InitTaskSuffix = "..inittask"
)
func getInitFuncName(packagename string) string {
return obj.PathToPrefix(packagename) + _InitTaskSuffix
}
//go:linkname doInit1 runtime.doInit1
func doInit1(t unsafe.Pointer) // t should be a *runtime.initTask
func doInit(ptr uintptr) {
p := adduintptr(ptr, 0)
task := *(*initTask)(p)
if task.nfns != 0 {
doInit1(p)
}
}
func (linker *Linker) isDependent(pkgPath string) bool {
for _, pkg := range linker.Packages {
for _, imported := range pkg.ImportPkgs {
if imported == pkgPath {
return false
}
}
}
return true
}
func (linker *Linker) getEnteyPackage() *obj.Pkg {
for _, pkg := range linker.Packages {
if linker.isDependent(pkg.PkgPath) {
return pkg
}
}
return nil
}
func (linker *Linker) importedPackages() []string {
if len(linker.Packages) == 0 {
return nil
}
mainPkg := linker.getEnteyPackage()
if mainPkg == nil {
return nil
}
iPackages := make([]string, 0)
seen := make(map[string]bool)
linker.sortedImportedPackages(mainPkg.PkgPath, &iPackages, seen)
return iPackages
}
func (linker *Linker) sortedImportedPackages(targetPkg string, iPackages *[]string, seen map[string]bool) {
if _, ok := seen[targetPkg]; !ok {
seen[targetPkg] = true
if _, ok := linker.Packages[targetPkg]; ok {
for _, imported := range linker.Packages[targetPkg].ImportPkgs {
linker.sortedImportedPackages(imported, iPackages, seen)
if _, ok := linker.Packages[imported]; ok {
nImporteds := linker.Packages[imported].ImportPkgs
for _, nImported := range nImporteds {
if _, ok := seen[nImported]; !ok {
*iPackages = append(*iPackages, nImported)
}
}
}
}
}
*iPackages = append(*iPackages, targetPkg)
}
}
func (linker *Linker) doInitialize(symPtr, symbolMap map[string]uintptr) error {
for _, pkgPath := range linker.importedPackages() {
if ptr, ok := symbolMap[getInitFuncName(pkgPath)]; ok {
doInit(ptr)
}
}
return nil
}