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

View as plain text