forked from pkujhd/goloader
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathinit.1.13.go
48 lines (41 loc) · 1.26 KB
/
init.1.13.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
//go:build go1.13 && !go1.21
// +build go1.13,!go1.21
package goloader
import (
"cmd/objfile/objabi"
"strings"
"unsafe"
)
const (
_InitTaskSuffix = "..inittask"
)
func getInitFuncName(packagename string) string {
return objabi.PathToPrefix(packagename) + _InitTaskSuffix
}
// doInit is defined in package runtime
//
//go:linkname doInit runtime.doInit
func doInit(t unsafe.Pointer) // t should be a *runtime.initTask
type initTask struct {
state uintptr // 0 = uninitialized, 1 = in progress, 2 = done
ndeps uintptr
nfns uintptr
}
func (linker *Linker) doInitialize(codeModule *CodeModule, symbolMap map[string]uintptr) error {
for _, name := range linker.initFuncs {
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)
shouldSkipDedup := false
for _, pkgPath := range linker.options.SkipTypeDeduplicationForPackages {
if strings.HasPrefix(name, pkgPath) {
shouldSkipDedup = true
}
}
if shouldSkipDedup {
x := (*initTask)(unsafe.Pointer(taskPtr))
x.state = 0 // Reset the inittask state in order to rerun the init function for the new version of the package
}
doInit(adduintptr(taskPtr, 0))
}
}
return nil
}