Skip to content

Commit

Permalink
fix #35, add support for package init
Browse files Browse the repository at this point in the history
  • Loading branch information
pkujhd committed Jun 22, 2021
1 parent 1cbed3b commit a79a36e
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 1 deletion.
14 changes: 13 additions & 1 deletion dymcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ type Linker struct {
pclntable []byte
pcfunc []findfuncbucket
_func []_func
initFuncs []string
Arch string
}

Expand Down Expand Up @@ -133,6 +134,12 @@ func (linker *Linker) addSymbols() error {
return err
}
}
if objSym.Kind == SNOPTRDATA {
_, err := linker.addSymbol(objSym.Name)
if err != nil {
return err
}
}
}
return nil
}
Expand Down Expand Up @@ -319,6 +326,9 @@ func (linker *Linker) addSymbolMap(symPtr map[string]uintptr, codeModule *CodeMo
symbolMap[name] = uintptr(linker.symMap[name].Offset + segment.dataBase)
} else {
symbolMap[name] = symPtr[name]
if isMainInitFunc(name) {
symbolMap[name] = uintptr(linker.symMap[name].Offset + segment.dataBase)
}
}
}
}
Expand Down Expand Up @@ -613,7 +623,9 @@ func Load(linker *Linker, symPtr map[string]uintptr) (codeModule *CodeModule, er
if symbolMap, err = linker.addSymbolMap(symPtr, codeModule); err == nil {
if err = linker.relocate(codeModule, symbolMap); err == nil {
if err = linker.buildModule(codeModule, symbolMap); err == nil {
return codeModule, err
if err = linker.doInitialize(codeModule, symbolMap); err == nil {
return codeModule, err
}
}
}
}
Expand Down
37 changes: 37 additions & 0 deletions init.1.13.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// +build go1.12
// +build !go1.18

package goloader

import (
"unsafe"
)

const (
_MainInitTask = "main..inittask"
_InitTaskSuffix = "..inittask"
)

func getInitFuncName(packagename string) string {
return packagename + _InitTaskSuffix
}

func isMainInitFunc(name string) bool {
if name == _MainInitTask {
return true
}
return false
}

// doInit is defined in package runtime
//go:linkname doInit runtime.doInit
func doInit(t unsafe.Pointer) // t should be a *runtime.initTask

func (linker *Linker) doInitialize(codeModule *CodeModule, symbolMap map[string]uintptr) error {
for _, name := range linker.initFuncs {
if funcPtr, ok := symbolMap[name]; ok {
doInit(adduintptr(funcPtr, 0))
}
}
return nil
}
35 changes: 35 additions & 0 deletions init.1.8.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// +build go1.8
// +build !go1.13

package goloader

import (
"unsafe"
)

const (
_MainInitTask = "main.init"
_InitTaskSuffix = ".init"
)

func getInitFuncName(packagename string) string {
return packagename + _InitTaskSuffix
}

func isMainInitFunc(name string) bool {
if name == _MainInitTask {
return true
}
return false
}

func (linker *Linker) doInitialize(codeModule *CodeModule, symbolMap map[string]uintptr) error {
for _, name := range linker.initFuncs {
if funcPtr, ok := codeModule.Syms[name]; ok {
funcPtrContainer := (uintptr)(unsafe.Pointer(&funcPtr))
runFunc := *(*func())(unsafe.Pointer(&funcPtrContainer))
runFunc()
}
}
return nil
}
1 change: 1 addition & 0 deletions readobj.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func readObj(pkg *Pkg, linker *Linker) error {
for _, sym := range pkg.Syms {
linker.objsymbolMap[sym.Name] = sym
}
linker.initFuncs = append(linker.initFuncs, getInitFuncName(pkg.PkgPath))
return nil
}

Expand Down

0 comments on commit a79a36e

Please sign in to comment.