github.com/fenixara/go@v0.0.0-20170127160404-96ea0918e670/src/runtime/symtab.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package runtime
     6  
     7  import (
     8  	"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 []uintptr
    17  
    18  	// If previous caller in iteration was a panic, then
    19  	// ci.callers[0] is the address of the faulting instruction
    20  	// instead of the return address of the call.
    21  	wasPanic bool
    22  
    23  	// Frames to return for subsequent calls to the Next method.
    24  	// Used for non-Go frames.
    25  	frames *[]Frame
    26  }
    27  
    28  // Frame is the information returned by Frames for each call frame.
    29  type Frame struct {
    30  	// Program counter for this frame; multiple frames may have
    31  	// the same PC value.
    32  	PC uintptr
    33  
    34  	// Func for this frame; may be nil for non-Go code or fully
    35  	// inlined functions.
    36  	Func *Func
    37  
    38  	// Function name, file name, and line number for this call frame.
    39  	// May be the empty string or zero if not known.
    40  	// If Func is not nil then Function == Func.Name().
    41  	Function string
    42  	File     string
    43  	Line     int
    44  
    45  	// Entry point for the function; may be zero if not known.
    46  	// If Func is not nil then Entry == Func.Entry().
    47  	Entry uintptr
    48  }
    49  
    50  // CallersFrames takes a slice of PC values returned by Callers and
    51  // prepares to return function/file/line information.
    52  // Do not change the slice until you are done with the Frames.
    53  func CallersFrames(callers []uintptr) *Frames {
    54  	return &Frames{callers: callers}
    55  }
    56  
    57  // Next returns frame information for the next caller.
    58  // If more is false, there are no more callers (the Frame value is valid).
    59  func (ci *Frames) Next() (frame Frame, more bool) {
    60  	if ci.frames != nil {
    61  		// We have saved up frames to return.
    62  		f := (*ci.frames)[0]
    63  		if len(*ci.frames) == 1 {
    64  			ci.frames = nil
    65  		} else {
    66  			*ci.frames = (*ci.frames)[1:]
    67  		}
    68  		return f, ci.frames != nil || len(ci.callers) > 0
    69  	}
    70  
    71  	if len(ci.callers) == 0 {
    72  		ci.wasPanic = false
    73  		return Frame{}, false
    74  	}
    75  	pc := ci.callers[0]
    76  	ci.callers = ci.callers[1:]
    77  	more = len(ci.callers) > 0
    78  	f := FuncForPC(pc)
    79  	if f == nil {
    80  		ci.wasPanic = false
    81  		if cgoSymbolizer != nil {
    82  			return ci.cgoNext(pc, more)
    83  		}
    84  		return Frame{}, more
    85  	}
    86  
    87  	entry := f.Entry()
    88  	xpc := pc
    89  	if xpc > entry && !ci.wasPanic {
    90  		xpc--
    91  	}
    92  	file, line := f.FileLine(xpc)
    93  
    94  	function := f.Name()
    95  	ci.wasPanic = entry == sigpanicPC
    96  
    97  	frame = Frame{
    98  		PC:       xpc,
    99  		Func:     f,
   100  		Function: function,
   101  		File:     file,
   102  		Line:     line,
   103  		Entry:    entry,
   104  	}
   105  
   106  	return frame, more
   107  }
   108  
   109  // cgoNext returns frame information for pc, known to be a non-Go function,
   110  // using the cgoSymbolizer hook.
   111  func (ci *Frames) cgoNext(pc uintptr, more bool) (Frame, bool) {
   112  	arg := cgoSymbolizerArg{pc: pc}
   113  	callCgoSymbolizer(&arg)
   114  
   115  	if arg.file == nil && arg.funcName == nil {
   116  		// No useful information from symbolizer.
   117  		return Frame{}, more
   118  	}
   119  
   120  	var frames []Frame
   121  	for {
   122  		frames = append(frames, Frame{
   123  			PC:       pc,
   124  			Func:     nil,
   125  			Function: gostring(arg.funcName),
   126  			File:     gostring(arg.file),
   127  			Line:     int(arg.lineno),
   128  			Entry:    arg.entry,
   129  		})
   130  		if arg.more == 0 {
   131  			break
   132  		}
   133  		callCgoSymbolizer(&arg)
   134  	}
   135  
   136  	// No more frames for this PC. Tell the symbolizer we are done.
   137  	// We don't try to maintain a single cgoSymbolizerArg for the
   138  	// whole use of Frames, because there would be no good way to tell
   139  	// the symbolizer when we are done.
   140  	arg.pc = 0
   141  	callCgoSymbolizer(&arg)
   142  
   143  	if len(frames) == 1 {
   144  		// Return a single frame.
   145  		return frames[0], more
   146  	}
   147  
   148  	// Return the first frame we saw and store the rest to be
   149  	// returned by later calls to Next.
   150  	rf := frames[0]
   151  	frames = frames[1:]
   152  	ci.frames = new([]Frame)
   153  	*ci.frames = frames
   154  	return rf, true
   155  }
   156  
   157  // NOTE: Func does not expose the actual unexported fields, because we return *Func
   158  // values to users, and we want to keep them from being able to overwrite the data
   159  // with (say) *f = Func{}.
   160  // All code operating on a *Func must call raw to get the *_func instead.
   161  
   162  // A Func represents a Go function in the running binary.
   163  type Func struct {
   164  	opaque struct{} // unexported field to disallow conversions
   165  }
   166  
   167  func (f *Func) raw() *_func {
   168  	return (*_func)(unsafe.Pointer(f))
   169  }
   170  
   171  // funcdata.h
   172  const (
   173  	_PCDATA_StackMapIndex       = 0
   174  	_FUNCDATA_ArgsPointerMaps   = 0
   175  	_FUNCDATA_LocalsPointerMaps = 1
   176  	_ArgsSizeUnknown            = -0x80000000
   177  )
   178  
   179  // moduledata records information about the layout of the executable
   180  // image. It is written by the linker. Any changes here must be
   181  // matched changes to the code in cmd/internal/ld/symtab.go:symtab.
   182  // moduledata is stored in read-only memory; none of the pointers here
   183  // are visible to the garbage collector.
   184  type moduledata struct {
   185  	pclntable    []byte
   186  	ftab         []functab
   187  	filetab      []uint32
   188  	findfunctab  uintptr
   189  	minpc, maxpc uintptr
   190  
   191  	text, etext           uintptr
   192  	noptrdata, enoptrdata uintptr
   193  	data, edata           uintptr
   194  	bss, ebss             uintptr
   195  	noptrbss, enoptrbss   uintptr
   196  	end, gcdata, gcbss    uintptr
   197  	types, etypes         uintptr
   198  
   199  	textsectmap []textsect
   200  	typelinks   []int32 // offsets from types
   201  	itablinks   []*itab
   202  
   203  	ptab []ptabEntry
   204  
   205  	pluginpath string
   206  	pkghashes  []modulehash
   207  
   208  	modulename   string
   209  	modulehashes []modulehash
   210  
   211  	gcdatamask, gcbssmask bitvector
   212  
   213  	typemap map[typeOff]*_type // offset to *_rtype in previous module
   214  
   215  	next *moduledata
   216  }
   217  
   218  // A modulehash is used to compare the ABI of a new module or a
   219  // package in a new module with the loaded program.
   220  //
   221  // For each shared library a module links against, the linker creates an entry in the
   222  // moduledata.modulehashes slice containing the name of the module, the abi hash seen
   223  // at link time and a pointer to the runtime abi hash. These are checked in
   224  // moduledataverify1 below.
   225  //
   226  // For each loaded plugin, the the pkghashes slice has a modulehash of the
   227  // newly loaded package that can be used to check the plugin's version of
   228  // a package against any previously loaded version of the package.
   229  // This is done in plugin.lastmoduleinit.
   230  type modulehash struct {
   231  	modulename   string
   232  	linktimehash string
   233  	runtimehash  *string
   234  }
   235  
   236  // pinnedTypemaps are the map[typeOff]*_type from the moduledata objects.
   237  //
   238  // These typemap objects are allocated at run time on the heap, but the
   239  // only direct reference to them is in the moduledata, created by the
   240  // linker and marked SNOPTRDATA so it is ignored by the GC.
   241  //
   242  // To make sure the map isn't collected, we keep a second reference here.
   243  var pinnedTypemaps []map[typeOff]*_type
   244  
   245  var firstmoduledata moduledata  // linker symbol
   246  var lastmoduledatap *moduledata // linker symbol
   247  var modulesSlice unsafe.Pointer // see activeModules
   248  
   249  // activeModules returns a slice of active modules.
   250  //
   251  // A module is active once its gcdatamask and gcbssmask have been
   252  // assembled and it is usable by the GC.
   253  func activeModules() []*moduledata {
   254  	p := (*[]*moduledata)(atomic.Loadp(unsafe.Pointer(&modulesSlice)))
   255  	if p == nil {
   256  		return nil
   257  	}
   258  	return *p
   259  }
   260  
   261  // modulesinit creates the active modules slice out of all loaded modules.
   262  //
   263  // When a module is first loaded by the dynamic linker, an .init_array
   264  // function (written by cmd/link) is invoked to call addmoduledata,
   265  // appending to the module to the linked list that starts with
   266  // firstmoduledata.
   267  //
   268  // There are two times this can happen in the lifecycle of a Go
   269  // program. First, if compiled with -linkshared, a number of modules
   270  // built with -buildmode=shared can be loaded at program initialization.
   271  // Second, a Go program can load a module while running that was built
   272  // with -buildmode=plugin.
   273  //
   274  // After loading, this function is called which initializes the
   275  // moduledata so it is usable by the GC and creates a new activeModules
   276  // list.
   277  //
   278  // Only one goroutine may call modulesinit at a time.
   279  func modulesinit() {
   280  	modules := new([]*moduledata)
   281  	for md := &firstmoduledata; md != nil; md = md.next {
   282  		*modules = append(*modules, md)
   283  		if md.gcdatamask == (bitvector{}) {
   284  			md.gcdatamask = progToPointerMask((*byte)(unsafe.Pointer(md.gcdata)), md.edata-md.data)
   285  			md.gcbssmask = progToPointerMask((*byte)(unsafe.Pointer(md.gcbss)), md.ebss-md.bss)
   286  		}
   287  	}
   288  
   289  	// Modules appear in the moduledata linked list in the order they are
   290  	// loaded by the dynamic loader, with one exception: the
   291  	// firstmoduledata itself the module that contains the runtime. This
   292  	// is not always the first module (when using -buildmode=shared, it
   293  	// is typically libstd.so, the second module). The order matters for
   294  	// typelinksinit, so we swap the first module with whatever module
   295  	// contains the main function.
   296  	//
   297  	// See Issue #18729.
   298  	mainText := funcPC(main_main)
   299  	for i, md := range *modules {
   300  		if md.text <= mainText && mainText <= md.etext {
   301  			(*modules)[0] = md
   302  			(*modules)[i] = &firstmoduledata
   303  			break
   304  		}
   305  	}
   306  
   307  	atomicstorep(unsafe.Pointer(&modulesSlice), unsafe.Pointer(modules))
   308  }
   309  
   310  type functab struct {
   311  	entry   uintptr
   312  	funcoff uintptr
   313  }
   314  
   315  // Mapping information for secondary text sections
   316  
   317  type textsect struct {
   318  	vaddr    uintptr // prelinked section vaddr
   319  	length   uintptr // section length
   320  	baseaddr uintptr // relocated section address
   321  }
   322  
   323  const minfunc = 16                 // minimum function size
   324  const pcbucketsize = 256 * minfunc // size of bucket in the pc->func lookup table
   325  
   326  // findfunctab is an array of these structures.
   327  // Each bucket represents 4096 bytes of the text segment.
   328  // Each subbucket represents 256 bytes of the text segment.
   329  // To find a function given a pc, locate the bucket and subbucket for
   330  // that pc. Add together the idx and subbucket value to obtain a
   331  // function index. Then scan the functab array starting at that
   332  // index to find the target function.
   333  // This table uses 20 bytes for every 4096 bytes of code, or ~0.5% overhead.
   334  type findfuncbucket struct {
   335  	idx        uint32
   336  	subbuckets [16]byte
   337  }
   338  
   339  func moduledataverify() {
   340  	for datap := &firstmoduledata; datap != nil; datap = datap.next {
   341  		moduledataverify1(datap)
   342  	}
   343  }
   344  
   345  const debugPcln = false
   346  
   347  func moduledataverify1(datap *moduledata) {
   348  	// See golang.org/s/go12symtab for header: 0xfffffffb,
   349  	// two zero bytes, a byte giving the PC quantum,
   350  	// and a byte giving the pointer width in bytes.
   351  	pcln := *(**[8]byte)(unsafe.Pointer(&datap.pclntable))
   352  	pcln32 := *(**[2]uint32)(unsafe.Pointer(&datap.pclntable))
   353  	if pcln32[0] != 0xfffffffb || pcln[4] != 0 || pcln[5] != 0 || pcln[6] != sys.PCQuantum || pcln[7] != sys.PtrSize {
   354  		println("runtime: function symbol table header:", hex(pcln32[0]), hex(pcln[4]), hex(pcln[5]), hex(pcln[6]), hex(pcln[7]))
   355  		throw("invalid function symbol table\n")
   356  	}
   357  
   358  	// ftab is lookup table for function by program counter.
   359  	nftab := len(datap.ftab) - 1
   360  	var pcCache pcvalueCache
   361  	for i := 0; i < nftab; i++ {
   362  		// NOTE: ftab[nftab].entry is legal; it is the address beyond the final function.
   363  		if datap.ftab[i].entry > datap.ftab[i+1].entry {
   364  			f1 := (*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[i].funcoff]))
   365  			f2 := (*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[i+1].funcoff]))
   366  			f2name := "end"
   367  			if i+1 < nftab {
   368  				f2name = funcname(f2)
   369  			}
   370  			println("function symbol table not sorted by program counter:", hex(datap.ftab[i].entry), funcname(f1), ">", hex(datap.ftab[i+1].entry), f2name)
   371  			for j := 0; j <= i; j++ {
   372  				print("\t", hex(datap.ftab[j].entry), " ", funcname((*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[j].funcoff]))), "\n")
   373  			}
   374  			throw("invalid runtime symbol table")
   375  		}
   376  
   377  		if debugPcln || nftab-i < 5 {
   378  			// Check a PC near but not at the very end.
   379  			// The very end might be just padding that is not covered by the tables.
   380  			// No architecture rounds function entries to more than 16 bytes,
   381  			// but if one came along we'd need to subtract more here.
   382  			// But don't use the next PC if it corresponds to a foreign object chunk
   383  			// (no pcln table, f2.pcln == 0). That chunk might have an alignment
   384  			// more than 16 bytes.
   385  			f := (*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[i].funcoff]))
   386  			end := f.entry
   387  			if i+1 < nftab {
   388  				f2 := (*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[i+1].funcoff]))
   389  				if f2.pcln != 0 {
   390  					end = f2.entry - 16
   391  					if end < f.entry {
   392  						end = f.entry
   393  					}
   394  				}
   395  			}
   396  			pcvalue(f, f.pcfile, end, &pcCache, true)
   397  			pcvalue(f, f.pcln, end, &pcCache, true)
   398  			pcvalue(f, f.pcsp, end, &pcCache, true)
   399  		}
   400  	}
   401  
   402  	if datap.minpc != datap.ftab[0].entry ||
   403  		datap.maxpc != datap.ftab[nftab].entry {
   404  		throw("minpc or maxpc invalid")
   405  	}
   406  
   407  	for _, modulehash := range datap.modulehashes {
   408  		if modulehash.linktimehash != *modulehash.runtimehash {
   409  			println("abi mismatch detected between", datap.modulename, "and", modulehash.modulename)
   410  			throw("abi mismatch")
   411  		}
   412  	}
   413  }
   414  
   415  // FuncForPC returns a *Func describing the function that contains the
   416  // given program counter address, or else nil.
   417  func FuncForPC(pc uintptr) *Func {
   418  	return (*Func)(unsafe.Pointer(findfunc(pc)))
   419  }
   420  
   421  // Name returns the name of the function.
   422  func (f *Func) Name() string {
   423  	return funcname(f.raw())
   424  }
   425  
   426  // Entry returns the entry address of the function.
   427  func (f *Func) Entry() uintptr {
   428  	return f.raw().entry
   429  }
   430  
   431  // FileLine returns the file name and line number of the
   432  // source code corresponding to the program counter pc.
   433  // The result will not be accurate if pc is not a program
   434  // counter within f.
   435  func (f *Func) FileLine(pc uintptr) (file string, line int) {
   436  	// Pass strict=false here, because anyone can call this function,
   437  	// and they might just be wrong about targetpc belonging to f.
   438  	file, line32 := funcline1(f.raw(), pc, false)
   439  	return file, int(line32)
   440  }
   441  
   442  func findmoduledatap(pc uintptr) *moduledata {
   443  	for datap := &firstmoduledata; datap != nil; datap = datap.next {
   444  		if datap.minpc <= pc && pc < datap.maxpc {
   445  			return datap
   446  		}
   447  	}
   448  	return nil
   449  }
   450  
   451  func findfunc(pc uintptr) *_func {
   452  	datap := findmoduledatap(pc)
   453  	if datap == nil {
   454  		return nil
   455  	}
   456  	const nsub = uintptr(len(findfuncbucket{}.subbuckets))
   457  
   458  	x := pc - datap.minpc
   459  	b := x / pcbucketsize
   460  	i := x % pcbucketsize / (pcbucketsize / nsub)
   461  
   462  	ffb := (*findfuncbucket)(add(unsafe.Pointer(datap.findfunctab), b*unsafe.Sizeof(findfuncbucket{})))
   463  	idx := ffb.idx + uint32(ffb.subbuckets[i])
   464  
   465  	// If the idx is beyond the end of the ftab, set it to the end of the table and search backward.
   466  	// This situation can occur if multiple text sections are generated to handle large text sections
   467  	// and the linker has inserted jump tables between them.
   468  
   469  	if idx >= uint32(len(datap.ftab)) {
   470  		idx = uint32(len(datap.ftab) - 1)
   471  	}
   472  	if pc < datap.ftab[idx].entry {
   473  
   474  		// With multiple text sections, the idx might reference a function address that
   475  		// is higher than the pc being searched, so search backward until the matching address is found.
   476  
   477  		for datap.ftab[idx].entry > pc && idx > 0 {
   478  			idx--
   479  		}
   480  		if idx == 0 {
   481  			throw("findfunc: bad findfunctab entry idx")
   482  		}
   483  	} else {
   484  
   485  		// linear search to find func with pc >= entry.
   486  		for datap.ftab[idx+1].entry <= pc {
   487  			idx++
   488  		}
   489  	}
   490  	return (*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[idx].funcoff]))
   491  }
   492  
   493  type pcvalueCache struct {
   494  	entries [16]pcvalueCacheEnt
   495  }
   496  
   497  type pcvalueCacheEnt struct {
   498  	// targetpc and off together are the key of this cache entry.
   499  	targetpc uintptr
   500  	off      int32
   501  	// val is the value of this cached pcvalue entry.
   502  	val int32
   503  }
   504  
   505  func pcvalue(f *_func, off int32, targetpc uintptr, cache *pcvalueCache, strict bool) int32 {
   506  	if off == 0 {
   507  		return -1
   508  	}
   509  
   510  	// Check the cache. This speeds up walks of deep stacks, which
   511  	// tend to have the same recursive functions over and over.
   512  	//
   513  	// This cache is small enough that full associativity is
   514  	// cheaper than doing the hashing for a less associative
   515  	// cache.
   516  	if cache != nil {
   517  		for _, ent := range cache.entries {
   518  			// We check off first because we're more
   519  			// likely to have multiple entries with
   520  			// different offsets for the same targetpc
   521  			// than the other way around, so we'll usually
   522  			// fail in the first clause.
   523  			if ent.off == off && ent.targetpc == targetpc {
   524  				return ent.val
   525  			}
   526  		}
   527  	}
   528  
   529  	datap := findmoduledatap(f.entry) // inefficient
   530  	if datap == nil {
   531  		if strict && panicking == 0 {
   532  			print("runtime: no module data for ", hex(f.entry), "\n")
   533  			throw("no module data")
   534  		}
   535  		return -1
   536  	}
   537  	p := datap.pclntable[off:]
   538  	pc := f.entry
   539  	val := int32(-1)
   540  	for {
   541  		var ok bool
   542  		p, ok = step(p, &pc, &val, pc == f.entry)
   543  		if !ok {
   544  			break
   545  		}
   546  		if targetpc < pc {
   547  			// Replace a random entry in the cache. Random
   548  			// replacement prevents a performance cliff if
   549  			// a recursive stack's cycle is slightly
   550  			// larger than the cache.
   551  			if cache != nil {
   552  				ci := fastrand() % uint32(len(cache.entries))
   553  				cache.entries[ci] = pcvalueCacheEnt{
   554  					targetpc: targetpc,
   555  					off:      off,
   556  					val:      val,
   557  				}
   558  			}
   559  
   560  			return val
   561  		}
   562  	}
   563  
   564  	// If there was a table, it should have covered all program counters.
   565  	// If not, something is wrong.
   566  	if panicking != 0 || !strict {
   567  		return -1
   568  	}
   569  
   570  	print("runtime: invalid pc-encoded table f=", funcname(f), " pc=", hex(pc), " targetpc=", hex(targetpc), " tab=", p, "\n")
   571  
   572  	p = datap.pclntable[off:]
   573  	pc = f.entry
   574  	val = -1
   575  	for {
   576  		var ok bool
   577  		p, ok = step(p, &pc, &val, pc == f.entry)
   578  		if !ok {
   579  			break
   580  		}
   581  		print("\tvalue=", val, " until pc=", hex(pc), "\n")
   582  	}
   583  
   584  	throw("invalid runtime symbol table")
   585  	return -1
   586  }
   587  
   588  func cfuncname(f *_func) *byte {
   589  	if f == nil || f.nameoff == 0 {
   590  		return nil
   591  	}
   592  	datap := findmoduledatap(f.entry) // inefficient
   593  	if datap == nil {
   594  		return nil
   595  	}
   596  	return &datap.pclntable[f.nameoff]
   597  }
   598  
   599  func funcname(f *_func) string {
   600  	return gostringnocopy(cfuncname(f))
   601  }
   602  
   603  func funcline1(f *_func, targetpc uintptr, strict bool) (file string, line int32) {
   604  	datap := findmoduledatap(f.entry) // inefficient
   605  	if datap == nil {
   606  		return "?", 0
   607  	}
   608  	fileno := int(pcvalue(f, f.pcfile, targetpc, nil, strict))
   609  	line = pcvalue(f, f.pcln, targetpc, nil, strict)
   610  	if fileno == -1 || line == -1 || fileno >= len(datap.filetab) {
   611  		// print("looking for ", hex(targetpc), " in ", funcname(f), " got file=", fileno, " line=", lineno, "\n")
   612  		return "?", 0
   613  	}
   614  	file = gostringnocopy(&datap.pclntable[datap.filetab[fileno]])
   615  	return
   616  }
   617  
   618  func funcline(f *_func, targetpc uintptr) (file string, line int32) {
   619  	return funcline1(f, targetpc, true)
   620  }
   621  
   622  func funcspdelta(f *_func, targetpc uintptr, cache *pcvalueCache) int32 {
   623  	x := pcvalue(f, f.pcsp, targetpc, cache, true)
   624  	if x&(sys.PtrSize-1) != 0 {
   625  		print("invalid spdelta ", funcname(f), " ", hex(f.entry), " ", hex(targetpc), " ", hex(f.pcsp), " ", x, "\n")
   626  	}
   627  	return x
   628  }
   629  
   630  func pcdatavalue(f *_func, table int32, targetpc uintptr, cache *pcvalueCache) int32 {
   631  	if table < 0 || table >= f.npcdata {
   632  		return -1
   633  	}
   634  	off := *(*int32)(add(unsafe.Pointer(&f.nfuncdata), unsafe.Sizeof(f.nfuncdata)+uintptr(table)*4))
   635  	return pcvalue(f, off, targetpc, cache, true)
   636  }
   637  
   638  func funcdata(f *_func, i int32) unsafe.Pointer {
   639  	if i < 0 || i >= f.nfuncdata {
   640  		return nil
   641  	}
   642  	p := add(unsafe.Pointer(&f.nfuncdata), unsafe.Sizeof(f.nfuncdata)+uintptr(f.npcdata)*4)
   643  	if sys.PtrSize == 8 && uintptr(p)&4 != 0 {
   644  		if uintptr(unsafe.Pointer(f))&4 != 0 {
   645  			println("runtime: misaligned func", f)
   646  		}
   647  		p = add(p, 4)
   648  	}
   649  	return *(*unsafe.Pointer)(add(p, uintptr(i)*sys.PtrSize))
   650  }
   651  
   652  // step advances to the next pc, value pair in the encoded table.
   653  func step(p []byte, pc *uintptr, val *int32, first bool) (newp []byte, ok bool) {
   654  	p, uvdelta := readvarint(p)
   655  	if uvdelta == 0 && !first {
   656  		return nil, false
   657  	}
   658  	if uvdelta&1 != 0 {
   659  		uvdelta = ^(uvdelta >> 1)
   660  	} else {
   661  		uvdelta >>= 1
   662  	}
   663  	vdelta := int32(uvdelta)
   664  	p, pcdelta := readvarint(p)
   665  	*pc += uintptr(pcdelta * sys.PCQuantum)
   666  	*val += vdelta
   667  	return p, true
   668  }
   669  
   670  // readvarint reads a varint from p.
   671  func readvarint(p []byte) (newp []byte, val uint32) {
   672  	var v, shift uint32
   673  	for {
   674  		b := p[0]
   675  		p = p[1:]
   676  		v |= (uint32(b) & 0x7F) << shift
   677  		if b&0x80 == 0 {
   678  			break
   679  		}
   680  		shift += 7
   681  	}
   682  	return p, v
   683  }
   684  
   685  type stackmap struct {
   686  	n        int32   // number of bitmaps
   687  	nbit     int32   // number of bits in each bitmap
   688  	bytedata [1]byte // bitmaps, each starting on a byte boundary
   689  }
   690  
   691  //go:nowritebarrier
   692  func stackmapdata(stkmap *stackmap, n int32) bitvector {
   693  	if n < 0 || n >= stkmap.n {
   694  		throw("stackmapdata: index out of range")
   695  	}
   696  	return bitvector{stkmap.nbit, (*byte)(add(unsafe.Pointer(&stkmap.bytedata), uintptr(n*((stkmap.nbit+7)/8))))}
   697  }