github.com/pkujhd/goloader@v0.0.0-20240411034752-1a28096bd7bd/func.1.20.go (about) 1 //go:build go1.20 && !go1.23 2 // +build go1.20,!go1.23 3 4 package goloader 5 6 import "github.com/pkujhd/goloader/obj" 7 8 // A funcID identifies particular functions that need to be treated 9 // specially by the runtime. 10 // Note that in some situations involving plugins, there may be multiple 11 // copies of a particular special runtime function. 12 // Note: this list must match the list in cmd/internal/objabi/funcid.go. 13 type funcID uint8 14 15 // A FuncFlag holds bits about a function. 16 // This list must match the list in cmd/internal/objabi/funcid.go. 17 type funcFlag uint8 18 19 // Layout of in-memory per-function information prepared by linker 20 // See https://golang.org/s/go12symtab. 21 // Keep in sync with linker (../cmd/link/internal/ld/pcln.go:/pclntab) 22 // and with package debug/gosym and with symtab.go in package runtime. 23 type _func struct { 24 Entryoff uint32 // start pc, as offset from moduledata.text/pcHeader.textStart 25 Nameoff int32 // function name, as index into moduledata.funcnametab. 26 27 Args int32 // in/out args size 28 Deferreturn uint32 // offset of start of a deferreturn call instruction from entry, if any. 29 30 Pcsp uint32 31 Pcfile uint32 32 Pcln uint32 33 Npcdata uint32 34 CuOffset uint32 // runtime.cutab offset of this function's CU 35 StartLine int32 // line number of start of function (func keyword/TEXT directive) 36 FuncID funcID // set for certain special runtime functions 37 Flag funcFlag 38 _ [1]byte // pad 39 Nfuncdata uint8 // must be last, must end on a uint32-aligned boundary 40 41 // The end of the struct is followed immediately by two variable-length 42 // arrays that reference the pcdata and funcdata locations for this 43 // function. 44 45 // pcdata contains the offset into moduledata.pctab for the start of 46 // that index's table. e.g., 47 // &moduledata.pctab[_func.pcdata[_PCDATA_UnsafePoint]] is the start of 48 // the unsafe point table. 49 // 50 // An offset of 0 indicates that there is no table. 51 // 52 // pcdata [npcdata]uint32 53 54 // funcdata contains the offset past moduledata.gofunc which contains a 55 // pointer to that index's funcdata. e.g., 56 // *(moduledata.gofunc + _func.funcdata[_FUNCDATA_ArgsPointerMaps]) is 57 // the argument pointer map. 58 // 59 // An offset of ^uint32(0) indicates that there is no entry. 60 // 61 // funcdata [nfuncdata]uint32 62 } 63 64 func initfunc(symbol *obj.ObjSymbol, nameOff, pcspOff, pcfileOff, pclnOff, cuOff int) _func { 65 fdata := _func{ 66 Entryoff: uint32(0), 67 Nameoff: int32(nameOff), 68 Args: int32(symbol.Func.Args), 69 Deferreturn: uint32(0), 70 Pcsp: uint32(pcspOff), 71 Pcfile: uint32(pcfileOff), 72 Pcln: uint32(pclnOff), 73 Npcdata: uint32(len(symbol.Func.PCData)), 74 CuOffset: uint32(cuOff), 75 StartLine: int32(symbol.Func.StartLine), 76 FuncID: funcID(symbol.Func.FuncID), 77 Flag: funcFlag(symbol.Func.FuncFlag), 78 Nfuncdata: uint8(len(symbol.Func.FuncData)), 79 } 80 return fdata 81 } 82 83 func setfuncentry(f *_func, entry uintptr, text uintptr) { 84 f.Entryoff = uint32(entry - text) 85 } 86 87 func getfuncentry(f *_func, text uintptr) uintptr { 88 return text + uintptr(f.Entryoff) 89 } 90 91 func getfuncname(f *_func, md *moduledata) string { 92 if f.Nameoff <= 0 || f.Nameoff >= int32(len(md.funcnametab)) { 93 return EmptyString 94 } 95 return gostringnocopy(&(md.funcnametab[f.Nameoff])) 96 } 97 98 func getfuncID(f *_func) uint8 { 99 return uint8(f.FuncID) 100 } 101 102 func adaptePCFile(linker *Linker, symbol *obj.ObjSymbol) { 103 }