github.com/pkujhd/goloader@v0.0.0-20240411034752-1a28096bd7bd/inlinetree.go (about) 1 package goloader 2 3 import ( 4 "unsafe" 5 6 "github.com/pkujhd/goloader/obj" 7 "github.com/pkujhd/goloader/objabi/dataindex" 8 ) 9 10 func (linker *Linker) addInlineTree(_func *_func, symbol *obj.ObjSymbol) (err error) { 11 funcname := symbol.Name 12 Func := symbol.Func 13 sym := linker.SymMap[funcname] 14 if Func != nil && len(Func.InlTree) != 0 { 15 for _func.Npcdata <= dataindex.PCDATA_InlTreeIndex { 16 sym.Func.PCData = append(sym.Func.PCData, uint32(0)) 17 _func.Npcdata++ 18 } 19 sym.Func.PCData[dataindex.PCDATA_InlTreeIndex] = uint32(len(linker.Pclntable)) 20 21 for _, reloc := range symbol.Reloc { 22 if reloc.Epilogue.Size > 0 { 23 patchPCValues(linker, &symbol.Func.PCInline, reloc) 24 } 25 } 26 27 linker.Pclntable = append(linker.Pclntable, symbol.Func.PCInline...) 28 for _, inl := range symbol.Func.InlTree { 29 if _, ok := linker.NameMap[inl.Func]; !ok { 30 linker.NameMap[inl.Func] = len(linker.Pclntable) 31 linker.Pclntable = append(linker.Pclntable, []byte(inl.Func)...) 32 linker.Pclntable = append(linker.Pclntable, ZeroByte) 33 } 34 } 35 36 bytes := make([]byte, len(Func.InlTree)*obj.InlinedCallSize) 37 for k, inl := range Func.InlTree { 38 funcID := uint8(0) 39 if _, ok := linker.ObjSymbolMap[inl.Func]; ok { 40 funcID = linker.ObjSymbolMap[inl.Func].Func.FuncID 41 } 42 inlinedcall := obj.InitInlinedCall(inl, funcID, linker.NameMap, linker.Filetab) 43 copy2Slice(bytes[k*obj.InlinedCallSize:], uintptr(unsafe.Pointer(&inlinedcall)), obj.InlinedCallSize) 44 } 45 offset := len(linker.Noptrdata) 46 linker.Noptrdata = append(linker.Noptrdata, bytes...) 47 bytearrayAlign(&linker.Noptrdata, PtrSize) 48 for _func.Nfuncdata <= dataindex.FUNCDATA_InlTree { 49 sym.Func.FuncData = append(sym.Func.FuncData, uintptr(0)) 50 _func.Nfuncdata++ 51 } 52 sym.Func.FuncData[dataindex.FUNCDATA_InlTree] = (uintptr)(offset) 53 } 54 return err 55 }