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  }