github.com/phuslu/log@v1.0.100/runtime_go1.21.go (about) 1 //go:build go1.21 && !go1.22 2 // +build go1.21,!go1.22 3 4 // MIT license, copy and modify from https://github.com/tlog-dev/loc 5 6 //nolint:unused 7 package log 8 9 import ( 10 "unsafe" 11 ) 12 13 // inlinedCall is the encoding of entries in the FUNCDATA_InlTree table. 14 type inlinedCall struct { 15 funcID uint8 // type of the called function 16 _ [3]byte 17 nameOff int32 // offset into pclntab for name of called function 18 parentPc int32 // position of an instruction whose source position is the call site (offset from entry) 19 startLine int32 // line number of start of function (func keyword/TEXT directive) 20 } 21 22 type inlineUnwinder struct { 23 f funcInfo 24 cache unsafe.Pointer 25 inlTree *[1 << 20]inlinedCall 26 } 27 28 type inlineFrame struct { 29 pc uintptr 30 index int32 31 } 32 33 type srcFunc struct { 34 datap unsafe.Pointer 35 nameOff int32 36 startLine int32 37 funcID uint8 38 } 39 40 type _func struct { 41 entryOff uint32 // start pc, as offset from moduledata.text/pcHeader.textStart 42 nameOff int32 // function name, as index into moduledata.funcnametab. 43 44 args int32 // in/out args size 45 deferreturn uint32 // offset of start of a deferreturn call instruction from entry, if any. 46 47 pcsp uint32 48 pcfile uint32 49 pcln uint32 50 npcdata uint32 51 cuOffset uint32 // runtime.cutab offset of this function's CU 52 startLine int32 // line number of start of function (func keyword/TEXT directive) 53 funcID uint8 // set for certain special runtime functions 54 flag uint8 55 _ [1]byte // pad 56 nfuncdata uint8 // must be last, must end on a uint32-aligned boundary 57 } 58 59 func pcFileLineName(pc uintptr) (file string, line int32, name string) { 60 funcInfo := findfunc(pc) 61 if funcInfo._func == nil { 62 return 63 } 64 65 entry := funcInfoEntry(funcInfo) 66 67 if pc > entry { 68 // We store the pc of the start of the instruction following 69 // the instruction in question (the call or the inline mark). 70 // This is done for historical reasons, and to make FuncForPC 71 // work correctly for entries in the result of runtime.Callers. 72 pc-- 73 } 74 75 file, line = funcline1(funcInfo, pc, false) 76 77 // It's important that interpret pc non-strictly as cgoTraceback may 78 // have added bogus PCs with a valid funcInfo but invalid PCDATA. 79 u, uf := newInlineUnwinder(funcInfo, pc, nil) 80 var sf srcFunc 81 if uf.index < 0 { 82 f := (*_func)(funcInfo._func) 83 sf = srcFunc{funcInfo.datap, f.nameOff, f.startLine, f.funcID} 84 } else { 85 t := &u.inlTree[uf.index] 86 sf = srcFunc{u.f.datap, t.nameOff, t.startLine, t.funcID} 87 } 88 name = srcFunc_name(sf) 89 90 return 91 } 92 93 //go:linkname newInlineUnwinder runtime.newInlineUnwinder 94 func newInlineUnwinder(f funcInfo, pc uintptr, cache unsafe.Pointer) (inlineUnwinder, inlineFrame) 95 96 //go:linkname srcFunc_name runtime.srcFunc.name 97 func srcFunc_name(srcFunc) string 98 99 // Fastrandn returns a pseudorandom uint32 in [0,n). 100 // 101 //go:noescape 102 //go:linkname Fastrandn runtime.fastrandn 103 func Fastrandn(x uint32) uint32