Black Lives Matter. Support the Equal Justice Initiative.

Source file src/runtime/symtab.go

Documentation: runtime

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package runtime
     6  
     7  import (
     8  	"runtime/internal/atomic"
     9  	"runtime/internal/sys"
    10  	"unsafe"
    11  )
    12  
    13  // Frames may be used to get function/file/line information for a
    14  // slice of PC values returned by Callers.
    15  type Frames struct {
    16  	// callers is a slice of PCs that have not yet been expanded to frames.
    17  	callers []uintptr
    18  
    19  	// frames is a slice of Frames that have yet to be returned.
    20  	frames     []Frame
    21  	frameStore [2]Frame
    22  }
    23  
    24  // Frame is the information returned by Frames for each call frame.
    25  type Frame struct {
    26  	// PC is the program counter for the location in this frame.
    27  	// For a frame that calls another frame, this will be the
    28  	// program counter of a call instruction. Because of inlining,
    29  	// multiple frames may have the same PC value, but different
    30  	// symbolic information.
    31  	PC uintptr
    32  
    33  	// Func is the Func value of this call frame. This may be nil
    34  	// for non-Go code or fully inlined functions.
    35  	Func *Func
    36  
    37  	// Function is the package path-qualified function name of
    38  	// this call frame. If non-empty, this string uniquely
    39  	// identifies a single function in the program.
    40  	// This may be the empty string if not known.
    41  	// If Func is not nil then Function == Func.Name().
    42  	Function string
    43  
    44  	// File and Line are the file name and line number of the
    45  	// location in this frame. For non-leaf frames, this will be
    46  	// the location of a call. These may be the empty string and
    47  	// zero, respectively, if not known.
    48  	File string
    49  	Line int
    50  
    51  	// Entry point program counter for the function; may be zero
    52  	// if not known. If Func is not nil then Entry ==
    53  	// Func.Entry().
    54  	Entry uintptr
    55  
    56  	// The runtime's internal view of the function. This field
    57  	// is set (funcInfo.valid() returns true) only for Go functions,
    58  	// not for C functions.
    59  	funcInfo funcInfo
    60  }
    61  
    62  // CallersFrames takes a slice of PC values returned by Callers and
    63  // prepares to return function/file/line information.
    64  // Do not change the slice until you are done with the Frames.
    65  func CallersFrames(callers []uintptr) *Frames {
    66  	f := &Frames{callers: callers}
    67  	f.frames = f.frameStore[:0]
    68  	return f
    69  }
    70  
    71  // Next returns frame information for the next caller.
    72  // If more is false, there are no more callers (the Frame value is valid).
    73  func (ci *Frames) Next() (frame Frame, more bool) {
    74  	for len(ci.frames) < 2 {
    75  		// Find the next frame.
    76  		// We need to look for 2 frames so we know what
    77  		// to return for the "more" result.
    78  		if len(ci.callers) == 0 {
    79  			break
    80  		}
    81  		pc := ci.callers[0]
    82  		ci.callers = ci.callers[1:]
    83  		funcInfo := findfunc(pc)
    84  		if !funcInfo.valid() {
    85  			if cgoSymbolizer != nil {
    86  				// Pre-expand cgo frames. We could do this
    87  				// incrementally, too, but there's no way to
    88  				// avoid allocation in this case anyway.
    89  				ci.frames = append(ci.frames, expandCgoFrames(pc)...)
    90  			}
    91  			continue
    92  		}
    93  		f := funcInfo._Func()
    94  		entry := f.Entry()
    95  		if pc > entry {
    96  			// We store the pc of the start of the instruction following
    97  			// the instruction in question (the call or the inline mark).
    98  			// This is done for historical reasons, and to make FuncForPC
    99  			// work correctly for entries in the result of runtime.Callers.
   100  			pc--
   101  		}
   102  		name := funcname(funcInfo)
   103  		if inldata := funcdata(funcInfo, _FUNCDATA_InlTree); inldata != nil {
   104  			inltree := (*[1 << 20]inlinedCall)(inldata)
   105  			// Non-strict as cgoTraceback may have added bogus PCs
   106  			// with a valid funcInfo but invalid PCDATA.
   107  			ix := pcdatavalue1(funcInfo, _PCDATA_InlTreeIndex, pc, nil, false)
   108  			if ix >= 0 {
   109  				// Note: entry is not modified. It always refers to a real frame, not an inlined one.
   110  				f = nil
   111  				name = funcnameFromNameoff(funcInfo, inltree[ix].func_)
   112  				// File/line is already correct.
   113  				// TODO: remove file/line from InlinedCall?
   114  			}
   115  		}
   116  		ci.frames = append(ci.frames, Frame{
   117  			PC:       pc,
   118  			Func:     f,
   119  			Function: name,
   120  			Entry:    entry,
   121  			funcInfo: funcInfo,
   122  			// Note: File,Line set below
   123  		})
   124  	}
   125  
   126  	// Pop one frame from the frame list. Keep the rest.
   127  	// Avoid allocation in the common case, which is 1 or 2 frames.
   128  	switch len(ci.frames) {
   129  	case 0: // In the rare case when there are no frames at all, we return Frame{}.
   130  		return
   131  	case 1:
   132  		frame = ci.frames[0]
   133  		ci.frames = ci.frameStore[:0]
   134  	case 2:
   135  		frame = ci.frames[0]
   136  		ci.frameStore[0] = ci.frames[1]
   137  		ci.frames = ci.frameStore[:1]
   138  	default:
   139  		frame = ci.frames[0]
   140  		ci.frames = ci.frames[1:]
   141  	}
   142  	more = len(ci.frames) > 0
   143  	if frame.funcInfo.valid() {
   144  		// Compute file/line just before we need to return it,
   145  		// as it can be expensive. This avoids computing file/line
   146  		// for the Frame we find but don't return. See issue 32093.
   147  		file, line := funcline1(frame.funcInfo, frame.PC, false)
   148  		frame.File, frame.Line = file, int(line)
   149  	}
   150  	return
   151  }
   152  
   153  // runtime_expandFinalInlineFrame expands the final pc in stk to include all
   154  // "callers" if pc is inline.
   155  //
   156  //go:linkname runtime_expandFinalInlineFrame runtime/pprof.runtime_expandFinalInlineFrame
   157  func runtime_expandFinalInlineFrame(stk []uintptr) []uintptr {
   158  	if len(stk) == 0 {
   159  		return stk
   160  	}
   161  	pc := stk[len(stk)-1]
   162  	tracepc := pc - 1
   163  
   164  	f := findfunc(tracepc)
   165  	if !f.valid() {
   166  		// Not a Go function.
   167  		return stk
   168  	}
   169  
   170  	inldata := funcdata(f, _FUNCDATA_InlTree)
   171  	if inldata == nil {
   172  		// Nothing inline in f.
   173  		return stk
   174  	}
   175  
   176  	// Treat the previous func as normal. We haven't actually checked, but
   177  	// since this pc was included in the stack, we know it shouldn't be
   178  	// elided.
   179  	lastFuncID := funcID_normal
   180  
   181  	// Remove pc from stk; we'll re-add it below.
   182  	stk = stk[:len(stk)-1]
   183  
   184  	// See inline expansion in gentraceback.
   185  	var cache pcvalueCache
   186  	inltree := (*[1 << 20]inlinedCall)(inldata)
   187  	for {
   188  		ix := pcdatavalue(f, _PCDATA_InlTreeIndex, tracepc, &cache)
   189  		if ix < 0 {
   190  			break
   191  		}
   192  		if inltree[ix].funcID == funcID_wrapper && elideWrapperCalling(lastFuncID) {
   193  			// ignore wrappers
   194  		} else {
   195  			stk = append(stk, pc)
   196  		}
   197  		lastFuncID = inltree[ix].funcID
   198  		// Back up to an instruction in the "caller".
   199  		tracepc = f.entry + uintptr(inltree[ix].parentPc)
   200  		pc = tracepc + 1
   201  	}
   202  
   203  	// N.B. we want to keep the last parentPC which is not inline.
   204  	stk = append(stk, pc)
   205  
   206  	return stk
   207  }
   208  
   209  // expandCgoFrames expands frame information for pc, known to be
   210  // a non-Go function, using the cgoSymbolizer hook. expandCgoFrames
   211  // returns nil if pc could not be expanded.
   212  func expandCgoFrames(pc uintptr) []Frame {
   213  	arg := cgoSymbolizerArg{pc: pc}
   214  	callCgoSymbolizer(&arg)
   215  
   216  	if arg.file == nil && arg.funcName == nil {
   217  		// No useful information from symbolizer.
   218  		return nil
   219  	}
   220  
   221  	var frames []Frame
   222  	for {
   223  		frames = append(frames, Frame{
   224  			PC:       pc,
   225  			Func:     nil,
   226  			Function: gostring(arg.funcName),
   227  			File:     gostring(arg.file),
   228  			Line:     int(arg.lineno),
   229  			Entry:    arg.entry,
   230  			// funcInfo is zero, which implies !funcInfo.valid().
   231  			// That ensures that we use the File/Line info given here.
   232  		})
   233  		if arg.more == 0 {
   234  			break
   235  		}
   236  		callCgoSymbolizer(&arg)
   237  	}
   238  
   239  	// No more frames for this PC. Tell the symbolizer we are done.
   240  	// We don't try to maintain a single cgoSymbolizerArg for the
   241  	// whole use of Frames, because there would be no good way to tell
   242  	// the symbolizer when we are done.
   243  	arg.pc = 0
   244  	callCgoSymbolizer(&arg)
   245  
   246  	return frames
   247  }
   248  
   249  // NOTE: Func does not expose the actual unexported fields, because we return *Func
   250  // values to users, and we want to keep them from being able to overwrite the data
   251  // with (say) *f = Func{}.
   252  // All code operating on a *Func must call raw() to get the *_func
   253  // or funcInfo() to get the funcInfo instead.
   254  
   255  // A Func represents a Go function in the running binary.
   256  type Func struct {
   257  	opaque struct{} // unexported field to disallow conversions
   258  }
   259  
   260  func (f *Func) raw() *_func {
   261  	return (*_func)(unsafe.Pointer(f))
   262  }
   263  
   264  func (f *Func) funcInfo() funcInfo {
   265  	fn := f.raw()
   266  	return funcInfo{fn, findmoduledatap(fn.entry)}
   267  }
   268  
   269  // PCDATA and FUNCDATA table indexes.
   270  //
   271  // See funcdata.h and ../cmd/internal/objabi/funcdata.go.
   272  const (
   273  	_PCDATA_UnsafePoint   = 0
   274  	_PCDATA_StackMapIndex = 1
   275  	_PCDATA_InlTreeIndex  = 2
   276  
   277  	_FUNCDATA_ArgsPointerMaps    = 0
   278  	_FUNCDATA_LocalsPointerMaps  = 1
   279  	_FUNCDATA_StackObjects       = 2
   280  	_FUNCDATA_InlTree            = 3
   281  	_FUNCDATA_OpenCodedDeferInfo = 4
   282  
   283  	_ArgsSizeUnknown = -0x80000000
   284  )
   285  
   286  const (
   287  	// PCDATA_UnsafePoint values.
   288  	_PCDATA_UnsafePointSafe   = -1 // Safe for async preemption
   289  	_PCDATA_UnsafePointUnsafe = -2 // Unsafe for async preemption
   290  
   291  	// _PCDATA_Restart1(2) apply on a sequence of instructions, within
   292  	// which if an async preemption happens, we should back off the PC
   293  	// to the start of the sequence when resume.
   294  	// We need two so we can distinguish the start/end of the sequence
   295  	// in case that two sequences are next to each other.
   296  	_PCDATA_Restart1 = -3
   297  	_PCDATA_Restart2 = -4
   298  
   299  	// Like _PCDATA_RestartAtEntry, but back to function entry if async
   300  	// preempted.
   301  	_PCDATA_RestartAtEntry = -5
   302  )
   303  
   304  // A FuncID identifies particular functions that need to be treated
   305  // specially by the runtime.
   306  // Note that in some situations involving plugins, there may be multiple
   307  // copies of a particular special runtime function.
   308  // Note: this list must match the list in cmd/internal/objabi/funcid.go.
   309  type funcID uint8
   310  
   311  const (
   312  	funcID_normal funcID = iota // not a special function
   313  	funcID_runtime_main
   314  	funcID_goexit
   315  	funcID_jmpdefer
   316  	funcID_mcall
   317  	funcID_morestack
   318  	funcID_mstart
   319  	funcID_rt0_go
   320  	funcID_asmcgocall
   321  	funcID_sigpanic
   322  	funcID_runfinq
   323  	funcID_gcBgMarkWorker
   324  	funcID_systemstack_switch
   325  	funcID_systemstack
   326  	funcID_cgocallback
   327  	funcID_gogo
   328  	funcID_externalthreadhandler
   329  	funcID_debugCallV1
   330  	funcID_gopanic
   331  	funcID_panicwrap
   332  	funcID_handleAsyncEvent
   333  	funcID_asyncPreempt
   334  	funcID_wrapper // any autogenerated code (hash/eq algorithms, method wrappers, etc.)
   335  )
   336  
   337  // pcHeader holds data used by the pclntab lookups.
   338  type pcHeader struct {
   339  	magic          uint32  // 0xFFFFFFFA
   340  	pad1, pad2     uint8   // 0,0
   341  	minLC          uint8   // min instruction size
   342  	ptrSize        uint8   // size of a ptr in bytes
   343  	nfunc          int     // number of functions in the module
   344  	nfiles         uint    // number of entries in the file tab.
   345  	funcnameOffset uintptr // offset to the funcnametab variable from pcHeader
   346  	cuOffset       uintptr // offset to the cutab variable from pcHeader
   347  	filetabOffset  uintptr // offset to the filetab variable from pcHeader
   348  	pctabOffset    uintptr // offset to the pctab varible from pcHeader
   349  	pclnOffset     uintptr // offset to the pclntab variable from pcHeader
   350  }
   351  
   352  // moduledata records information about the layout of the executable
   353  // image. It is written by the linker. Any changes here must be
   354  // matched changes to the code in cmd/internal/ld/symtab.go:symtab.
   355  // moduledata is stored in statically allocated non-pointer memory;
   356  // none of the pointers here are visible to the garbage collector.
   357  type moduledata struct {
   358  	pcHeader     *pcHeader
   359  	funcnametab  []byte
   360  	cutab        []uint32
   361  	filetab      []byte
   362  	pctab        []byte
   363  	pclntable    []byte
   364  	ftab         []functab
   365  	findfunctab  uintptr
   366  	minpc, maxpc uintptr
   367  
   368  	text, etext           uintptr
   369  	noptrdata, enoptrdata uintptr
   370  	data, edata           uintptr
   371  	bss, ebss             uintptr
   372  	noptrbss, enoptrbss   uintptr
   373  	end, gcdata, gcbss    uintptr
   374  	types, etypes         uintptr
   375  
   376  	textsectmap []textsect
   377  	typelinks   []int32 // offsets from types
   378  	itablinks   []*itab
   379  
   380  	ptab []ptabEntry
   381  
   382  	pluginpath string
   383  	pkghashes  []modulehash
   384  
   385  	modulename   string
   386  	modulehashes []modulehash
   387  
   388  	hasmain uint8 // 1 if module contains the main function, 0 otherwise
   389  
   390  	gcdatamask, gcbssmask bitvector
   391  
   392  	typemap map[typeOff]*_type // offset to *_rtype in previous module
   393  
   394  	bad bool // module failed to load and should be ignored
   395  
   396  	next *moduledata
   397  }
   398  
   399  // A modulehash is used to compare the ABI of a new module or a
   400  // package in a new module with the loaded program.
   401  //
   402  // For each shared library a module links against, the linker creates an entry in the
   403  // moduledata.modulehashes slice containing the name of the module, the abi hash seen
   404  // at link time and a pointer to the runtime abi hash. These are checked in
   405  // moduledataverify1 below.
   406  //
   407  // For each loaded plugin, the pkghashes slice has a modulehash of the
   408  // newly loaded package that can be used to check the plugin's version of
   409  // a package against any previously loaded version of the package.
   410  // This is done in plugin.lastmoduleinit.
   411  type modulehash struct {
   412  	modulename   string
   413  	linktimehash string
   414  	runtimehash  *string
   415  }
   416  
   417  // pinnedTypemaps are the map[typeOff]*_type from the moduledata objects.
   418  //
   419  // These typemap objects are allocated at run time on the heap, but the
   420  // only direct reference to them is in the moduledata, created by the
   421  // linker and marked SNOPTRDATA so it is ignored by the GC.
   422  //
   423  // To make sure the map isn't collected, we keep a second reference here.
   424  var pinnedTypemaps []map[typeOff]*_type
   425  
   426  var firstmoduledata moduledata  // linker symbol
   427  var lastmoduledatap *moduledata // linker symbol
   428  var modulesSlice *[]*moduledata // see activeModules
   429  
   430  // activeModules returns a slice of active modules.
   431  //
   432  // A module is active once its gcdatamask and gcbssmask have been
   433  // assembled and it is usable by the GC.
   434  //
   435  // This is nosplit/nowritebarrier because it is called by the
   436  // cgo pointer checking code.
   437  //go:nosplit
   438  //go:nowritebarrier
   439  func activeModules() []*moduledata {
   440  	p := (*[]*moduledata)(atomic.Loadp(unsafe.Pointer(&modulesSlice)))
   441  	if p == nil {
   442  		return nil
   443  	}
   444  	return *p
   445  }
   446  
   447  // modulesinit creates the active modules slice out of all loaded modules.
   448  //
   449  // When a module is first loaded by the dynamic linker, an .init_array
   450  // function (written by cmd/link) is invoked to call addmoduledata,
   451  // appending to the module to the linked list that starts with
   452  // firstmoduledata.
   453  //
   454  // There are two times this can happen in the lifecycle of a Go
   455  // program. First, if compiled with -linkshared, a number of modules
   456  // built with -buildmode=shared can be loaded at program initialization.
   457  // Second, a Go program can load a module while running that was built
   458  // with -buildmode=plugin.
   459  //
   460  // After loading, this function is called which initializes the
   461  // moduledata so it is usable by the GC and creates a new activeModules
   462  // list.
   463  //
   464  // Only one goroutine may call modulesinit at a time.
   465  func modulesinit() {
   466  	modules := new([]*moduledata)
   467  	for md := &firstmoduledata; md != nil; md = md.next {
   468  		if md.bad {
   469  			continue
   470  		}
   471  		*modules = append(*modules, md)
   472  		if md.gcdatamask == (bitvector{}) {
   473  			md.gcdatamask = progToPointerMask((*byte)(unsafe.Pointer(md.gcdata)), md.edata-md.data)
   474  			md.gcbssmask = progToPointerMask((*byte)(unsafe.Pointer(md.gcbss)), md.ebss-md.bss)
   475  		}
   476  	}
   477  
   478  	// Modules appear in the moduledata linked list in the order they are
   479  	// loaded by the dynamic loader, with one exception: the
   480  	// firstmoduledata itself the module that contains the runtime. This
   481  	// is not always the first module (when using -buildmode=shared, it
   482  	// is typically libstd.so, the second module). The order matters for
   483  	// typelinksinit, so we swap the first module with whatever module
   484  	// contains the main function.
   485  	//
   486  	// See Issue #18729.
   487  	for i, md := range *modules {
   488  		if md.hasmain != 0 {
   489  			(*modules)[0] = md
   490  			(*modules)[i] = &firstmoduledata
   491  			break
   492  		}
   493  	}
   494  
   495  	atomicstorep(unsafe.Pointer(&modulesSlice), unsafe.Pointer(modules))
   496  }
   497  
   498  type functab struct {
   499  	entry   uintptr
   500  	funcoff uintptr
   501  }
   502  
   503  // Mapping information for secondary text sections
   504  
   505  type textsect struct {
   506  	vaddr    uintptr // prelinked section vaddr
   507  	length   uintptr // section length
   508  	baseaddr uintptr // relocated section address
   509  }
   510  
   511  const minfunc = 16                 // minimum function size
   512  const pcbucketsize = 256 * minfunc // size of bucket in the pc->func lookup table
   513  
   514  // findfunctab is an array of these structures.
   515  // Each bucket represents 4096 bytes of the text segment.
   516  // Each subbucket represents 256 bytes of the text segment.
   517  // To find a function given a pc, locate the bucket and subbucket for
   518  // that pc. Add together the idx and subbucket value to obtain a
   519  // function index. Then scan the functab array starting at that
   520  // index to find the target function.
   521  // This table uses 20 bytes for every 4096 bytes of code, or ~0.5% overhead.
   522  type findfuncbucket struct {
   523  	idx        uint32
   524  	subbuckets [16]byte
   525  }
   526  
   527  func moduledataverify() {
   528  	for datap := &firstmoduledata; datap != nil; datap = datap.next {
   529  		moduledataverify1(datap)
   530  	}
   531  }
   532  
   533  const debugPcln = false
   534  
   535  func moduledataverify1(datap *moduledata) {
   536  	// Check that the pclntab's format is valid.
   537  	hdr := datap.pcHeader
   538  	if hdr.magic != 0xfffffffa || hdr.pad1 != 0 || hdr.pad2 != 0 || hdr.minLC != sys.PCQuantum || hdr.ptrSize != sys.PtrSize {
   539  		println("runtime: function symbol table header:", hex(hdr.magic), hex(hdr.pad1), hex(hdr.pad2), hex(hdr.minLC), hex(hdr.ptrSize))
   540  		throw("invalid function symbol table\n")
   541  	}
   542  
   543  	// ftab is lookup table for function by program counter.
   544  	nftab := len(datap.ftab) - 1
   545  	for i := 0; i < nftab; i++ {
   546  		// NOTE: ftab[nftab].entry is legal; it is the address beyond the final function.
   547  		if datap.ftab[i].entry > datap.ftab[i+1].entry {
   548  			f1 := funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[i].funcoff])), datap}
   549  			f2 := funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[i+1].funcoff])), datap}
   550  			f2name := "end"
   551  			if i+1 < nftab {
   552  				f2name = funcname(f2)
   553  			}
   554  			println("function symbol table not sorted by program counter:", hex(datap.ftab[i].entry), funcname(f1), ">", hex(datap.ftab[i+1].entry), f2name)
   555  			for j := 0; j <= i; j++ {
   556  				print("\t", hex(datap.ftab[j].entry), " ", funcname(funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[j].funcoff])), datap}), "\n")
   557  			}
   558  			if GOOS == "aix" && isarchive {
   559  				println("-Wl,-bnoobjreorder is mandatory on aix/ppc64 with c-archive")
   560  			}
   561  			throw("invalid runtime symbol table")
   562  		}
   563  	}
   564  
   565  	if datap.minpc != datap.ftab[0].entry ||
   566  		datap.maxpc != datap.ftab[nftab].entry {
   567  		throw("minpc or maxpc invalid")
   568  	}
   569  
   570  	for _, modulehash := range datap.modulehashes {
   571  		if modulehash.linktimehash != *modulehash.runtimehash {
   572  			println("abi mismatch detected between", datap.modulename, "and", modulehash.modulename)
   573  			throw("abi mismatch")
   574  		}
   575  	}
   576  }
   577  
   578  // FuncForPC returns a *Func describing the function that contains the
   579  // given program counter address, or else nil.
   580  //
   581  // If pc represents multiple functions because of inlining, it returns
   582  // the *Func describing the innermost function, but with an entry of
   583  // the outermost function.
   584  func FuncForPC(pc uintptr) *Func {
   585  	f := findfunc(pc)
   586  	if !f.valid() {
   587  		return nil
   588  	}
   589  	if inldata := funcdata(f, _FUNCDATA_InlTree); inldata != nil {
   590  		// Note: strict=false so bad PCs (those between functions) don't crash the runtime.
   591  		// We just report the preceding function in that situation. See issue 29735.
   592  		// TODO: Perhaps we should report no function at all in that case.
   593  		// The runtime currently doesn't have function end info, alas.
   594  		if ix := pcdatavalue1(f, _PCDATA_InlTreeIndex, pc, nil, false); ix >= 0 {
   595  			inltree := (*[1 << 20]inlinedCall)(inldata)
   596  			name := funcnameFromNameoff(f, inltree[ix].func_)
   597  			file, line := funcline(f, pc)
   598  			fi := &funcinl{
   599  				entry: f.entry, // entry of the real (the outermost) function.
   600  				name:  name,
   601  				file:  file,
   602  				line:  int(line),
   603  			}
   604  			return (*Func)(unsafe.Pointer(fi))
   605  		}
   606  	}
   607  	return f._Func()
   608  }
   609  
   610  // Name returns the name of the function.
   611  func (f *Func) Name() string {
   612  	if f == nil {
   613  		return ""
   614  	}
   615  	fn := f.raw()
   616  	if fn.entry == 0 { // inlined version
   617  		fi := (*funcinl)(unsafe.Pointer(fn))
   618  		return fi.name
   619  	}
   620  	return funcname(f.funcInfo())
   621  }
   622  
   623  // Entry returns the entry address of the function.
   624  func (f *Func) Entry() uintptr {
   625  	fn := f.raw()
   626  	if fn.entry == 0 { // inlined version
   627  		fi := (*funcinl)(unsafe.Pointer(fn))
   628  		return fi.entry
   629  	}
   630  	return fn.entry
   631  }
   632  
   633  // FileLine returns the file name and line number of the
   634  // source code corresponding to the program counter pc.
   635  // The result will not be accurate if pc is not a program
   636  // counter within f.
   637  func (f *Func) FileLine(pc uintptr) (file string, line int) {
   638  	fn := f.raw()
   639  	if fn.entry == 0 { // inlined version
   640  		fi := (*funcinl)(unsafe.Pointer(fn))
   641  		return fi.file, fi.line
   642  	}
   643  	// Pass strict=false here, because anyone can call this function,
   644  	// and they might just be wrong about targetpc belonging to f.
   645  	file, line32 := funcline1(f.funcInfo(), pc, false)
   646  	return file, int(line32)
   647  }
   648  
   649  func findmoduledatap(pc uintptr) *moduledata {
   650  	for datap := &firstmoduledata; datap != nil; datap = datap.next {
   651  		if datap.minpc <= pc && pc < datap.maxpc {
   652  			return datap
   653  		}
   654  	}
   655  	return nil
   656  }
   657  
   658  type funcInfo struct {
   659  	*_func
   660  	datap *moduledata
   661  }
   662  
   663  func (f funcInfo) valid() bool {
   664  	return f._func != nil
   665  }
   666  
   667  func (f funcInfo) _Func() *Func {
   668  	return (*Func)(unsafe.Pointer(f._func))
   669  }
   670  
   671  func findfunc(pc uintptr) funcInfo {
   672  	datap := findmoduledatap(pc)
   673  	if datap == nil {
   674  		return funcInfo{}
   675  	}
   676  	const nsub = uintptr(len(findfuncbucket{}.subbuckets))
   677  
   678  	x := pc - datap.minpc
   679  	b := x / pcbucketsize
   680  	i := x % pcbucketsize / (pcbucketsize / nsub)
   681  
   682  	ffb := (*findfuncbucket)(add(unsafe.Pointer(datap.findfunctab), b*unsafe.Sizeof(findfuncbucket{})))
   683  	idx := ffb.idx + uint32(ffb.subbuckets[i])
   684  
   685  	// If the idx is beyond the end of the ftab, set it to the end of the table and search backward.
   686  	// This situation can occur if multiple text sections are generated to handle large text sections
   687  	// and the linker has inserted jump tables between them.
   688  
   689  	if idx >= uint32(len(datap.ftab)) {
   690  		idx = uint32(len(datap.ftab) - 1)
   691  	}
   692  	if pc < datap.ftab[idx].entry {
   693  		// With multiple text sections, the idx might reference a function address that
   694  		// is higher than the pc being searched, so search backward until the matching address is found.
   695  
   696  		for datap.ftab[idx].entry > pc && idx > 0 {
   697  			idx--
   698  		}
   699  		if idx == 0 {
   700  			throw("findfunc: bad findfunctab entry idx")
   701  		}
   702  	} else {
   703  		// linear search to find func with pc >= entry.
   704  		for datap.ftab[idx+1].entry <= pc {
   705  			idx++
   706  		}
   707  	}
   708  	funcoff := datap.ftab[idx].funcoff
   709  	if funcoff == ^uintptr(0) {
   710  		// With multiple text sections, there may be functions inserted by the external
   711  		// linker that are not known by Go. This means there may be holes in the PC
   712  		// range covered by the func table. The invalid funcoff value indicates a hole.
   713  		// See also cmd/link/internal/ld/pcln.go:pclntab
   714  		return funcInfo{}
   715  	}
   716  	return funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[funcoff])), datap}
   717  }
   718  
   719  type pcvalueCache struct {
   720  	entries [2][8]pcvalueCacheEnt
   721  }
   722  
   723  type pcvalueCacheEnt struct {
   724  	// targetpc and off together are the key of this cache entry.
   725  	targetpc uintptr
   726  	off      uint32
   727  	// val is the value of this cached pcvalue entry.
   728  	val int32
   729  }
   730  
   731  // pcvalueCacheKey returns the outermost index in a pcvalueCache to use for targetpc.
   732  // It must be very cheap to calculate.
   733  // For now, align to sys.PtrSize and reduce mod the number of entries.
   734  // In practice, this appears to be fairly randomly and evenly distributed.
   735  func pcvalueCacheKey(targetpc uintptr) uintptr {
   736  	return (targetpc / sys.PtrSize) % uintptr(len(pcvalueCache{}.entries))
   737  }
   738  
   739  // Returns the PCData value, and the PC where this value starts.
   740  // TODO: the start PC is returned only when cache is nil.
   741  func pcvalue(f funcInfo, off uint32, targetpc uintptr, cache *pcvalueCache, strict bool) (int32, uintptr) {
   742  	if off == 0 {
   743  		return -1, 0
   744  	}
   745  
   746  	// Check the cache. This speeds up walks of deep stacks, which
   747  	// tend to have the same recursive functions over and over.
   748  	//
   749  	// This cache is small enough that full associativity is
   750  	// cheaper than doing the hashing for a less associative
   751  	// cache.
   752  	if cache != nil {
   753  		x := pcvalueCacheKey(targetpc)
   754  		for i := range cache.entries[x] {
   755  			// We check off first because we're more
   756  			// likely to have multiple entries with
   757  			// different offsets for the same targetpc
   758  			// than the other way around, so we'll usually
   759  			// fail in the first clause.
   760  			ent := &cache.entries[x][i]
   761  			if ent.off == off && ent.targetpc == targetpc {
   762  				return ent.val, 0
   763  			}
   764  		}
   765  	}
   766  
   767  	if !f.valid() {
   768  		if strict && panicking == 0 {
   769  			print("runtime: no module data for ", hex(f.entry), "\n")
   770  			throw("no module data")
   771  		}
   772  		return -1, 0
   773  	}
   774  	datap := f.datap
   775  	p := datap.pctab[off:]
   776  	pc := f.entry
   777  	prevpc := pc
   778  	val := int32(-1)
   779  	for {
   780  		var ok bool
   781  		p, ok = step(p, &pc, &val, pc == f.entry)
   782  		if !ok {
   783  			break
   784  		}
   785  		if targetpc < pc {
   786  			// Replace a random entry in the cache. Random
   787  			// replacement prevents a performance cliff if
   788  			// a recursive stack's cycle is slightly
   789  			// larger than the cache.
   790  			// Put the new element at the beginning,
   791  			// since it is the most likely to be newly used.
   792  			if cache != nil {
   793  				x := pcvalueCacheKey(targetpc)
   794  				e := &cache.entries[x]
   795  				ci := fastrand() % uint32(len(cache.entries[x]))
   796  				e[ci] = e[0]
   797  				e[0] = pcvalueCacheEnt{
   798  					targetpc: targetpc,
   799  					off:      off,
   800  					val:      val,
   801  				}
   802  			}
   803  
   804  			return val, prevpc
   805  		}
   806  		prevpc = pc
   807  	}
   808  
   809  	// If there was a table, it should have covered all program counters.
   810  	// If not, something is wrong.
   811  	if panicking != 0 || !strict {
   812  		return -1, 0
   813  	}
   814  
   815  	print("runtime: invalid pc-encoded table f=", funcname(f), " pc=", hex(pc), " targetpc=", hex(targetpc), " tab=", p, "\n")
   816  
   817  	p = datap.pctab[off:]
   818  	pc = f.entry
   819  	val = -1
   820  	for {
   821  		var ok bool
   822  		p, ok = step(p, &pc, &val, pc == f.entry)
   823  		if !ok {
   824  			break
   825  		}
   826  		print("\tvalue=", val, " until pc=", hex(pc), "\n")
   827  	}
   828  
   829  	throw("invalid runtime symbol table")
   830  	return -1, 0
   831  }
   832  
   833  func cfuncname(f funcInfo) *byte {
   834  	if !f.valid() || f.nameoff == 0 {
   835  		return nil
   836  	}
   837  	return &f.datap.funcnametab[f.nameoff]
   838  }
   839  
   840  func funcname(f funcInfo) string {
   841  	return gostringnocopy(cfuncname(f))
   842  }
   843  
   844  func funcpkgpath(f funcInfo) string {
   845  	name := funcname(f)
   846  	i := len(name) - 1
   847  	for ; i > 0; i-- {
   848  		if name[i] == '/' {
   849  			break
   850  		}
   851  	}
   852  	for ; i < len(name); i++ {
   853  		if name[i] == '.' {
   854  			break
   855  		}
   856  	}
   857  	return name[:i]
   858  }
   859  
   860  func cfuncnameFromNameoff(f funcInfo, nameoff int32) *byte {
   861  	if !f.valid() {
   862  		return nil
   863  	}
   864  	return &f.datap.funcnametab[nameoff]
   865  }
   866  
   867  func funcnameFromNameoff(f funcInfo, nameoff int32) string {
   868  	return gostringnocopy(cfuncnameFromNameoff(f, nameoff))
   869  }
   870  
   871  func funcfile(f funcInfo, fileno int32) string {
   872  	datap := f.datap
   873  	if !f.valid() {
   874  		return "?"
   875  	}
   876  	// Make sure the cu index and file offset are valid
   877  	if fileoff := datap.cutab[f.cuOffset+uint32(fileno)]; fileoff != ^uint32(0) {
   878  		return gostringnocopy(&datap.filetab[fileoff])
   879  	}
   880  	// pcln section is corrupt.
   881  	return "?"
   882  }
   883  
   884  func funcline1(f funcInfo, targetpc uintptr, strict bool) (file string, line int32) {
   885  	datap := f.datap
   886  	if !f.valid() {
   887  		return "?", 0
   888  	}
   889  	fileno, _ := pcvalue(f, f.pcfile, targetpc, nil, strict)
   890  	line, _ = pcvalue(f, f.pcln, targetpc, nil, strict)
   891  	if fileno == -1 || line == -1 || int(fileno) >= len(datap.filetab) {
   892  		// print("looking for ", hex(targetpc), " in ", funcname(f), " got file=", fileno, " line=", lineno, "\n")
   893  		return "?", 0
   894  	}
   895  	file = funcfile(f, fileno)
   896  	return
   897  }
   898  
   899  func funcline(f funcInfo, targetpc uintptr) (file string, line int32) {
   900  	return funcline1(f, targetpc, true)
   901  }
   902  
   903  func funcspdelta(f funcInfo, targetpc uintptr, cache *pcvalueCache) int32 {
   904  	x, _ := pcvalue(f, f.pcsp, targetpc, cache, true)
   905  	if x&(sys.PtrSize-1) != 0 {
   906  		print("invalid spdelta ", funcname(f), " ", hex(f.entry), " ", hex(targetpc), " ", hex(f.pcsp), " ", x, "\n")
   907  	}
   908  	return x
   909  }
   910  
   911  // funcMaxSPDelta returns the maximum spdelta at any point in f.
   912  func funcMaxSPDelta(f funcInfo) int32 {
   913  	datap := f.datap
   914  	p := datap.pctab[f.pcsp:]
   915  	pc := f.entry
   916  	val := int32(-1)
   917  	max := int32(0)
   918  	for {
   919  		var ok bool
   920  		p, ok = step(p, &pc, &val, pc == f.entry)
   921  		if !ok {
   922  			return max
   923  		}
   924  		if val > max {
   925  			max = val
   926  		}
   927  	}
   928  }
   929  
   930  func pcdatastart(f funcInfo, table uint32) uint32 {
   931  	return *(*uint32)(add(unsafe.Pointer(&f.nfuncdata), unsafe.Sizeof(f.nfuncdata)+uintptr(table)*4))
   932  }
   933  
   934  func pcdatavalue(f funcInfo, table uint32, targetpc uintptr, cache *pcvalueCache) int32 {
   935  	if table >= f.npcdata {
   936  		return -1
   937  	}
   938  	r, _ := pcvalue(f, pcdatastart(f, table), targetpc, cache, true)
   939  	return r
   940  }
   941  
   942  func pcdatavalue1(f funcInfo, table uint32, targetpc uintptr, cache *pcvalueCache, strict bool) int32 {
   943  	if table >= f.npcdata {
   944  		return -1
   945  	}
   946  	r, _ := pcvalue(f, pcdatastart(f, table), targetpc, cache, strict)
   947  	return r
   948  }
   949  
   950  // Like pcdatavalue, but also return the start PC of this PCData value.
   951  // It doesn't take a cache.
   952  func pcdatavalue2(f funcInfo, table uint32, targetpc uintptr) (int32, uintptr) {
   953  	if table >= f.npcdata {
   954  		return -1, 0
   955  	}
   956  	return pcvalue(f, pcdatastart(f, table), targetpc, nil, true)
   957  }
   958  
   959  func funcdata(f funcInfo, i uint8) unsafe.Pointer {
   960  	if i < 0 || i >= f.nfuncdata {
   961  		return nil
   962  	}
   963  	p := add(unsafe.Pointer(&f.nfuncdata), unsafe.Sizeof(f.nfuncdata)+uintptr(f.npcdata)*4)
   964  	if sys.PtrSize == 8 && uintptr(p)&4 != 0 {
   965  		if uintptr(unsafe.Pointer(f._func))&4 != 0 {
   966  			println("runtime: misaligned func", f._func)
   967  		}
   968  		p = add(p, 4)
   969  	}
   970  	return *(*unsafe.Pointer)(add(p, uintptr(i)*sys.PtrSize))
   971  }
   972  
   973  // step advances to the next pc, value pair in the encoded table.
   974  func step(p []byte, pc *uintptr, val *int32, first bool) (newp []byte, ok bool) {
   975  	// For both uvdelta and pcdelta, the common case (~70%)
   976  	// is that they are a single byte. If so, avoid calling readvarint.
   977  	uvdelta := uint32(p[0])
   978  	if uvdelta == 0 && !first {
   979  		return nil, false
   980  	}
   981  	n := uint32(1)
   982  	if uvdelta&0x80 != 0 {
   983  		n, uvdelta = readvarint(p)
   984  	}
   985  	*val += int32(-(uvdelta & 1) ^ (uvdelta >> 1))
   986  	p = p[n:]
   987  
   988  	pcdelta := uint32(p[0])
   989  	n = 1
   990  	if pcdelta&0x80 != 0 {
   991  		n, pcdelta = readvarint(p)
   992  	}
   993  	p = p[n:]
   994  	*pc += uintptr(pcdelta * sys.PCQuantum)
   995  	return p, true
   996  }
   997  
   998  // readvarint reads a varint from p.
   999  func readvarint(p []byte) (read uint32, val uint32) {
  1000  	var v, shift, n uint32
  1001  	for {
  1002  		b := p[n]
  1003  		n++
  1004  		v |= uint32(b&0x7F) << (shift & 31)
  1005  		if b&0x80 == 0 {
  1006  			break
  1007  		}
  1008  		shift += 7
  1009  	}
  1010  	return n, v
  1011  }
  1012  
  1013  type stackmap struct {
  1014  	n        int32   // number of bitmaps
  1015  	nbit     int32   // number of bits in each bitmap
  1016  	bytedata [1]byte // bitmaps, each starting on a byte boundary
  1017  }
  1018  
  1019  //go:nowritebarrier
  1020  func stackmapdata(stkmap *stackmap, n int32) bitvector {
  1021  	// Check this invariant only when stackDebug is on at all.
  1022  	// The invariant is already checked by many of stackmapdata's callers,
  1023  	// and disabling it by default allows stackmapdata to be inlined.
  1024  	if stackDebug > 0 && (n < 0 || n >= stkmap.n) {
  1025  		throw("stackmapdata: index out of range")
  1026  	}
  1027  	return bitvector{stkmap.nbit, addb(&stkmap.bytedata[0], uintptr(n*((stkmap.nbit+7)>>3)))}
  1028  }
  1029  
  1030  // inlinedCall is the encoding of entries in the FUNCDATA_InlTree table.
  1031  type inlinedCall struct {
  1032  	parent   int16  // index of parent in the inltree, or < 0
  1033  	funcID   funcID // type of the called function
  1034  	_        byte
  1035  	file     int32 // perCU file index for inlined call. See cmd/link:pcln.go
  1036  	line     int32 // line number of the call site
  1037  	func_    int32 // offset into pclntab for name of called function
  1038  	parentPc int32 // position of an instruction whose source position is the call site (offset from entry)
  1039  }
  1040  

View as plain text