github.com/pkujhd/goloader@v0.0.0-20240411034752-1a28096bd7bd/obj/readobj.1.16.go (about) 1 //go:build go1.16 && !go1.23 2 // +build go1.16,!go1.23 3 4 package obj 5 6 import ( 7 "cmd/objfile/archive" 8 "cmd/objfile/goobj" 9 "cmd/objfile/objabi" 10 "fmt" 11 "os" 12 "path/filepath" 13 ) 14 15 func (pkg *Pkg) Symbols() error { 16 file, err := os.Open(pkg.File) 17 if err != nil { 18 return err 19 } 20 defer file.Close() 21 a, err := archive.Parse(file, false) 22 if err != nil { 23 return err 24 } 25 for _, e := range a.Entries { 26 switch e.Type { 27 case archive.EntryPkgDef: 28 //nothing todo 29 case archive.EntryGoObj: 30 b := make([]byte, e.Obj.Size) 31 _, err := file.ReadAt(b, e.Obj.Offset) 32 if err != nil { 33 return err 34 } 35 r := goobj.NewReaderFromBytes(b, false) 36 // Name of referenced indexed symbols. 37 nrefName := r.NRefName() 38 refNames := make(map[goobj.SymRef]string, nrefName) 39 for i := 0; i < nrefName; i++ { 40 rn := r.RefName(i) 41 refNames[rn.Sym()] = rn.Name(r) 42 } 43 for i := 0; i < r.NFile(); i++ { 44 pkg.CUFiles = append(pkg.CUFiles, r.File(i)) 45 } 46 pkg.Arch = e.Obj.Arch 47 nsym := r.NSym() + r.NHashed64def() + r.NHasheddef() + r.NNonpkgdef() 48 for i := 0; i < nsym; i++ { 49 pkg.addSym(r, uint32(i), &refNames) 50 } 51 for _, importPkg := range r.Autolib() { 52 path := importPkg.Pkg 53 path = path[:len(path)-len(filepath.Ext(path))] 54 pkg.ImportPkgs = append(pkg.ImportPkgs, path) 55 } 56 default: 57 return fmt.Errorf("Parse open %s: unrecognized archive member %s\n", file.Name(), e.Name) 58 } 59 } 60 return nil 61 } 62 63 func resolveSymRef(s goobj.SymRef, r *goobj.Reader, refNames *map[goobj.SymRef]string) (string, uint32) { 64 i := InvalidIndex 65 switch p := s.PkgIdx; p { 66 case goobj.PkgIdxInvalid: 67 if s.SymIdx != 0 { 68 panic("bad sym ref") 69 } 70 return EmptyString, i 71 case goobj.PkgIdxHashed64: 72 i = s.SymIdx + uint32(r.NSym()) 73 case goobj.PkgIdxHashed: 74 i = s.SymIdx + uint32(r.NSym()+r.NHashed64def()) 75 case goobj.PkgIdxNone: 76 i = s.SymIdx + uint32(r.NSym()+r.NHashed64def()+r.NHasheddef()) 77 case goobj.PkgIdxBuiltin: 78 name, _ := goobj.BuiltinName(int(s.SymIdx)) 79 return name, i 80 case goobj.PkgIdxSelf: 81 i = s.SymIdx 82 default: 83 return (*refNames)[s], i 84 } 85 return r.Sym(i).Name(r), i 86 } 87 88 func (pkg *Pkg) addSym(r *goobj.Reader, index uint32, refNames *map[goobj.SymRef]string) { 89 s := r.Sym(index) 90 symbol := ObjSymbol{Name: s.Name(r), Kind: int(s.Type()), DupOK: s.Dupok(), Size: (int64)(s.Siz()), Func: &FuncInfo{}} 91 if _, ok := pkg.Syms[symbol.Name]; ok { 92 return 93 } 94 if objabi.SymKind(symbol.Kind) == objabi.Sxxx || symbol.Name == EmptyString { 95 return 96 } 97 if symbol.Size > 0 { 98 symbol.Data = r.Data(index) 99 Grow(&symbol.Data, (int)(symbol.Size)) 100 } else { 101 symbol.Data = make([]byte, 0) 102 } 103 104 pkg.Syms[symbol.Name] = &symbol 105 106 auxs := r.Auxs(index) 107 for k := 0; k < len(auxs); k++ { 108 name, index := resolveSymRef(auxs[k].Sym(), r, refNames) 109 switch auxs[k].Type() { 110 case goobj.AuxGotype: 111 symbol.Type = name 112 case goobj.AuxFuncInfo: 113 funcInfo := goobj.FuncInfo{} 114 readFuncInfo(&funcInfo, r.Data(index), symbol.Func) 115 symbol.Func.CUOffset = 0 116 for _, index := range funcInfo.File { 117 symbol.Func.File = append(symbol.Func.File, r.File(int(index))) 118 } 119 for _, inl := range funcInfo.InlTree { 120 funcname, _ := resolveSymRef(inl.Func, r, refNames) 121 funcname = ReplacePkgPath(funcname, pkg.PkgPath) 122 inlNode := InlTreeNode{ 123 Parent: int64(inl.Parent), 124 File: r.File(int(inl.File)), 125 Line: int64(inl.Line), 126 Func: funcname, 127 ParentPC: int64(inl.ParentPC), 128 } 129 symbol.Func.InlTree = append(symbol.Func.InlTree, inlNode) 130 } 131 case goobj.AuxFuncdata: 132 symbol.Func.FuncData = append(symbol.Func.FuncData, name) 133 case goobj.AuxDwarfInfo: 134 case goobj.AuxDwarfLoc: 135 case goobj.AuxDwarfRanges: 136 case goobj.AuxDwarfLines: 137 case goobj.AuxPcsp: 138 symbol.Func.PCSP = r.Data(index) 139 case goobj.AuxPcfile: 140 symbol.Func.PCFile = r.Data(index) 141 case goobj.AuxPcline: 142 symbol.Func.PCLine = r.Data(index) 143 case goobj.AuxPcinline: 144 symbol.Func.PCInline = r.Data(index) 145 case goobj.AuxPcdata: 146 symbol.Func.PCData = append(symbol.Func.PCData, r.Data(index)) 147 } 148 if _, ok := pkg.Syms[name]; !ok && index != InvalidIndex { 149 pkg.addSym(r, index, refNames) 150 } 151 } 152 153 relocs := r.Relocs(index) 154 for k := 0; k < len(relocs); k++ { 155 symbol.Reloc = append(symbol.Reloc, Reloc{}) 156 symbol.Reloc[k].Add = int(relocs[k].Add()) 157 symbol.Reloc[k].Offset = int(relocs[k].Off()) 158 symbol.Reloc[k].Size = int(relocs[k].Siz()) 159 symbol.Reloc[k].Type = int(relocs[k].Type()) 160 name, index := resolveSymRef(relocs[k].Sym(), r, refNames) 161 symbol.Reloc[k].SymName = name 162 if _, ok := pkg.Syms[name]; !ok && index != InvalidIndex { 163 pkg.addSym(r, index, refNames) 164 } 165 } 166 }