github.com/Rookout/GoSDK@v0.1.48/pkg/services/instrumentation/module/module1.21.go (about) 1 //go:build go1.21 && !go1.22 2 // +build go1.21,!go1.22 3 4 package module 5 6 import ( 7 "runtime" 8 "unsafe" 9 ) 10 11 12 13 type funcFlag uint8 14 15 type functab struct { 16 entryoff uint32 17 funcoff uint32 18 } 19 20 type textsect struct { 21 vaddr uintptr 22 end uintptr 23 baseaddr uintptr 24 } 25 26 type nih struct{} 27 28 29 type NotInHeap struct{ _ nih } 30 31 type _func struct { 32 NotInHeap 33 34 entryoff uint32 35 nameoff int32 36 37 args int32 38 deferreturn uint32 39 40 pcsp uint32 41 pcfile uint32 42 pcln uint32 43 npcdata uint32 44 cuOffset uint32 45 startLine int32 46 funcID FuncID 47 flag funcFlag 48 _ [1]byte 49 nfuncdata uint8 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 } 73 74 type pcHeader struct { 75 magic uint32 76 pad1, pad2 uint8 77 minLC uint8 78 ptrSize uint8 79 nfunc int 80 nfiles uint 81 textStart uintptr 82 funcnameOffset uintptr 83 cuOffset uintptr 84 filetabOffset uintptr 85 pctabOffset uintptr 86 pclnOffset uintptr 87 } 88 89 type initTask struct { 90 state uint32 91 nfns uint32 92 93 } 94 95 type moduledata struct { 96 NotInHeap 97 98 pcHeader *pcHeader 99 funcnametab []byte 100 cutab []uint32 101 filetab []byte 102 pctab []byte 103 pclntable []byte 104 ftab []functab 105 findfunctab uintptr 106 minpc, maxpc uintptr 107 108 text, etext uintptr 109 noptrdata, enoptrdata uintptr 110 data, edata uintptr 111 bss, ebss uintptr 112 noptrbss, enoptrbss uintptr 113 covctrs, ecovctrs uintptr 114 end, gcdata, gcbss uintptr 115 types, etypes uintptr 116 rodata uintptr 117 gofunc uintptr // go.func.* 118 119 textsectmap []textsect 120 typelinks []int32 121 itablinks []*itab 122 123 ptab []ptabEntry 124 125 pluginpath string 126 pkghashes []modulehash 127 128 129 130 inittasks []*initTask 131 132 modulename string 133 modulehashes []modulehash 134 135 hasmain uint8 136 137 gcdatamask, gcbssmask bitvector 138 139 typemap map[TypeOff]*_type 140 141 bad bool 142 143 next *moduledata 144 } 145 146 func getPCTab(m *moduledata) []byte { 147 return m.pctab 148 } 149 150 func (f *FuncInfo) getEntry() uintptr { 151 entry, _ := f.datap.textAddr(f.entryoff) 152 return entry 153 } 154 155 156 func findFuncOffsetInModule(pc uintptr, datap *moduledata) (uintptr, bool) { 157 if datap == nil { 158 return 0, false 159 } 160 const nsub = uintptr(len(findfuncbucket{}.subbuckets)) 161 162 pcOff, ok := datap.textOff(pc) 163 if !ok { 164 return 0, false 165 } 166 167 x := uintptr(pcOff) + datap.text - datap.minpc 168 b := x / pcbucketsize 169 i := x % pcbucketsize / (pcbucketsize / nsub) 170 171 ffb := (*findfuncbucket)(add(unsafe.Pointer(datap.findfunctab), b*unsafe.Sizeof(findfuncbucket{}))) 172 idx := ffb.idx + uint32(ffb.subbuckets[i]) 173 174 175 for datap.ftab[idx+1].entryoff <= pcOff { 176 idx++ 177 } 178 179 funcoff := uintptr(datap.ftab[idx].funcoff) 180 if funcoff == ^uintptr(0) { 181 182 183 184 185 return 0, false 186 } 187 188 return funcoff, true 189 } 190 191 192 func (md *moduledata) textOff(pc uintptr) (uint32, bool) { 193 res := uint32(pc - md.text) 194 if len(md.textsectmap) > 1 { 195 for i, sect := range md.textsectmap { 196 if sect.baseaddr > pc { 197 198 return 0, false 199 } 200 end := sect.baseaddr + (sect.end - sect.vaddr) 201 202 if i == len(md.textsectmap) { 203 end++ 204 } 205 if pc < end { 206 res = uint32(pc - sect.baseaddr + sect.vaddr) 207 break 208 } 209 } 210 } 211 return res, true 212 } 213 214 215 func (md *moduledata) textAddr(off32 uint32) (uintptr, bool) { 216 off := uintptr(off32) 217 res := md.text + off 218 if len(md.textsectmap) > 1 { 219 for i, sect := range md.textsectmap { 220 221 if off >= sect.vaddr && off < sect.end || (i == len(md.textsectmap)-1 && off == sect.end) { 222 res = sect.baseaddr + off - sect.vaddr 223 break 224 } 225 } 226 if res > md.etext && runtime.GOARCH != "wasm" { 227 println("runtime: textAddr", hex(res), "out of range", hex(md.text), "-", hex(md.etext)) 228 return 0, false 229 } 230 } 231 return res, true 232 } 233 234 type hex uint64 235 236 func (md *moduledata) GetTypeMap() map[TypeOff]uintptr { 237 typemap := make(map[TypeOff]uintptr) 238 for k, v := range md.typemap { 239 typemap[k] = uintptr(unsafe.Pointer(v)) 240 } 241 return typemap 242 }