From e6325bec231abd6fe74bfc7567a0f48c902fedb1 Mon Sep 17 00:00:00 2001 From: pkujhd Date: Sat, 27 Jul 2024 11:42:36 +0800 Subject: [PATCH] after golang 1.21, init task need execute sequence --- init.1.21.go | 77 ++++++++++++++++++++++++++++++++++++++++++---------- ld.go | 3 +- readobj.go | 2 +- 3 files changed, 65 insertions(+), 17 deletions(-) diff --git a/init.1.21.go b/init.1.21.go index 9b710e50..16f35717 100644 --- a/init.1.21.go +++ b/init.1.21.go @@ -7,7 +7,6 @@ import ( "unsafe" "github.com/pkujhd/goloader/obj" - "github.com/pkujhd/goloader/objabi/reloctype" ) type initTask struct { @@ -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 diff --git a/ld.go b/ld.go index 22387b43..2e161883 100644 --- a/ld.go +++ b/ld.go @@ -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 @@ -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, } diff --git a/readobj.go b/readobj.go index 3e8e9d29..7bcce222 100644 --- a/readobj.go +++ b/readobj.go @@ -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 }