Source file src/runtime/symtab.go

Documentation: runtime

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

View as plain text