...

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

View as plain text