github.com/pkujhd/goloader@v0.0.0-20240411034752-1a28096bd7bd/readobj.go (about) 1 package goloader 2 3 import ( 4 "fmt" 5 6 "github.com/pkujhd/goloader/obj" 7 ) 8 9 func Parse(file, pkgpath string) ([]string, error) { 10 pkg := obj.Pkg{Syms: make(map[string]*obj.ObjSymbol, 0), File: file, PkgPath: pkgpath} 11 if err := pkg.Symbols(); err != nil { 12 return nil, err 13 } 14 symbols := make([]string, 0) 15 for _, sym := range pkg.Syms { 16 symbols = append(symbols, sym.Name) 17 } 18 return symbols, nil 19 } 20 21 func (linker *Linker) readObj(file, pkgpath string) error { 22 pkg := obj.Pkg{Syms: make(map[string]*obj.ObjSymbol, 0), File: file, PkgPath: pkgpath} 23 if pkg.PkgPath == EmptyString { 24 pkg.PkgPath = DefaultPkgPath 25 } 26 if err := pkg.Symbols(); err != nil { 27 return fmt.Errorf("read error: %v", err) 28 } 29 if linker.Arch != nil && linker.Arch.Name != pkg.Arch { 30 return fmt.Errorf("read obj error: Arch %s != Arch %s", linker.Arch.Name, pkg.Arch) 31 } else { 32 linker.Arch = getArch(pkg.Arch) 33 } 34 35 for _, sym := range pkg.Syms { 36 for index, loc := range sym.Reloc { 37 sym.Reloc[index].SymName = obj.ReplacePkgPath(loc.SymName, pkg.PkgPath) 38 } 39 if sym.Type != EmptyString { 40 sym.Type = obj.ReplacePkgPath(sym.Type, pkg.PkgPath) 41 } 42 if sym.Func != nil { 43 for index, FuncData := range sym.Func.FuncData { 44 sym.Func.FuncData[index] = obj.ReplacePkgPath(FuncData, pkg.PkgPath) 45 } 46 sym.Func.CUOffset += linker.CUOffset 47 } 48 sym.Name = obj.ReplacePkgPath(sym.Name, pkg.PkgPath) 49 linker.ObjSymbolMap[sym.Name] = sym 50 } 51 linker.addFiles(pkg.CUFiles) 52 linker.Packages = append(linker.Packages, &pkg) 53 return nil 54 } 55 56 func ReadObj(file, pkgpath string) (*Linker, error) { 57 linker := initLinker() 58 if err := linker.readObj(file, pkgpath); err != nil { 59 return nil, err 60 } 61 linker.initPcHeader() 62 if err := linker.addSymbols(); err != nil { 63 return nil, err 64 } 65 return linker, nil 66 } 67 68 func ReadObjs(files []string, pkgPaths []string) (*Linker, error) { 69 linker := initLinker() 70 for i, file := range files { 71 if err := linker.readObj(file, pkgPaths[i]); err != nil { 72 return nil, err 73 } 74 } 75 linker.initPcHeader() 76 if err := linker.addSymbols(); err != nil { 77 return nil, err 78 } 79 return linker, nil 80 } 81 82 func (linker *Linker) ReadDependPkg(file, pkgPath string, symbolNames []string, symPtr map[string]uintptr) error { 83 if linker.AdaptedOffset { 84 return fmt.Errorf("already adapted symbol offset, don't add new symbols") 85 } 86 //only add unresolved symbol in ObjSymbolMap. use temporary map store read symbols 87 objSymbolMap := linker.ObjSymbolMap 88 linker.ObjSymbolMap = make(map[string]*obj.ObjSymbol) 89 if err := linker.readObj(file, pkgPath); err != nil { 90 return err 91 } 92 initFuncName := getInitFuncName(pkgPath) 93 if _, ok := linker.ObjSymbolMap[initFuncName]; ok { 94 if _, err := linker.addSymbol(initFuncName, nil); err != nil { 95 return err 96 } 97 } 98 for _, name := range symbolNames { 99 if _, ok := linker.ObjSymbolMap[name]; ok { 100 delete(linker.SymMap, name) 101 _, err := linker.addSymbol(name, symPtr) 102 if err != nil { 103 return err 104 } 105 } 106 } 107 for name, sym := range linker.ObjSymbolMap { 108 if _, ok := linker.SymMap[name]; ok { 109 objSymbolMap[name] = sym 110 } 111 } 112 linker.ObjSymbolMap = objSymbolMap 113 return nil 114 }