Source file src/runtime/symtab.go

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

View as plain text