github.com/AESNooper/go/src@v0.0.0-20220218095104-b56a4ab1bbbb/runtime/symtab.go (about)

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