Skip to content

Commit

Permalink
after golang 1.21, init task need execute sequence
Browse files Browse the repository at this point in the history
  • Loading branch information
pkujhd committed Jul 27, 2024
1 parent 66ff56c commit e6325be
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 17 deletions.
77 changes: 62 additions & 15 deletions init.1.21.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"unsafe"

"github.com/pkujhd/goloader/obj"
"github.com/pkujhd/goloader/objabi/reloctype"
)

type initTask struct {
Expand All @@ -27,24 +26,72 @@ func getInitFuncName(packagename string) string {
//go:linkname doInit1 runtime.doInit1
func doInit1(t unsafe.Pointer) // t should be a *runtime.initTask

func (linker *Linker) doInitialize(symPtr, symbolMap map[string]uintptr) error {
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 {
name := getInitFuncName(pkg.PkgPath)
if ptr, ok := symbolMap[name]; ok {
for _, loc := range linker.SymMap[name].Reloc {
if loc.Type == reloctype.R_INITORDER {
if locPtr, ok := symPtr[loc.SymName]; ok {
doInit1(adduintptr(locPtr, 0))
} else if locPtr, ok := symbolMap[loc.SymName]; ok {
doInit1(adduintptr(locPtr, 0))
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)
}
}
}
}
task := *(*initTask)(adduintptr(ptr, 0))
if task.nfns == 0 {
continue
}
doInit1(adduintptr(ptr, 0))
}
*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
Expand Down
3 changes: 2 additions & 1 deletion ld.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ type Linker struct {
Filetab []uint32
Pclntable []byte
Funcs []*_func
Packages []*obj.Pkg
Packages map[string]*obj.Pkg
Arch *sys.Arch
CUOffset int32
AdaptedOffset bool
Expand All @@ -93,6 +93,7 @@ func initLinker() *Linker {
ObjSymbolMap: make(map[string]*obj.ObjSymbol),
NameMap: make(map[string]int),
StringMap: make(map[string]*string),
Packages: make(map[string]*obj.Pkg),
CUOffset: 0,
AdaptedOffset: false,
}
Expand Down
2 changes: 1 addition & 1 deletion readobj.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (linker *Linker) readObj(file, pkgpath string) error {
linker.ObjSymbolMap[sym.Name] = sym
}
linker.addFiles(pkg.CUFiles)
linker.Packages = append(linker.Packages, &pkg)
linker.Packages[pkg.PkgPath] = &pkg
return nil
}

Expand Down

0 comments on commit e6325be

Please sign in to comment.