github.com/nikandfor/loc@v0.5.1/name_file_line_go1.17.go (about) 1 //go:build nikandfor_loc_unsafe && go1.17 && !go1.18 2 // +build nikandfor_loc_unsafe,go1.17,!go1.18 3 4 package loc 5 6 import "unsafe" 7 8 func (l PC) nameFileLine() (name, file string, line int) { 9 funcInfo := findfunc(l) 10 if funcInfo.entry == nil { 11 return 12 } 13 14 if uintptr(l) > *funcInfo.entry { 15 // We store the pc of the start of the instruction following 16 // the instruction in question (the call or the inline mark). 17 // This is done for historical reasons, and to make FuncForPC 18 // work correctly for entries in the result of runtime.Callers. 19 l-- 20 } 21 22 name = funcname(funcInfo) 23 file, line32 := funcline1(funcInfo, l, false) 24 line = int(line32) 25 if inldata := funcdata(funcInfo, _FUNCDATA_InlTree); inldata != nil { 26 ix := pcdatavalue1(funcInfo, _PCDATA_InlTreeIndex, l, nil, false) 27 if ix >= 0 { 28 inltree := (*[1 << 20]inlinedCall)(inldata) 29 // Note: entry is not modified. It always refers to a real frame, not an inlined one. 30 name = funcnameFromNameoff(funcInfo, inltree[ix].func_) 31 // File/line is already correct. 32 // TODO: remove file/line from InlinedCall? 33 } 34 } 35 36 return 37 } 38 39 //go:linkname findfunc runtime.findfunc 40 func findfunc(pc PC) funcInfo 41 42 //go:linkname funcline1 runtime.funcline1 43 func funcline1(f funcInfo, targetpc PC, strict bool) (file string, line int32) 44 45 //go:linkname funcname runtime.funcname 46 func funcname(f funcInfo) string 47 48 //go:linkname funcdata runtime.funcdata 49 func funcdata(f funcInfo, i uint8) unsafe.Pointer 50 51 //go:linkname pcdatavalue runtime.pcdatavalue 52 func pcdatavalue(f funcInfo, table int32, targetpc PC, cache unsafe.Pointer) int32 53 54 //go:linkname pcdatavalue1 runtime.pcdatavalue1 55 func pcdatavalue1(f funcInfo, table int32, targetpc PC, cache unsafe.Pointer, strict bool) int32 56 57 //go:linkname funcnameFromNameoff runtime.funcnameFromNameoff 58 func funcnameFromNameoff(f funcInfo, nameoff int32) string