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