...

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  	"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  	_FUNCDATA_WrapInfo           = 7
   314  
   315  	_ArgsSizeUnknown = -0x80000000
   316  )
   317  
   318  const (
   319  	// PCDATA_UnsafePoint values.
   320  	_PCDATA_UnsafePointSafe   = -1 // Safe for async preemption
   321  	_PCDATA_UnsafePointUnsafe = -2 // Unsafe for async preemption
   322  
   323  	// _PCDATA_Restart1(2) apply on a sequence of instructions, within
   324  	// which if an async preemption happens, we should back off the PC
   325  	// to the start of the sequence when resume.
   326  	// We need two so we can distinguish the start/end of the sequence
   327  	// in case that two sequences are next to each other.
   328  	_PCDATA_Restart1 = -3
   329  	_PCDATA_Restart2 = -4
   330  
   331  	// Like _PCDATA_RestartAtEntry, but back to function entry if async
   332  	// preempted.
   333  	_PCDATA_RestartAtEntry = -5
   334  )
   335  
   336  // A FuncID identifies particular functions that need to be treated
   337  // specially by the runtime.
   338  // Note that in some situations involving plugins, there may be multiple
   339  // copies of a particular special runtime function.
   340  // Note: this list must match the list in cmd/internal/objabi/funcid.go.
   341  type funcID uint8
   342  
   343  const (
   344  	funcID_normal funcID = iota // not a special function
   345  	funcID_abort
   346  	funcID_asmcgocall
   347  	funcID_asyncPreempt
   348  	funcID_cgocallback
   349  	funcID_debugCallV2
   350  	funcID_gcBgMarkWorker
   351  	funcID_goexit
   352  	funcID_gogo
   353  	funcID_gopanic
   354  	funcID_handleAsyncEvent
   355  	funcID_mcall
   356  	funcID_morestack
   357  	funcID_mstart
   358  	funcID_panicwrap
   359  	funcID_rt0_go
   360  	funcID_runfinq
   361  	funcID_runtime_main
   362  	funcID_sigpanic
   363  	funcID_systemstack
   364  	funcID_systemstack_switch
   365  	funcID_wrapper // any autogenerated code (hash/eq algorithms, method wrappers, etc.)
   366  )
   367  
   368  // A FuncFlag holds bits about a function.
   369  // This list must match the list in cmd/internal/objabi/funcid.go.
   370  type funcFlag uint8
   371  
   372  const (
   373  	// TOPFRAME indicates a function that appears at the top of its stack.
   374  	// The traceback routine stop at such a function and consider that a
   375  	// successful, complete traversal of the stack.
   376  	// Examples of TOPFRAME functions include goexit, which appears
   377  	// at the top of a user goroutine stack, and mstart, which appears
   378  	// at the top of a system goroutine stack.
   379  	funcFlag_TOPFRAME funcFlag = 1 << iota
   380  
   381  	// SPWRITE indicates a function that writes an arbitrary value to SP
   382  	// (any write other than adding or subtracting a constant amount).
   383  	// The traceback routines cannot encode such changes into the
   384  	// pcsp tables, so the function traceback cannot safely unwind past
   385  	// SPWRITE functions. Stopping at an SPWRITE function is considered
   386  	// to be an incomplete unwinding of the stack. In certain contexts
   387  	// (in particular garbage collector stack scans) that is a fatal error.
   388  	funcFlag_SPWRITE
   389  
   390  	// ASM indicates that a function was implemented in assembly.
   391  	funcFlag_ASM
   392  )
   393  
   394  // pcHeader holds data used by the pclntab lookups.
   395  type pcHeader struct {
   396  	magic          uint32  // 0xFFFFFFF0
   397  	pad1, pad2     uint8   // 0,0
   398  	minLC          uint8   // min instruction size
   399  	ptrSize        uint8   // size of a ptr in bytes
   400  	nfunc          int     // number of functions in the module
   401  	nfiles         uint    // number of entries in the file tab
   402  	textStart      uintptr // base for function entry PC offsets in this module, equal to moduledata.text
   403  	funcnameOffset uintptr // offset to the funcnametab variable from pcHeader
   404  	cuOffset       uintptr // offset to the cutab variable from pcHeader
   405  	filetabOffset  uintptr // offset to the filetab variable from pcHeader
   406  	pctabOffset    uintptr // offset to the pctab variable from pcHeader
   407  	pclnOffset     uintptr // offset to the pclntab variable from pcHeader
   408  }
   409  
   410  // moduledata records information about the layout of the executable
   411  // image. It is written by the linker. Any changes here must be
   412  // matched changes to the code in cmd/link/internal/ld/symtab.go:symtab.
   413  // moduledata is stored in statically allocated non-pointer memory;
   414  // none of the pointers here are visible to the garbage collector.
   415  type moduledata struct {
   416  	pcHeader     *pcHeader
   417  	funcnametab  []byte
   418  	cutab        []uint32
   419  	filetab      []byte
   420  	pctab        []byte
   421  	pclntable    []byte
   422  	ftab         []functab
   423  	findfunctab  uintptr
   424  	minpc, maxpc uintptr
   425  
   426  	text, etext           uintptr
   427  	noptrdata, enoptrdata uintptr
   428  	data, edata           uintptr
   429  	bss, ebss             uintptr
   430  	noptrbss, enoptrbss   uintptr
   431  	end, gcdata, gcbss    uintptr
   432  	types, etypes         uintptr
   433  	rodata                uintptr
   434  	gofunc                uintptr // go.func.*
   435  
   436  	textsectmap []textsect
   437  	typelinks   []int32 // offsets from types
   438  	itablinks   []*itab
   439  
   440  	ptab []ptabEntry
   441  
   442  	pluginpath string
   443  	pkghashes  []modulehash
   444  
   445  	modulename   string
   446  	modulehashes []modulehash
   447  
   448  	hasmain uint8 // 1 if module contains the main function, 0 otherwise
   449  
   450  	gcdatamask, gcbssmask bitvector
   451  
   452  	typemap map[typeOff]*_type // offset to *_rtype in previous module
   453  
   454  	bad bool // module failed to load and should be ignored
   455  
   456  	next *moduledata
   457  }
   458  
   459  // A modulehash is used to compare the ABI of a new module or a
   460  // package in a new module with the loaded program.
   461  //
   462  // For each shared library a module links against, the linker creates an entry in the
   463  // moduledata.modulehashes slice containing the name of the module, the abi hash seen
   464  // at link time and a pointer to the runtime abi hash. These are checked in
   465  // moduledataverify1 below.
   466  //
   467  // For each loaded plugin, the pkghashes slice has a modulehash of the
   468  // newly loaded package that can be used to check the plugin's version of
   469  // a package against any previously loaded version of the package.
   470  // This is done in plugin.lastmoduleinit.
   471  type modulehash struct {
   472  	modulename   string
   473  	linktimehash string
   474  	runtimehash  *string
   475  }
   476  
   477  // pinnedTypemaps are the map[typeOff]*_type from the moduledata objects.
   478  //
   479  // These typemap objects are allocated at run time on the heap, but the
   480  // only direct reference to them is in the moduledata, created by the
   481  // linker and marked SNOPTRDATA so it is ignored by the GC.
   482  //
   483  // To make sure the map isn't collected, we keep a second reference here.
   484  var pinnedTypemaps []map[typeOff]*_type
   485  
   486  var firstmoduledata moduledata  // linker symbol
   487  var lastmoduledatap *moduledata // linker symbol
   488  var modulesSlice *[]*moduledata // see activeModules
   489  
   490  // activeModules returns a slice of active modules.
   491  //
   492  // A module is active once its gcdatamask and gcbssmask have been
   493  // assembled and it is usable by the GC.
   494  //
   495  // This is nosplit/nowritebarrier because it is called by the
   496  // cgo pointer checking code.
   497  //
   498  //go:nosplit
   499  //go:nowritebarrier
   500  func activeModules() []*moduledata {
   501  	p := (*[]*moduledata)(atomic.Loadp(unsafe.Pointer(&modulesSlice)))
   502  	if p == nil {
   503  		return nil
   504  	}
   505  	return *p
   506  }
   507  
   508  // modulesinit creates the active modules slice out of all loaded modules.
   509  //
   510  // When a module is first loaded by the dynamic linker, an .init_array
   511  // function (written by cmd/link) is invoked to call addmoduledata,
   512  // appending to the module to the linked list that starts with
   513  // firstmoduledata.
   514  //
   515  // There are two times this can happen in the lifecycle of a Go
   516  // program. First, if compiled with -linkshared, a number of modules
   517  // built with -buildmode=shared can be loaded at program initialization.
   518  // Second, a Go program can load a module while running that was built
   519  // with -buildmode=plugin.
   520  //
   521  // After loading, this function is called which initializes the
   522  // moduledata so it is usable by the GC and creates a new activeModules
   523  // list.
   524  //
   525  // Only one goroutine may call modulesinit at a time.
   526  func modulesinit() {
   527  	modules := new([]*moduledata)
   528  	for md := &firstmoduledata; md != nil; md = md.next {
   529  		if md.bad {
   530  			continue
   531  		}
   532  		*modules = append(*modules, md)
   533  		if md.gcdatamask == (bitvector{}) {
   534  			scanDataSize := md.edata - md.data
   535  			md.gcdatamask = progToPointerMask((*byte)(unsafe.Pointer(md.gcdata)), scanDataSize)
   536  			scanBSSSize := md.ebss - md.bss
   537  			md.gcbssmask = progToPointerMask((*byte)(unsafe.Pointer(md.gcbss)), scanBSSSize)
   538  			gcController.addGlobals(int64(scanDataSize + scanBSSSize))
   539  		}
   540  	}
   541  
   542  	// Modules appear in the moduledata linked list in the order they are
   543  	// loaded by the dynamic loader, with one exception: the
   544  	// firstmoduledata itself the module that contains the runtime. This
   545  	// is not always the first module (when using -buildmode=shared, it
   546  	// is typically libstd.so, the second module). The order matters for
   547  	// typelinksinit, so we swap the first module with whatever module
   548  	// contains the main function.
   549  	//
   550  	// See Issue #18729.
   551  	for i, md := range *modules {
   552  		if md.hasmain != 0 {
   553  			(*modules)[0] = md
   554  			(*modules)[i] = &firstmoduledata
   555  			break
   556  		}
   557  	}
   558  
   559  	atomicstorep(unsafe.Pointer(&modulesSlice), unsafe.Pointer(modules))
   560  }
   561  
   562  type functab struct {
   563  	entryoff uint32 // relative to runtime.text
   564  	funcoff  uint32
   565  }
   566  
   567  // Mapping information for secondary text sections
   568  
   569  type textsect struct {
   570  	vaddr    uintptr // prelinked section vaddr
   571  	end      uintptr // vaddr + section length
   572  	baseaddr uintptr // relocated section address
   573  }
   574  
   575  const minfunc = 16                 // minimum function size
   576  const pcbucketsize = 256 * minfunc // size of bucket in the pc->func lookup table
   577  
   578  // findfunctab is an array of these structures.
   579  // Each bucket represents 4096 bytes of the text segment.
   580  // Each subbucket represents 256 bytes of the text segment.
   581  // To find a function given a pc, locate the bucket and subbucket for
   582  // that pc. Add together the idx and subbucket value to obtain a
   583  // function index. Then scan the functab array starting at that
   584  // index to find the target function.
   585  // This table uses 20 bytes for every 4096 bytes of code, or ~0.5% overhead.
   586  type findfuncbucket struct {
   587  	idx        uint32
   588  	subbuckets [16]byte
   589  }
   590  
   591  func moduledataverify() {
   592  	for datap := &firstmoduledata; datap != nil; datap = datap.next {
   593  		moduledataverify1(datap)
   594  	}
   595  }
   596  
   597  const debugPcln = false
   598  
   599  func moduledataverify1(datap *moduledata) {
   600  	// Check that the pclntab's format is valid.
   601  	hdr := datap.pcHeader
   602  	if hdr.magic != 0xfffffff0 || hdr.pad1 != 0 || hdr.pad2 != 0 ||
   603  		hdr.minLC != sys.PCQuantum || hdr.ptrSize != goarch.PtrSize || hdr.textStart != datap.text {
   604  		println("runtime: pcHeader: magic=", hex(hdr.magic), "pad1=", hdr.pad1, "pad2=", hdr.pad2,
   605  			"minLC=", hdr.minLC, "ptrSize=", hdr.ptrSize, "pcHeader.textStart=", hex(hdr.textStart),
   606  			"text=", hex(datap.text), "pluginpath=", datap.pluginpath)
   607  		throw("invalid function symbol table")
   608  	}
   609  
   610  	// ftab is lookup table for function by program counter.
   611  	nftab := len(datap.ftab) - 1
   612  	for i := 0; i < nftab; i++ {
   613  		// NOTE: ftab[nftab].entry is legal; it is the address beyond the final function.
   614  		if datap.ftab[i].entryoff > datap.ftab[i+1].entryoff {
   615  			f1 := funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[i].funcoff])), datap}
   616  			f2 := funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[i+1].funcoff])), datap}
   617  			f2name := "end"
   618  			if i+1 < nftab {
   619  				f2name = funcname(f2)
   620  			}
   621  			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)
   622  			for j := 0; j <= i; j++ {
   623  				println("\t", hex(datap.ftab[j].entryoff), funcname(funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[j].funcoff])), datap}))
   624  			}
   625  			if GOOS == "aix" && isarchive {
   626  				println("-Wl,-bnoobjreorder is mandatory on aix/ppc64 with c-archive")
   627  			}
   628  			throw("invalid runtime symbol table")
   629  		}
   630  	}
   631  
   632  	min := datap.textAddr(datap.ftab[0].entryoff)
   633  	max := datap.textAddr(datap.ftab[nftab].entryoff)
   634  	if datap.minpc != min || datap.maxpc != max {
   635  		println("minpc=", hex(datap.minpc), "min=", hex(min), "maxpc=", hex(datap.maxpc), "max=", hex(max))
   636  		throw("minpc or maxpc invalid")
   637  	}
   638  
   639  	for _, modulehash := range datap.modulehashes {
   640  		if modulehash.linktimehash != *modulehash.runtimehash {
   641  			println("abi mismatch detected between", datap.modulename, "and", modulehash.modulename)
   642  			throw("abi mismatch")
   643  		}
   644  	}
   645  }
   646  
   647  // textAddr returns md.text + off, with special handling for multiple text sections.
   648  // off is a (virtual) offset computed at internal linking time,
   649  // before the external linker adjusts the sections' base addresses.
   650  //
   651  // The text, or instruction stream is generated as one large buffer.
   652  // The off (offset) for a function is its offset within this buffer.
   653  // If the total text size gets too large, there can be issues on platforms like ppc64
   654  // if the target of calls are too far for the call instruction.
   655  // To resolve the large text issue, the text is split into multiple text sections
   656  // to allow the linker to generate long calls when necessary.
   657  // When this happens, the vaddr for each text section is set to its offset within the text.
   658  // Each function's offset is compared against the section vaddrs and ends to determine the containing section.
   659  // Then the section relative offset is added to the section's
   660  // relocated baseaddr to compute the function address.
   661  //
   662  // It is nosplit because it is part of the findfunc implementation.
   663  //
   664  //go:nosplit
   665  func (md *moduledata) textAddr(off32 uint32) uintptr {
   666  	off := uintptr(off32)
   667  	res := md.text + off
   668  	if len(md.textsectmap) > 1 {
   669  		for i, sect := range md.textsectmap {
   670  			// For the last section, include the end address (etext), as it is included in the functab.
   671  			if off >= sect.vaddr && off < sect.end || (i == len(md.textsectmap)-1 && off == sect.end) {
   672  				res = sect.baseaddr + off - sect.vaddr
   673  				break
   674  			}
   675  		}
   676  		if res > md.etext && GOARCH != "wasm" { // on wasm, functions do not live in the same address space as the linear memory
   677  			println("runtime: textAddr", hex(res), "out of range", hex(md.text), "-", hex(md.etext))
   678  			throw("runtime: text offset out of range")
   679  		}
   680  	}
   681  	return res
   682  }
   683  
   684  // textOff is the opposite of textAddr. It converts a PC to a (virtual) offset
   685  // to md.text, and returns if the PC is in any Go text section.
   686  //
   687  // It is nosplit because it is part of the findfunc implementation.
   688  //
   689  //go:nosplit
   690  func (md *moduledata) textOff(pc uintptr) (uint32, bool) {
   691  	res := uint32(pc - md.text)
   692  	if len(md.textsectmap) > 1 {
   693  		for i, sect := range md.textsectmap {
   694  			if sect.baseaddr > pc {
   695  				// pc is not in any section.
   696  				return 0, false
   697  			}
   698  			end := sect.baseaddr + (sect.end - sect.vaddr)
   699  			// For the last section, include the end address (etext), as it is included in the functab.
   700  			if i == len(md.textsectmap) {
   701  				end++
   702  			}
   703  			if pc < end {
   704  				res = uint32(pc - sect.baseaddr + sect.vaddr)
   705  				break
   706  			}
   707  		}
   708  	}
   709  	return res, true
   710  }
   711  
   712  // FuncForPC returns a *Func describing the function that contains the
   713  // given program counter address, or else nil.
   714  //
   715  // If pc represents multiple functions because of inlining, it returns
   716  // the *Func describing the innermost function, but with an entry of
   717  // the outermost function.
   718  func FuncForPC(pc uintptr) *Func {
   719  	f := findfunc(pc)
   720  	if !f.valid() {
   721  		return nil
   722  	}
   723  	if inldata := funcdata(f, _FUNCDATA_InlTree); inldata != nil {
   724  		// Note: strict=false so bad PCs (those between functions) don't crash the runtime.
   725  		// We just report the preceding function in that situation. See issue 29735.
   726  		// TODO: Perhaps we should report no function at all in that case.
   727  		// The runtime currently doesn't have function end info, alas.
   728  		if ix := pcdatavalue1(f, _PCDATA_InlTreeIndex, pc, nil, false); ix >= 0 {
   729  			inltree := (*[1 << 20]inlinedCall)(inldata)
   730  			name := funcnameFromNameoff(f, inltree[ix].func_)
   731  			file, line := funcline(f, pc)
   732  			fi := &funcinl{
   733  				ones:  ^uint32(0),
   734  				entry: f.entry(), // entry of the real (the outermost) function.
   735  				name:  name,
   736  				file:  file,
   737  				line:  int(line),
   738  			}
   739  			return (*Func)(unsafe.Pointer(fi))
   740  		}
   741  	}
   742  	return f._Func()
   743  }
   744  
   745  // Name returns the name of the function.
   746  func (f *Func) Name() string {
   747  	if f == nil {
   748  		return ""
   749  	}
   750  	fn := f.raw()
   751  	if fn.isInlined() { // inlined version
   752  		fi := (*funcinl)(unsafe.Pointer(fn))
   753  		return fi.name
   754  	}
   755  	return funcname(f.funcInfo())
   756  }
   757  
   758  // Entry returns the entry address of the function.
   759  func (f *Func) Entry() uintptr {
   760  	fn := f.raw()
   761  	if fn.isInlined() { // inlined version
   762  		fi := (*funcinl)(unsafe.Pointer(fn))
   763  		return fi.entry
   764  	}
   765  	return fn.funcInfo().entry()
   766  }
   767  
   768  // FileLine returns the file name and line number of the
   769  // source code corresponding to the program counter pc.
   770  // The result will not be accurate if pc is not a program
   771  // counter within f.
   772  func (f *Func) FileLine(pc uintptr) (file string, line int) {
   773  	fn := f.raw()
   774  	if fn.isInlined() { // inlined version
   775  		fi := (*funcinl)(unsafe.Pointer(fn))
   776  		return fi.file, fi.line
   777  	}
   778  	// Pass strict=false here, because anyone can call this function,
   779  	// and they might just be wrong about targetpc belonging to f.
   780  	file, line32 := funcline1(f.funcInfo(), pc, false)
   781  	return file, int(line32)
   782  }
   783  
   784  // findmoduledatap looks up the moduledata for a PC.
   785  //
   786  // It is nosplit because it's part of the isgoexception
   787  // implementation.
   788  //
   789  //go:nosplit
   790  func findmoduledatap(pc uintptr) *moduledata {
   791  	for datap := &firstmoduledata; datap != nil; datap = datap.next {
   792  		if datap.minpc <= pc && pc < datap.maxpc {
   793  			return datap
   794  		}
   795  	}
   796  	return nil
   797  }
   798  
   799  type funcInfo struct {
   800  	*_func
   801  	datap *moduledata
   802  }
   803  
   804  func (f funcInfo) valid() bool {
   805  	return f._func != nil
   806  }
   807  
   808  func (f funcInfo) _Func() *Func {
   809  	return (*Func)(unsafe.Pointer(f._func))
   810  }
   811  
   812  // isInlined reports whether f should be re-interpreted as a *funcinl.
   813  func (f *_func) isInlined() bool {
   814  	return f.entryoff == ^uint32(0) // see comment for funcinl.ones
   815  }
   816  
   817  // entry returns the entry PC for f.
   818  func (f funcInfo) entry() uintptr {
   819  	return f.datap.textAddr(f.entryoff)
   820  }
   821  
   822  // findfunc looks up function metadata for a PC.
   823  //
   824  // It is nosplit because it's part of the isgoexception
   825  // implementation.
   826  //
   827  //go:nosplit
   828  func findfunc(pc uintptr) funcInfo {
   829  	datap := findmoduledatap(pc)
   830  	if datap == nil {
   831  		return funcInfo{}
   832  	}
   833  	const nsub = uintptr(len(findfuncbucket{}.subbuckets))
   834  
   835  	pcOff, ok := datap.textOff(pc)
   836  	if !ok {
   837  		return funcInfo{}
   838  	}
   839  
   840  	x := uintptr(pcOff) + datap.text - datap.minpc // TODO: are datap.text and datap.minpc always equal?
   841  	b := x / pcbucketsize
   842  	i := x % pcbucketsize / (pcbucketsize / nsub)
   843  
   844  	ffb := (*findfuncbucket)(add(unsafe.Pointer(datap.findfunctab), b*unsafe.Sizeof(findfuncbucket{})))
   845  	idx := ffb.idx + uint32(ffb.subbuckets[i])
   846  
   847  	// Find the ftab entry.
   848  	for datap.ftab[idx+1].entryoff <= pcOff {
   849  		idx++
   850  	}
   851  
   852  	funcoff := datap.ftab[idx].funcoff
   853  	return funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[funcoff])), datap}
   854  }
   855  
   856  type pcvalueCache struct {
   857  	entries [2][8]pcvalueCacheEnt
   858  }
   859  
   860  type pcvalueCacheEnt struct {
   861  	// targetpc and off together are the key of this cache entry.
   862  	targetpc uintptr
   863  	off      uint32
   864  	// val is the value of this cached pcvalue entry.
   865  	val int32
   866  }
   867  
   868  // pcvalueCacheKey returns the outermost index in a pcvalueCache to use for targetpc.
   869  // It must be very cheap to calculate.
   870  // For now, align to goarch.PtrSize and reduce mod the number of entries.
   871  // In practice, this appears to be fairly randomly and evenly distributed.
   872  func pcvalueCacheKey(targetpc uintptr) uintptr {
   873  	return (targetpc / goarch.PtrSize) % uintptr(len(pcvalueCache{}.entries))
   874  }
   875  
   876  // Returns the PCData value, and the PC where this value starts.
   877  // TODO: the start PC is returned only when cache is nil.
   878  func pcvalue(f funcInfo, off uint32, targetpc uintptr, cache *pcvalueCache, strict bool) (int32, uintptr) {
   879  	if off == 0 {
   880  		return -1, 0
   881  	}
   882  
   883  	// Check the cache. This speeds up walks of deep stacks, which
   884  	// tend to have the same recursive functions over and over.
   885  	//
   886  	// This cache is small enough that full associativity is
   887  	// cheaper than doing the hashing for a less associative
   888  	// cache.
   889  	if cache != nil {
   890  		x := pcvalueCacheKey(targetpc)
   891  		for i := range cache.entries[x] {
   892  			// We check off first because we're more
   893  			// likely to have multiple entries with
   894  			// different offsets for the same targetpc
   895  			// than the other way around, so we'll usually
   896  			// fail in the first clause.
   897  			ent := &cache.entries[x][i]
   898  			if ent.off == off && ent.targetpc == targetpc {
   899  				return ent.val, 0
   900  			}
   901  		}
   902  	}
   903  
   904  	if !f.valid() {
   905  		if strict && panicking == 0 {
   906  			println("runtime: no module data for", hex(f.entry()))
   907  			throw("no module data")
   908  		}
   909  		return -1, 0
   910  	}
   911  	datap := f.datap
   912  	p := datap.pctab[off:]
   913  	pc := f.entry()
   914  	prevpc := pc
   915  	val := int32(-1)
   916  	for {
   917  		var ok bool
   918  		p, ok = step(p, &pc, &val, pc == f.entry())
   919  		if !ok {
   920  			break
   921  		}
   922  		if targetpc < pc {
   923  			// Replace a random entry in the cache. Random
   924  			// replacement prevents a performance cliff if
   925  			// a recursive stack's cycle is slightly
   926  			// larger than the cache.
   927  			// Put the new element at the beginning,
   928  			// since it is the most likely to be newly used.
   929  			if cache != nil {
   930  				x := pcvalueCacheKey(targetpc)
   931  				e := &cache.entries[x]
   932  				ci := fastrandn(uint32(len(cache.entries[x])))
   933  				e[ci] = e[0]
   934  				e[0] = pcvalueCacheEnt{
   935  					targetpc: targetpc,
   936  					off:      off,
   937  					val:      val,
   938  				}
   939  			}
   940  
   941  			return val, prevpc
   942  		}
   943  		prevpc = pc
   944  	}
   945  
   946  	// If there was a table, it should have covered all program counters.
   947  	// If not, something is wrong.
   948  	if panicking != 0 || !strict {
   949  		return -1, 0
   950  	}
   951  
   952  	print("runtime: invalid pc-encoded table f=", funcname(f), " pc=", hex(pc), " targetpc=", hex(targetpc), " tab=", p, "\n")
   953  
   954  	p = datap.pctab[off:]
   955  	pc = f.entry()
   956  	val = -1
   957  	for {
   958  		var ok bool
   959  		p, ok = step(p, &pc, &val, pc == f.entry())
   960  		if !ok {
   961  			break
   962  		}
   963  		print("\tvalue=", val, " until pc=", hex(pc), "\n")
   964  	}
   965  
   966  	throw("invalid runtime symbol table")
   967  	return -1, 0
   968  }
   969  
   970  func cfuncname(f funcInfo) *byte {
   971  	if !f.valid() || f.nameoff == 0 {
   972  		return nil
   973  	}
   974  	return &f.datap.funcnametab[f.nameoff]
   975  }
   976  
   977  func funcname(f funcInfo) string {
   978  	return gostringnocopy(cfuncname(f))
   979  }
   980  
   981  func funcpkgpath(f funcInfo) string {
   982  	name := funcname(f)
   983  	i := len(name) - 1
   984  	for ; i > 0; i-- {
   985  		if name[i] == '/' {
   986  			break
   987  		}
   988  	}
   989  	for ; i < len(name); i++ {
   990  		if name[i] == '.' {
   991  			break
   992  		}
   993  	}
   994  	return name[:i]
   995  }
   996  
   997  func cfuncnameFromNameoff(f funcInfo, nameoff int32) *byte {
   998  	if !f.valid() {
   999  		return nil
  1000  	}
  1001  	return &f.datap.funcnametab[nameoff]
  1002  }
  1003  
  1004  func funcnameFromNameoff(f funcInfo, nameoff int32) string {
  1005  	return gostringnocopy(cfuncnameFromNameoff(f, nameoff))
  1006  }
  1007  
  1008  func funcfile(f funcInfo, fileno int32) string {
  1009  	datap := f.datap
  1010  	if !f.valid() {
  1011  		return "?"
  1012  	}
  1013  	// Make sure the cu index and file offset are valid
  1014  	if fileoff := datap.cutab[f.cuOffset+uint32(fileno)]; fileoff != ^uint32(0) {
  1015  		return gostringnocopy(&datap.filetab[fileoff])
  1016  	}
  1017  	// pcln section is corrupt.
  1018  	return "?"
  1019  }
  1020  
  1021  func funcline1(f funcInfo, targetpc uintptr, strict bool) (file string, line int32) {
  1022  	datap := f.datap
  1023  	if !f.valid() {
  1024  		return "?", 0
  1025  	}
  1026  	fileno, _ := pcvalue(f, f.pcfile, targetpc, nil, strict)
  1027  	line, _ = pcvalue(f, f.pcln, targetpc, nil, strict)
  1028  	if fileno == -1 || line == -1 || int(fileno) >= len(datap.filetab) {
  1029  		// print("looking for ", hex(targetpc), " in ", funcname(f), " got file=", fileno, " line=", lineno, "\n")
  1030  		return "?", 0
  1031  	}
  1032  	file = funcfile(f, fileno)
  1033  	return
  1034  }
  1035  
  1036  func funcline(f funcInfo, targetpc uintptr) (file string, line int32) {
  1037  	return funcline1(f, targetpc, true)
  1038  }
  1039  
  1040  func funcspdelta(f funcInfo, targetpc uintptr, cache *pcvalueCache) int32 {
  1041  	x, _ := pcvalue(f, f.pcsp, targetpc, cache, true)
  1042  	if debugPcln && x&(goarch.PtrSize-1) != 0 {
  1043  		print("invalid spdelta ", funcname(f), " ", hex(f.entry()), " ", hex(targetpc), " ", hex(f.pcsp), " ", x, "\n")
  1044  		throw("bad spdelta")
  1045  	}
  1046  	return x
  1047  }
  1048  
  1049  // funcMaxSPDelta returns the maximum spdelta at any point in f.
  1050  func funcMaxSPDelta(f funcInfo) int32 {
  1051  	datap := f.datap
  1052  	p := datap.pctab[f.pcsp:]
  1053  	pc := f.entry()
  1054  	val := int32(-1)
  1055  	max := int32(0)
  1056  	for {
  1057  		var ok bool
  1058  		p, ok = step(p, &pc, &val, pc == f.entry())
  1059  		if !ok {
  1060  			return max
  1061  		}
  1062  		if val > max {
  1063  			max = val
  1064  		}
  1065  	}
  1066  }
  1067  
  1068  func pcdatastart(f funcInfo, table uint32) uint32 {
  1069  	return *(*uint32)(add(unsafe.Pointer(&f.nfuncdata), unsafe.Sizeof(f.nfuncdata)+uintptr(table)*4))
  1070  }
  1071  
  1072  func pcdatavalue(f funcInfo, table uint32, targetpc uintptr, cache *pcvalueCache) int32 {
  1073  	if table >= f.npcdata {
  1074  		return -1
  1075  	}
  1076  	r, _ := pcvalue(f, pcdatastart(f, table), targetpc, cache, true)
  1077  	return r
  1078  }
  1079  
  1080  func pcdatavalue1(f funcInfo, table uint32, targetpc uintptr, cache *pcvalueCache, strict bool) int32 {
  1081  	if table >= f.npcdata {
  1082  		return -1
  1083  	}
  1084  	r, _ := pcvalue(f, pcdatastart(f, table), targetpc, cache, strict)
  1085  	return r
  1086  }
  1087  
  1088  // Like pcdatavalue, but also return the start PC of this PCData value.
  1089  // It doesn't take a cache.
  1090  func pcdatavalue2(f funcInfo, table uint32, targetpc uintptr) (int32, uintptr) {
  1091  	if table >= f.npcdata {
  1092  		return -1, 0
  1093  	}
  1094  	return pcvalue(f, pcdatastart(f, table), targetpc, nil, true)
  1095  }
  1096  
  1097  // funcdata returns a pointer to the ith funcdata for f.
  1098  // funcdata should be kept in sync with cmd/link:writeFuncs.
  1099  func funcdata(f funcInfo, i uint8) unsafe.Pointer {
  1100  	if i < 0 || i >= f.nfuncdata {
  1101  		return nil
  1102  	}
  1103  	base := f.datap.gofunc // load gofunc address early so that we calculate during cache misses
  1104  	p := uintptr(unsafe.Pointer(&f.nfuncdata)) + unsafe.Sizeof(f.nfuncdata) + uintptr(f.npcdata)*4 + uintptr(i)*4
  1105  	off := *(*uint32)(unsafe.Pointer(p))
  1106  	// Return off == ^uint32(0) ? 0 : f.datap.gofunc + uintptr(off), but without branches.
  1107  	// The compiler calculates mask on most architectures using conditional assignment.
  1108  	var mask uintptr
  1109  	if off == ^uint32(0) {
  1110  		mask = 1
  1111  	}
  1112  	mask--
  1113  	raw := base + uintptr(off)
  1114  	return unsafe.Pointer(raw & mask)
  1115  }
  1116  
  1117  // step advances to the next pc, value pair in the encoded table.
  1118  func step(p []byte, pc *uintptr, val *int32, first bool) (newp []byte, ok bool) {
  1119  	// For both uvdelta and pcdelta, the common case (~70%)
  1120  	// is that they are a single byte. If so, avoid calling readvarint.
  1121  	uvdelta := uint32(p[0])
  1122  	if uvdelta == 0 && !first {
  1123  		return nil, false
  1124  	}
  1125  	n := uint32(1)
  1126  	if uvdelta&0x80 != 0 {
  1127  		n, uvdelta = readvarint(p)
  1128  	}
  1129  	*val += int32(-(uvdelta & 1) ^ (uvdelta >> 1))
  1130  	p = p[n:]
  1131  
  1132  	pcdelta := uint32(p[0])
  1133  	n = 1
  1134  	if pcdelta&0x80 != 0 {
  1135  		n, pcdelta = readvarint(p)
  1136  	}
  1137  	p = p[n:]
  1138  	*pc += uintptr(pcdelta * sys.PCQuantum)
  1139  	return p, true
  1140  }
  1141  
  1142  // readvarint reads a varint from p.
  1143  func readvarint(p []byte) (read uint32, val uint32) {
  1144  	var v, shift, n uint32
  1145  	for {
  1146  		b := p[n]
  1147  		n++
  1148  		v |= uint32(b&0x7F) << (shift & 31)
  1149  		if b&0x80 == 0 {
  1150  			break
  1151  		}
  1152  		shift += 7
  1153  	}
  1154  	return n, v
  1155  }
  1156  
  1157  type stackmap struct {
  1158  	n        int32   // number of bitmaps
  1159  	nbit     int32   // number of bits in each bitmap
  1160  	bytedata [1]byte // bitmaps, each starting on a byte boundary
  1161  }
  1162  
  1163  //go:nowritebarrier
  1164  func stackmapdata(stkmap *stackmap, n int32) bitvector {
  1165  	// Check this invariant only when stackDebug is on at all.
  1166  	// The invariant is already checked by many of stackmapdata's callers,
  1167  	// and disabling it by default allows stackmapdata to be inlined.
  1168  	if stackDebug > 0 && (n < 0 || n >= stkmap.n) {
  1169  		throw("stackmapdata: index out of range")
  1170  	}
  1171  	return bitvector{stkmap.nbit, addb(&stkmap.bytedata[0], uintptr(n*((stkmap.nbit+7)>>3)))}
  1172  }
  1173  
  1174  // inlinedCall is the encoding of entries in the FUNCDATA_InlTree table.
  1175  type inlinedCall struct {
  1176  	parent   int16  // index of parent in the inltree, or < 0
  1177  	funcID   funcID // type of the called function
  1178  	_        byte
  1179  	file     int32 // perCU file index for inlined call. See cmd/link:pcln.go
  1180  	line     int32 // line number of the call site
  1181  	func_    int32 // offset into pclntab for name of called function
  1182  	parentPc int32 // position of an instruction whose source position is the call site (offset from entry)
  1183  }
  1184  

View as plain text