funcdata_go118.go (6037B)
1 // +build go1.18,!go1.20 2 3 /* 4 * Copyright 2021 ByteDance Inc. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package loader 20 21 import ( 22 `unsafe` 23 24 `github.com/bytedance/sonic/internal/rt` 25 ) 26 27 // A FuncFlag holds bits about a function. 28 // This list must match the list in cmd/internal/objabi/funcid.go. 29 type funcFlag uint8 30 31 type _Func struct { 32 entryOff uint32 // start pc 33 nameoff int32 // function name 34 args int32 // in/out args size 35 deferreturn uint32 // offset of start of a deferreturn call instruction from entry, if any. 36 pcsp uint32 37 pcfile uint32 38 pcln uint32 39 npcdata uint32 40 cuOffset uint32 // runtime.cutab offset of this function's CU 41 funcID uint8 // set for certain special runtime functions 42 flag funcFlag 43 _ [1]byte // pad 44 nfuncdata uint8 // must be last 45 argptrs uint32 46 localptrs uint32 47 } 48 49 type _FuncTab struct { 50 entry uint32 51 funcoff uint32 52 } 53 54 type _PCHeader struct { 55 magic uint32 // 0xFFFFFFF0 56 pad1, pad2 uint8 // 0,0 57 minLC uint8 // min instruction size 58 ptrSize uint8 // size of a ptr in bytes 59 nfunc int // number of functions in the module 60 nfiles uint // number of entries in the file tab 61 textStart uintptr // base for function entry PC offsets in this module, equal to moduledata.text 62 funcnameOffset uintptr // offset to the funcnametab variable from pcHeader 63 cuOffset uintptr // offset to the cutab variable from pcHeader 64 filetabOffset uintptr // offset to the filetab variable from pcHeader 65 pctabOffset uintptr // offset to the pctab variable from pcHeader 66 pclnOffset uintptr // offset to the pclntab variable from pcHeader 67 } 68 69 type _BitVector struct { 70 n int32 // # of bits 71 bytedata *uint8 72 } 73 74 type _PtabEntry struct { 75 name int32 76 typ int32 77 } 78 79 type _TextSection struct { 80 vaddr uintptr // prelinked section vaddr 81 length uintptr // section length 82 baseaddr uintptr // relocated section address 83 } 84 85 type _ModuleData struct { 86 pcHeader *_PCHeader 87 funcnametab []byte 88 cutab []uint32 89 filetab []byte 90 pctab []byte 91 pclntable []byte 92 ftab []_FuncTab 93 findfunctab *_FindFuncBucket 94 minpc, maxpc uintptr 95 text, etext uintptr 96 noptrdata, enoptrdata uintptr 97 data, edata uintptr 98 bss, ebss uintptr 99 noptrbss, enoptrbss uintptr 100 end, gcdata, gcbss uintptr 101 types, etypes uintptr 102 rodata uintptr 103 gofunc uintptr 104 textsectmap []_TextSection 105 typelinks []int32 106 itablinks []unsafe.Pointer 107 ptab []_PtabEntry 108 pluginpath string 109 pkghashes []struct{} 110 modulename string 111 modulehashes []struct{} 112 hasmain uint8 113 gcdatamask, gcbssmask _BitVector 114 typemap map[int32]unsafe.Pointer 115 bad bool 116 next *_ModuleData 117 } 118 119 120 type _FindFuncBucket struct { 121 idx uint32 122 subbuckets [16]byte 123 } 124 125 126 127 func makePCtab(fp int) []byte { 128 return append([]byte{0}, encodeVariant((fp + 1) << 1)...) 129 } 130 131 func registerFunction(name string, pc uintptr, textSize uintptr, fp int, args int, size uintptr, argPtrs []bool, localPtrs []bool) { 132 mod := new(_ModuleData) 133 134 minpc := pc 135 maxpc := pc + size 136 137 findFuncTab := make([]_FindFuncBucket, textSize/4096 + 1) 138 139 modHeader := &_PCHeader { 140 magic : 0xfffffff0, 141 minLC : 1, 142 nfunc : 1, 143 ptrSize : 4 << (^uintptr(0) >> 63), 144 textStart: minpc, 145 } 146 147 // cache arg and local stackmap 148 argptrs, localptrs := cacheStackmap(argPtrs, localPtrs, mod) 149 150 base := argptrs 151 if argptrs > localptrs { 152 base = localptrs 153 } 154 155 /* function entry */ 156 lnt := []_Func {{ 157 entryOff : 0, 158 nameoff : 1, 159 args : int32(args), 160 pcsp : 1, 161 nfuncdata : 2, 162 argptrs: uint32(argptrs - base), 163 localptrs: uint32(localptrs - base), 164 }} 165 nlnt := len(lnt)*int(unsafe.Sizeof(_Func{})) 166 plnt := unsafe.Pointer(&lnt[0]) 167 168 /* function table */ 169 ftab := []_FuncTab { 170 {entry : 0, funcoff : 16}, 171 {entry : uint32(size)}, 172 } 173 nftab := len(ftab)*int(unsafe.Sizeof(_FuncTab{})) 174 pftab := unsafe.Pointer(&ftab[0]) 175 176 pclntab := make([]byte, 0, nftab + nlnt) 177 pclntab = append(pclntab, rt.BytesFrom(pftab, nftab, nftab)...) 178 pclntab = append(pclntab, rt.BytesFrom(plnt, nlnt, nlnt)...) 179 180 /* module data */ 181 *mod = _ModuleData { 182 pcHeader : modHeader, 183 funcnametab : append(append([]byte{0}, name...), 0), 184 pctab : append(makePCtab(fp), encodeVariant(int(size))...), 185 pclntable : pclntab, 186 ftab : ftab, 187 text : minpc, 188 etext : pc + textSize, 189 findfunctab : &findFuncTab[0], 190 minpc : minpc, 191 maxpc : maxpc, 192 modulename : name, 193 gcdata: uintptr(unsafe.Pointer(&emptyByte)), 194 gcbss: uintptr(unsafe.Pointer(&emptyByte)), 195 gofunc: base, 196 } 197 198 /* verify and register the new module */ 199 moduledataverify1(mod) 200 registerModule(mod) 201 }