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
5package runtime
6
7import (
8	"internal/abi"
9	"internal/goarch"
10	"internal/runtime/atomic"
11	"runtime/internal/sys"
12	"unsafe"
13)
14
15// Frames may be used to get function/file/line information for a
16// slice of PC values returned by [Callers].
17type Frames struct {
18	// callers is a slice of PCs that have not yet been expanded to frames.
19	callers []uintptr
20
21	// nextPC is a next PC to expand ahead of processing callers.
22	nextPC uintptr
23
24	// frames is a slice of Frames that have yet to be returned.
25	frames     []Frame
26	frameStore [2]Frame
27}
28
29// Frame is the information returned by [Frames] for each call frame.
30type Frame struct {
31	// PC is the program counter for the location in this frame.
32	// For a frame that calls another frame, this will be the
33	// program counter of a call instruction. Because of inlining,
34	// multiple frames may have the same PC value, but different
35	// symbolic information.
36	PC uintptr
37
38	// Func is the Func value of this call frame. This may be nil
39	// for non-Go code or fully inlined functions.
40	Func *Func
41
42	// Function is the package path-qualified function name of
43	// this call frame. If non-empty, this string uniquely
44	// identifies a single function in the program.
45	// This may be the empty string if not known.
46	// If Func is not nil then Function == Func.Name().
47	Function string
48
49	// File and Line are the file name and line number of the
50	// location in this frame. For non-leaf frames, this will be
51	// the location of a call. These may be the empty string and
52	// zero, respectively, if not known.
53	File string
54	Line int
55
56	// startLine is the line number of the beginning of the function in
57	// this frame. Specifically, it is the line number of the func keyword
58	// for Go functions. Note that //line directives can change the
59	// filename and/or line number arbitrarily within a function, meaning
60	// that the Line - startLine offset is not always meaningful.
61	//
62	// This may be zero if not known.
63	startLine int
64
65	// Entry point program counter for the function; may be zero
66	// if not known. If Func is not nil then Entry ==
67	// Func.Entry().
68	Entry uintptr
69
70	// The runtime's internal view of the function. This field
71	// is set (funcInfo.valid() returns true) only for Go functions,
72	// not for C functions.
73	funcInfo funcInfo
74}
75
76// CallersFrames takes a slice of PC values returned by [Callers] and
77// prepares to return function/file/line information.
78// Do not change the slice until you are done with the [Frames].
79func CallersFrames(callers []uintptr) *Frames {
80	f := &Frames{callers: callers}
81	f.frames = f.frameStore[:0]
82	return f
83}
84
85// Next returns a [Frame] representing the next call frame in the slice
86// of PC values. If it has already returned all call frames, Next
87// returns a zero [Frame].
88//
89// The more result indicates whether the next call to Next will return
90// a valid [Frame]. It does not necessarily indicate whether this call
91// returned one.
92//
93// See the [Frames] example for idiomatic usage.
94func (ci *Frames) Next() (frame Frame, more bool) {
95	for len(ci.frames) < 2 {
96		// Find the next frame.
97		// We need to look for 2 frames so we know what
98		// to return for the "more" result.
99		if len(ci.callers) == 0 {
100			break
101		}
102		var pc uintptr
103		if ci.nextPC != 0 {
104			pc, ci.nextPC = ci.nextPC, 0
105		} else {
106			pc, ci.callers = ci.callers[0], ci.callers[1:]
107		}
108		funcInfo := findfunc(pc)
109		if !funcInfo.valid() {
110			if cgoSymbolizer != nil {
111				// Pre-expand cgo frames. We could do this
112				// incrementally, too, but there's no way to
113				// avoid allocation in this case anyway.
114				ci.frames = append(ci.frames, expandCgoFrames(pc)...)
115			}
116			continue
117		}
118		f := funcInfo._Func()
119		entry := f.Entry()
120		if pc > entry {
121			// We store the pc of the start of the instruction following
122			// the instruction in question (the call or the inline mark).
123			// This is done for historical reasons, and to make FuncForPC
124			// work correctly for entries in the result of runtime.Callers.
125			pc--
126		}
127		// It's important that interpret pc non-strictly as cgoTraceback may
128		// have added bogus PCs with a valid funcInfo but invalid PCDATA.
129		u, uf := newInlineUnwinder(funcInfo, pc)
130		sf := u.srcFunc(uf)
131		if u.isInlined(uf) {
132			// Note: entry is not modified. It always refers to a real frame, not an inlined one.
133			// File/line from funcline1 below are already correct.
134			f = nil
135
136			// When CallersFrame is invoked using the PC list returned by Callers,
137			// the PC list includes virtual PCs corresponding to each outer frame
138			// around an innermost real inlined PC.
139			// We also want to support code passing in a PC list extracted from a
140			// stack trace, and there only the real PCs are printed, not the virtual ones.
141			// So check to see if the implied virtual PC for this PC (obtained from the
142			// unwinder itself) is the next PC in ci.callers. If not, insert it.
143			// The +1 here correspond to the pc-- above: the output of Callers
144			// and therefore the input to CallersFrames is return PCs from the stack;
145			// The pc-- backs up into the CALL instruction (not the first byte of the CALL
146			// instruction, but good enough to find it nonetheless).
147			// There are no cycles in implied virtual PCs (some number of frames were
148			// inlined, but that number is finite), so this unpacking cannot cause an infinite loop.
149			for unext := u.next(uf); unext.valid() && len(ci.callers) > 0 && ci.callers[0] != unext.pc+1; unext = u.next(unext) {
150				snext := u.srcFunc(unext)
151				if snext.funcID == abi.FuncIDWrapper && elideWrapperCalling(sf.funcID) {
152					// Skip, because tracebackPCs (inside runtime.Callers) would too.
153					continue
154				}
155				ci.nextPC = unext.pc + 1
156				break
157			}
158		}
159		ci.frames = append(ci.frames, Frame{
160			PC:        pc,
161			Func:      f,
162			Function:  funcNameForPrint(sf.name()),
163			Entry:     entry,
164			startLine: int(sf.startLine),
165			funcInfo:  funcInfo,
166			// Note: File,Line set below
167		})
168	}
169
170	// Pop one frame from the frame list. Keep the rest.
171	// Avoid allocation in the common case, which is 1 or 2 frames.
172	switch len(ci.frames) {
173	case 0: // In the rare case when there are no frames at all, we return Frame{}.
174		return
175	case 1:
176		frame = ci.frames[0]
177		ci.frames = ci.frameStore[:0]
178	case 2:
179		frame = ci.frames[0]
180		ci.frameStore[0] = ci.frames[1]
181		ci.frames = ci.frameStore[:1]
182	default:
183		frame = ci.frames[0]
184		ci.frames = ci.frames[1:]
185	}
186	more = len(ci.frames) > 0
187	if frame.funcInfo.valid() {
188		// Compute file/line just before we need to return it,
189		// as it can be expensive. This avoids computing file/line
190		// for the Frame we find but don't return. See issue 32093.
191		file, line := funcline1(frame.funcInfo, frame.PC, false)
192		frame.File, frame.Line = file, int(line)
193	}
194	return
195}
196
197// runtime_FrameStartLine returns the start line of the function in a Frame.
198//
199// runtime_FrameStartLine should be an internal detail,
200// but widely used packages access it using linkname.
201// Notable members of the hall of shame include:
202//   - github.com/grafana/pyroscope-go/godeltaprof
203//
204// Do not remove or change the type signature.
205// See go.dev/issue/67401.
206//
207//go:linkname runtime_FrameStartLine runtime/pprof.runtime_FrameStartLine
208func runtime_FrameStartLine(f *Frame) int {
209	return f.startLine
210}
211
212// runtime_FrameSymbolName returns the full symbol name of the function in a Frame.
213// For generic functions this differs from f.Function in that this doesn't replace
214// the shape name to "...".
215//
216// runtime_FrameSymbolName should be an internal detail,
217// but widely used packages access it using linkname.
218// Notable members of the hall of shame include:
219//   - github.com/grafana/pyroscope-go/godeltaprof
220//
221// Do not remove or change the type signature.
222// See go.dev/issue/67401.
223//
224//go:linkname runtime_FrameSymbolName runtime/pprof.runtime_FrameSymbolName
225func runtime_FrameSymbolName(f *Frame) string {
226	if !f.funcInfo.valid() {
227		return f.Function
228	}
229	u, uf := newInlineUnwinder(f.funcInfo, f.PC)
230	sf := u.srcFunc(uf)
231	return sf.name()
232}
233
234// runtime_expandFinalInlineFrame expands the final pc in stk to include all
235// "callers" if pc is inline.
236//
237// runtime_expandFinalInlineFrame should be an internal detail,
238// but widely used packages access it using linkname.
239// Notable members of the hall of shame include:
240//   - github.com/grafana/pyroscope-go/godeltaprof
241//   - github.com/pyroscope-io/godeltaprof
242//
243// Do not remove or change the type signature.
244// See go.dev/issue/67401.
245//
246//go:linkname runtime_expandFinalInlineFrame runtime/pprof.runtime_expandFinalInlineFrame
247func runtime_expandFinalInlineFrame(stk []uintptr) []uintptr {
248	// TODO: It would be more efficient to report only physical PCs to pprof and
249	// just expand the whole stack.
250	if len(stk) == 0 {
251		return stk
252	}
253	pc := stk[len(stk)-1]
254	tracepc := pc - 1
255
256	f := findfunc(tracepc)
257	if !f.valid() {
258		// Not a Go function.
259		return stk
260	}
261
262	u, uf := newInlineUnwinder(f, tracepc)
263	if !u.isInlined(uf) {
264		// Nothing inline at tracepc.
265		return stk
266	}
267
268	// Treat the previous func as normal. We haven't actually checked, but
269	// since this pc was included in the stack, we know it shouldn't be
270	// elided.
271	calleeID := abi.FuncIDNormal
272
273	// Remove pc from stk; we'll re-add it below.
274	stk = stk[:len(stk)-1]
275
276	for ; uf.valid(); uf = u.next(uf) {
277		funcID := u.srcFunc(uf).funcID
278		if funcID == abi.FuncIDWrapper && elideWrapperCalling(calleeID) {
279			// ignore wrappers
280		} else {
281			stk = append(stk, uf.pc+1)
282		}
283		calleeID = funcID
284	}
285
286	return stk
287}
288
289// expandCgoFrames expands frame information for pc, known to be
290// a non-Go function, using the cgoSymbolizer hook. expandCgoFrames
291// returns nil if pc could not be expanded.
292func expandCgoFrames(pc uintptr) []Frame {
293	arg := cgoSymbolizerArg{pc: pc}
294	callCgoSymbolizer(&arg)
295
296	if arg.file == nil && arg.funcName == nil {
297		// No useful information from symbolizer.
298		return nil
299	}
300
301	var frames []Frame
302	for {
303		frames = append(frames, Frame{
304			PC:       pc,
305			Func:     nil,
306			Function: gostring(arg.funcName),
307			File:     gostring(arg.file),
308			Line:     int(arg.lineno),
309			Entry:    arg.entry,
310			// funcInfo is zero, which implies !funcInfo.valid().
311			// That ensures that we use the File/Line info given here.
312		})
313		if arg.more == 0 {
314			break
315		}
316		callCgoSymbolizer(&arg)
317	}
318
319	// No more frames for this PC. Tell the symbolizer we are done.
320	// We don't try to maintain a single cgoSymbolizerArg for the
321	// whole use of Frames, because there would be no good way to tell
322	// the symbolizer when we are done.
323	arg.pc = 0
324	callCgoSymbolizer(&arg)
325
326	return frames
327}
328
329// NOTE: Func does not expose the actual unexported fields, because we return *Func
330// values to users, and we want to keep them from being able to overwrite the data
331// with (say) *f = Func{}.
332// All code operating on a *Func must call raw() to get the *_func
333// or funcInfo() to get the funcInfo instead.
334
335// A Func represents a Go function in the running binary.
336type Func struct {
337	opaque struct{} // unexported field to disallow conversions
338}
339
340func (f *Func) raw() *_func {
341	return (*_func)(unsafe.Pointer(f))
342}
343
344func (f *Func) funcInfo() funcInfo {
345	return f.raw().funcInfo()
346}
347
348func (f *_func) funcInfo() funcInfo {
349	// Find the module containing fn. fn is located in the pclntable.
350	// The unsafe.Pointer to uintptr conversions and arithmetic
351	// are safe because we are working with module addresses.
352	ptr := uintptr(unsafe.Pointer(f))
353	var mod *moduledata
354	for datap := &firstmoduledata; datap != nil; datap = datap.next {
355		if len(datap.pclntable) == 0 {
356			continue
357		}
358		base := uintptr(unsafe.Pointer(&datap.pclntable[0]))
359		if base <= ptr && ptr < base+uintptr(len(datap.pclntable)) {
360			mod = datap
361			break
362		}
363	}
364	return funcInfo{f, mod}
365}
366
367// pcHeader holds data used by the pclntab lookups.
368type pcHeader struct {
369	magic          uint32  // 0xFFFFFFF1
370	pad1, pad2     uint8   // 0,0
371	minLC          uint8   // min instruction size
372	ptrSize        uint8   // size of a ptr in bytes
373	nfunc          int     // number of functions in the module
374	nfiles         uint    // number of entries in the file tab
375	textStart      uintptr // base for function entry PC offsets in this module, equal to moduledata.text
376	funcnameOffset uintptr // offset to the funcnametab variable from pcHeader
377	cuOffset       uintptr // offset to the cutab variable from pcHeader
378	filetabOffset  uintptr // offset to the filetab variable from pcHeader
379	pctabOffset    uintptr // offset to the pctab variable from pcHeader
380	pclnOffset     uintptr // offset to the pclntab variable from pcHeader
381}
382
383// moduledata records information about the layout of the executable
384// image. It is written by the linker. Any changes here must be
385// matched changes to the code in cmd/link/internal/ld/symtab.go:symtab.
386// moduledata is stored in statically allocated non-pointer memory;
387// none of the pointers here are visible to the garbage collector.
388type moduledata struct {
389	sys.NotInHeap // Only in static data
390
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	covctrs, ecovctrs     uintptr
407	end, gcdata, gcbss    uintptr
408	types, etypes         uintptr
409	rodata                uintptr
410	gofunc                uintptr // go.func.*
411
412	textsectmap []textsect
413	typelinks   []int32 // offsets from types
414	itablinks   []*itab
415
416	ptab []ptabEntry
417
418	pluginpath string
419	pkghashes  []modulehash
420
421	// This slice records the initializing tasks that need to be
422	// done to start up the program. It is built by the linker.
423	inittasks []*initTask
424
425	modulename   string
426	modulehashes []modulehash
427
428	hasmain uint8 // 1 if module contains the main function, 0 otherwise
429	bad     bool  // module failed to load and should be ignored
430
431	gcdatamask, gcbssmask bitvector
432
433	typemap map[typeOff]*_type // offset to *_rtype in previous module
434
435	next *moduledata
436}
437
438// A modulehash is used to compare the ABI of a new module or a
439// package in a new module with the loaded program.
440//
441// For each shared library a module links against, the linker creates an entry in the
442// moduledata.modulehashes slice containing the name of the module, the abi hash seen
443// at link time and a pointer to the runtime abi hash. These are checked in
444// moduledataverify1 below.
445//
446// For each loaded plugin, the pkghashes slice has a modulehash of the
447// newly loaded package that can be used to check the plugin's version of
448// a package against any previously loaded version of the package.
449// This is done in plugin.lastmoduleinit.
450type modulehash struct {
451	modulename   string
452	linktimehash string
453	runtimehash  *string
454}
455
456// pinnedTypemaps are the map[typeOff]*_type from the moduledata objects.
457//
458// These typemap objects are allocated at run time on the heap, but the
459// only direct reference to them is in the moduledata, created by the
460// linker and marked SNOPTRDATA so it is ignored by the GC.
461//
462// To make sure the map isn't collected, we keep a second reference here.
463var pinnedTypemaps []map[typeOff]*_type
464
465var firstmoduledata moduledata // linker symbol
466
467// lastmoduledatap should be an internal detail,
468// but widely used packages access it using linkname.
469// Notable members of the hall of shame include:
470//   - github.com/cloudwego/frugal
471//
472// Do not remove or change the type signature.
473// See go.dev/issue/67401.
474//
475//go:linkname lastmoduledatap
476var lastmoduledatap *moduledata // linker symbol
477
478var modulesSlice *[]*moduledata // see activeModules
479
480// activeModules returns a slice of active modules.
481//
482// A module is active once its gcdatamask and gcbssmask have been
483// assembled and it is usable by the GC.
484//
485// This is nosplit/nowritebarrier because it is called by the
486// cgo pointer checking code.
487//
488//go:nosplit
489//go:nowritebarrier
490func activeModules() []*moduledata {
491	p := (*[]*moduledata)(atomic.Loadp(unsafe.Pointer(&modulesSlice)))
492	if p == nil {
493		return nil
494	}
495	return *p
496}
497
498// modulesinit creates the active modules slice out of all loaded modules.
499//
500// When a module is first loaded by the dynamic linker, an .init_array
501// function (written by cmd/link) is invoked to call addmoduledata,
502// appending to the module to the linked list that starts with
503// firstmoduledata.
504//
505// There are two times this can happen in the lifecycle of a Go
506// program. First, if compiled with -linkshared, a number of modules
507// built with -buildmode=shared can be loaded at program initialization.
508// Second, a Go program can load a module while running that was built
509// with -buildmode=plugin.
510//
511// After loading, this function is called which initializes the
512// moduledata so it is usable by the GC and creates a new activeModules
513// list.
514//
515// Only one goroutine may call modulesinit at a time.
516func modulesinit() {
517	modules := new([]*moduledata)
518	for md := &firstmoduledata; md != nil; md = md.next {
519		if md.bad {
520			continue
521		}
522		*modules = append(*modules, md)
523		if md.gcdatamask == (bitvector{}) {
524			scanDataSize := md.edata - md.data
525			md.gcdatamask = progToPointerMask((*byte)(unsafe.Pointer(md.gcdata)), scanDataSize)
526			scanBSSSize := md.ebss - md.bss
527			md.gcbssmask = progToPointerMask((*byte)(unsafe.Pointer(md.gcbss)), scanBSSSize)
528			gcController.addGlobals(int64(scanDataSize + scanBSSSize))
529		}
530	}
531
532	// Modules appear in the moduledata linked list in the order they are
533	// loaded by the dynamic loader, with one exception: the
534	// firstmoduledata itself the module that contains the runtime. This
535	// is not always the first module (when using -buildmode=shared, it
536	// is typically libstd.so, the second module). The order matters for
537	// typelinksinit, so we swap the first module with whatever module
538	// contains the main function.
539	//
540	// See Issue #18729.
541	for i, md := range *modules {
542		if md.hasmain != 0 {
543			(*modules)[0] = md
544			(*modules)[i] = &firstmoduledata
545			break
546		}
547	}
548
549	atomicstorep(unsafe.Pointer(&modulesSlice), unsafe.Pointer(modules))
550}
551
552type functab struct {
553	entryoff uint32 // relative to runtime.text
554	funcoff  uint32
555}
556
557// Mapping information for secondary text sections
558
559type textsect struct {
560	vaddr    uintptr // prelinked section vaddr
561	end      uintptr // vaddr + section length
562	baseaddr uintptr // relocated section address
563}
564
565// findfuncbucket is an array of these structures.
566// Each bucket represents 4096 bytes of the text segment.
567// Each subbucket represents 256 bytes of the text segment.
568// To find a function given a pc, locate the bucket and subbucket for
569// that pc. Add together the idx and subbucket value to obtain a
570// function index. Then scan the functab array starting at that
571// index to find the target function.
572// This table uses 20 bytes for every 4096 bytes of code, or ~0.5% overhead.
573type findfuncbucket struct {
574	idx        uint32
575	subbuckets [16]byte
576}
577
578func moduledataverify() {
579	for datap := &firstmoduledata; datap != nil; datap = datap.next {
580		moduledataverify1(datap)
581	}
582}
583
584const debugPcln = false
585
586// moduledataverify1 should be an internal detail,
587// but widely used packages access it using linkname.
588// Notable members of the hall of shame include:
589//   - github.com/cloudwego/frugal
590//
591// Do not remove or change the type signature.
592// See go.dev/issue/67401.
593//
594//go:linkname moduledataverify1
595func moduledataverify1(datap *moduledata) {
596	// Check that the pclntab's format is valid.
597	hdr := datap.pcHeader
598	if hdr.magic != 0xfffffff1 || hdr.pad1 != 0 || hdr.pad2 != 0 ||
599		hdr.minLC != sys.PCQuantum || hdr.ptrSize != goarch.PtrSize || hdr.textStart != datap.text {
600		println("runtime: pcHeader: magic=", hex(hdr.magic), "pad1=", hdr.pad1, "pad2=", hdr.pad2,
601			"minLC=", hdr.minLC, "ptrSize=", hdr.ptrSize, "pcHeader.textStart=", hex(hdr.textStart),
602			"text=", hex(datap.text), "pluginpath=", datap.pluginpath)
603		throw("invalid function symbol table")
604	}
605
606	// ftab is lookup table for function by program counter.
607	nftab := len(datap.ftab) - 1
608	for i := 0; i < nftab; i++ {
609		// NOTE: ftab[nftab].entry is legal; it is the address beyond the final function.
610		if datap.ftab[i].entryoff > datap.ftab[i+1].entryoff {
611			f1 := funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[i].funcoff])), datap}
612			f2 := funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[i+1].funcoff])), datap}
613			f2name := "end"
614			if i+1 < nftab {
615				f2name = funcname(f2)
616			}
617			println("function symbol table not sorted by PC offset:", hex(datap.ftab[i].entryoff), funcname(f1), ">", hex(datap.ftab[i+1].entryoff), f2name, ", plugin:", datap.pluginpath)
618			for j := 0; j <= i; j++ {
619				println("\t", hex(datap.ftab[j].entryoff), funcname(funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[j].funcoff])), datap}))
620			}
621			if GOOS == "aix" && isarchive {
622				println("-Wl,-bnoobjreorder is mandatory on aix/ppc64 with c-archive")
623			}
624			throw("invalid runtime symbol table")
625		}
626	}
627
628	min := datap.textAddr(datap.ftab[0].entryoff)
629	max := datap.textAddr(datap.ftab[nftab].entryoff)
630	if datap.minpc != min || datap.maxpc != max {
631		println("minpc=", hex(datap.minpc), "min=", hex(min), "maxpc=", hex(datap.maxpc), "max=", hex(max))
632		throw("minpc or maxpc invalid")
633	}
634
635	for _, modulehash := range datap.modulehashes {
636		if modulehash.linktimehash != *modulehash.runtimehash {
637			println("abi mismatch detected between", datap.modulename, "and", modulehash.modulename)
638			throw("abi mismatch")
639		}
640	}
641}
642
643// textAddr returns md.text + off, with special handling for multiple text sections.
644// off is a (virtual) offset computed at internal linking time,
645// before the external linker adjusts the sections' base addresses.
646//
647// The text, or instruction stream is generated as one large buffer.
648// The off (offset) for a function is its offset within this buffer.
649// If the total text size gets too large, there can be issues on platforms like ppc64
650// if the target of calls are too far for the call instruction.
651// To resolve the large text issue, the text is split into multiple text sections
652// to allow the linker to generate long calls when necessary.
653// When this happens, the vaddr for each text section is set to its offset within the text.
654// Each function's offset is compared against the section vaddrs and ends to determine the containing section.
655// Then the section relative offset is added to the section's
656// relocated baseaddr to compute the function address.
657//
658// It is nosplit because it is part of the findfunc implementation.
659//
660//go:nosplit
661func (md *moduledata) textAddr(off32 uint32) uintptr {
662	off := uintptr(off32)
663	res := md.text + off
664	if len(md.textsectmap) > 1 {
665		for i, sect := range md.textsectmap {
666			// For the last section, include the end address (etext), as it is included in the functab.
667			if off >= sect.vaddr && off < sect.end || (i == len(md.textsectmap)-1 && off == sect.end) {
668				res = sect.baseaddr + off - sect.vaddr
669				break
670			}
671		}
672		if res > md.etext && GOARCH != "wasm" { // on wasm, functions do not live in the same address space as the linear memory
673			println("runtime: textAddr", hex(res), "out of range", hex(md.text), "-", hex(md.etext))
674			throw("runtime: text offset out of range")
675		}
676	}
677	return res
678}
679
680// textOff is the opposite of textAddr. It converts a PC to a (virtual) offset
681// to md.text, and returns if the PC is in any Go text section.
682//
683// It is nosplit because it is part of the findfunc implementation.
684//
685//go:nosplit
686func (md *moduledata) textOff(pc uintptr) (uint32, bool) {
687	res := uint32(pc - md.text)
688	if len(md.textsectmap) > 1 {
689		for i, sect := range md.textsectmap {
690			if sect.baseaddr > pc {
691				// pc is not in any section.
692				return 0, false
693			}
694			end := sect.baseaddr + (sect.end - sect.vaddr)
695			// For the last section, include the end address (etext), as it is included in the functab.
696			if i == len(md.textsectmap)-1 {
697				end++
698			}
699			if pc < end {
700				res = uint32(pc - sect.baseaddr + sect.vaddr)
701				break
702			}
703		}
704	}
705	return res, true
706}
707
708// funcName returns the string at nameOff in the function name table.
709func (md *moduledata) funcName(nameOff int32) string {
710	if nameOff == 0 {
711		return ""
712	}
713	return gostringnocopy(&md.funcnametab[nameOff])
714}
715
716// FuncForPC returns a *[Func] describing the function that contains the
717// given program counter address, or else nil.
718//
719// If pc represents multiple functions because of inlining, it returns
720// the *Func describing the innermost function, but with an entry of
721// the outermost function.
722//
723// For completely unclear reasons, even though they can import runtime,
724// some widely used packages access this using linkname.
725// Notable members of the hall of shame include:
726//   - gitee.com/quant1x/gox
727//
728// Do not remove or change the type signature.
729// See go.dev/issue/67401.
730//
731//go:linkname FuncForPC
732func FuncForPC(pc uintptr) *Func {
733	f := findfunc(pc)
734	if !f.valid() {
735		return nil
736	}
737	// This must interpret PC non-strictly so bad PCs (those between functions) don't crash the runtime.
738	// We just report the preceding function in that situation. See issue 29735.
739	// TODO: Perhaps we should report no function at all in that case.
740	// The runtime currently doesn't have function end info, alas.
741	u, uf := newInlineUnwinder(f, pc)
742	if !u.isInlined(uf) {
743		return f._Func()
744	}
745	sf := u.srcFunc(uf)
746	file, line := u.fileLine(uf)
747	fi := &funcinl{
748		ones:      ^uint32(0),
749		entry:     f.entry(), // entry of the real (the outermost) function.
750		name:      sf.name(),
751		file:      file,
752		line:      int32(line),
753		startLine: sf.startLine,
754	}
755	return (*Func)(unsafe.Pointer(fi))
756}
757
758// Name returns the name of the function.
759func (f *Func) Name() string {
760	if f == nil {
761		return ""
762	}
763	fn := f.raw()
764	if fn.isInlined() { // inlined version
765		fi := (*funcinl)(unsafe.Pointer(fn))
766		return funcNameForPrint(fi.name)
767	}
768	return funcNameForPrint(funcname(f.funcInfo()))
769}
770
771// Entry returns the entry address of the function.
772func (f *Func) Entry() uintptr {
773	fn := f.raw()
774	if fn.isInlined() { // inlined version
775		fi := (*funcinl)(unsafe.Pointer(fn))
776		return fi.entry
777	}
778	return fn.funcInfo().entry()
779}
780
781// FileLine returns the file name and line number of the
782// source code corresponding to the program counter pc.
783// The result will not be accurate if pc is not a program
784// counter within f.
785func (f *Func) FileLine(pc uintptr) (file string, line int) {
786	fn := f.raw()
787	if fn.isInlined() { // inlined version
788		fi := (*funcinl)(unsafe.Pointer(fn))
789		return fi.file, int(fi.line)
790	}
791	// Pass strict=false here, because anyone can call this function,
792	// and they might just be wrong about targetpc belonging to f.
793	file, line32 := funcline1(f.funcInfo(), pc, false)
794	return file, int(line32)
795}
796
797// startLine returns the starting line number of the function. i.e., the line
798// number of the func keyword.
799func (f *Func) startLine() int32 {
800	fn := f.raw()
801	if fn.isInlined() { // inlined version
802		fi := (*funcinl)(unsafe.Pointer(fn))
803		return fi.startLine
804	}
805	return fn.funcInfo().startLine
806}
807
808// findmoduledatap looks up the moduledata for a PC.
809//
810// It is nosplit because it's part of the isgoexception
811// implementation.
812//
813//go:nosplit
814func findmoduledatap(pc uintptr) *moduledata {
815	for datap := &firstmoduledata; datap != nil; datap = datap.next {
816		if datap.minpc <= pc && pc < datap.maxpc {
817			return datap
818		}
819	}
820	return nil
821}
822
823type funcInfo struct {
824	*_func
825	datap *moduledata
826}
827
828func (f funcInfo) valid() bool {
829	return f._func != nil
830}
831
832func (f funcInfo) _Func() *Func {
833	return (*Func)(unsafe.Pointer(f._func))
834}
835
836// isInlined reports whether f should be re-interpreted as a *funcinl.
837func (f *_func) isInlined() bool {
838	return f.entryOff == ^uint32(0) // see comment for funcinl.ones
839}
840
841// entry returns the entry PC for f.
842//
843// entry should be an internal detail,
844// but widely used packages access it using linkname.
845// Notable members of the hall of shame include:
846//   - github.com/phuslu/log
847//
848// Do not remove or change the type signature.
849// See go.dev/issue/67401.
850func (f funcInfo) entry() uintptr {
851	return f.datap.textAddr(f.entryOff)
852}
853
854//go:linkname badFuncInfoEntry runtime.funcInfo.entry
855func badFuncInfoEntry(funcInfo) uintptr
856
857// findfunc looks up function metadata for a PC.
858//
859// It is nosplit because it's part of the isgoexception
860// implementation.
861//
862// findfunc should be an internal detail,
863// but widely used packages access it using linkname.
864// Notable members of the hall of shame include:
865//   - github.com/cloudwego/frugal
866//   - github.com/phuslu/log
867//
868// Do not remove or change the type signature.
869// See go.dev/issue/67401.
870//
871//go:nosplit
872//go:linkname findfunc
873func findfunc(pc uintptr) funcInfo {
874	datap := findmoduledatap(pc)
875	if datap == nil {
876		return funcInfo{}
877	}
878	const nsub = uintptr(len(findfuncbucket{}.subbuckets))
879
880	pcOff, ok := datap.textOff(pc)
881	if !ok {
882		return funcInfo{}
883	}
884
885	x := uintptr(pcOff) + datap.text - datap.minpc // TODO: are datap.text and datap.minpc always equal?
886	b := x / abi.FuncTabBucketSize
887	i := x % abi.FuncTabBucketSize / (abi.FuncTabBucketSize / nsub)
888
889	ffb := (*findfuncbucket)(add(unsafe.Pointer(datap.findfunctab), b*unsafe.Sizeof(findfuncbucket{})))
890	idx := ffb.idx + uint32(ffb.subbuckets[i])
891
892	// Find the ftab entry.
893	for datap.ftab[idx+1].entryoff <= pcOff {
894		idx++
895	}
896
897	funcoff := datap.ftab[idx].funcoff
898	return funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[funcoff])), datap}
899}
900
901// A srcFunc represents a logical function in the source code. This may
902// correspond to an actual symbol in the binary text, or it may correspond to a
903// source function that has been inlined.
904type srcFunc struct {
905	datap     *moduledata
906	nameOff   int32
907	startLine int32
908	funcID    abi.FuncID
909}
910
911func (f funcInfo) srcFunc() srcFunc {
912	if !f.valid() {
913		return srcFunc{}
914	}
915	return srcFunc{f.datap, f.nameOff, f.startLine, f.funcID}
916}
917
918// name should be an internal detail,
919// but widely used packages access it using linkname.
920// Notable members of the hall of shame include:
921//   - github.com/phuslu/log
922//
923// Do not remove or change the type signature.
924// See go.dev/issue/67401.
925func (s srcFunc) name() string {
926	if s.datap == nil {
927		return ""
928	}
929	return s.datap.funcName(s.nameOff)
930}
931
932//go:linkname badSrcFuncName runtime.srcFunc.name
933func badSrcFuncName(srcFunc) string
934
935type pcvalueCache struct {
936	entries [2][8]pcvalueCacheEnt
937	inUse   int
938}
939
940type pcvalueCacheEnt struct {
941	// targetpc and off together are the key of this cache entry.
942	targetpc uintptr
943	off      uint32
944
945	val   int32   // The value of this entry.
946	valPC uintptr // The PC at which val starts
947}
948
949// pcvalueCacheKey returns the outermost index in a pcvalueCache to use for targetpc.
950// It must be very cheap to calculate.
951// For now, align to goarch.PtrSize and reduce mod the number of entries.
952// In practice, this appears to be fairly randomly and evenly distributed.
953func pcvalueCacheKey(targetpc uintptr) uintptr {
954	return (targetpc / goarch.PtrSize) % uintptr(len(pcvalueCache{}.entries))
955}
956
957// Returns the PCData value, and the PC where this value starts.
958func pcvalue(f funcInfo, off uint32, targetpc uintptr, strict bool) (int32, uintptr) {
959	// If true, when we get a cache hit, still look up the data and make sure it
960	// matches the cached contents.
961	const debugCheckCache = false
962
963	if off == 0 {
964		return -1, 0
965	}
966
967	// Check the cache. This speeds up walks of deep stacks, which
968	// tend to have the same recursive functions over and over,
969	// or repetitive stacks between goroutines.
970	var checkVal int32
971	var checkPC uintptr
972	ck := pcvalueCacheKey(targetpc)
973	{
974		mp := acquirem()
975		cache := &mp.pcvalueCache
976		// The cache can be used by the signal handler on this M. Avoid
977		// re-entrant use of the cache. The signal handler can also write inUse,
978		// but will always restore its value, so we can use a regular increment
979		// even if we get signaled in the middle of it.
980		cache.inUse++
981		if cache.inUse == 1 {
982			for i := range cache.entries[ck] {
983				// We check off first because we're more
984				// likely to have multiple entries with
985				// different offsets for the same targetpc
986				// than the other way around, so we'll usually
987				// fail in the first clause.
988				ent := &cache.entries[ck][i]
989				if ent.off == off && ent.targetpc == targetpc {
990					val, pc := ent.val, ent.valPC
991					if debugCheckCache {
992						checkVal, checkPC = ent.val, ent.valPC
993						break
994					} else {
995						cache.inUse--
996						releasem(mp)
997						return val, pc
998					}
999				}
1000			}
1001		} else if debugCheckCache && (cache.inUse < 1 || cache.inUse > 2) {
1002			// Catch accounting errors or deeply reentrant use. In principle
1003			// "inUse" should never exceed 2.
1004			throw("cache.inUse out of range")
1005		}
1006		cache.inUse--
1007		releasem(mp)
1008	}
1009
1010	if !f.valid() {
1011		if strict && panicking.Load() == 0 {
1012			println("runtime: no module data for", hex(f.entry()))
1013			throw("no module data")
1014		}
1015		return -1, 0
1016	}
1017	datap := f.datap
1018	p := datap.pctab[off:]
1019	pc := f.entry()
1020	prevpc := pc
1021	val := int32(-1)
1022	for {
1023		var ok bool
1024		p, ok = step(p, &pc, &val, pc == f.entry())
1025		if !ok {
1026			break
1027		}
1028		if targetpc < pc {
1029			// Replace a random entry in the cache. Random
1030			// replacement prevents a performance cliff if
1031			// a recursive stack's cycle is slightly
1032			// larger than the cache.
1033			// Put the new element at the beginning,
1034			// since it is the most likely to be newly used.
1035			if debugCheckCache && checkPC != 0 {
1036				if checkVal != val || checkPC != prevpc {
1037					print("runtime: table value ", val, "@", prevpc, " != cache value ", checkVal, "@", checkPC, " at PC ", targetpc, " off ", off, "\n")
1038					throw("bad pcvalue cache")
1039				}
1040			} else {
1041				mp := acquirem()
1042				cache := &mp.pcvalueCache
1043				cache.inUse++
1044				if cache.inUse == 1 {
1045					e := &cache.entries[ck]
1046					ci := cheaprandn(uint32(len(cache.entries[ck])))
1047					e[ci] = e[0]
1048					e[0] = pcvalueCacheEnt{
1049						targetpc: targetpc,
1050						off:      off,
1051						val:      val,
1052						valPC:    prevpc,
1053					}
1054				}
1055				cache.inUse--
1056				releasem(mp)
1057			}
1058
1059			return val, prevpc
1060		}
1061		prevpc = pc
1062	}
1063
1064	// If there was a table, it should have covered all program counters.
1065	// If not, something is wrong.
1066	if panicking.Load() != 0 || !strict {
1067		return -1, 0
1068	}
1069
1070	print("runtime: invalid pc-encoded table f=", funcname(f), " pc=", hex(pc), " targetpc=", hex(targetpc), " tab=", p, "\n")
1071
1072	p = datap.pctab[off:]
1073	pc = f.entry()
1074	val = -1
1075	for {
1076		var ok bool
1077		p, ok = step(p, &pc, &val, pc == f.entry())
1078		if !ok {
1079			break
1080		}
1081		print("\tvalue=", val, " until pc=", hex(pc), "\n")
1082	}
1083
1084	throw("invalid runtime symbol table")
1085	return -1, 0
1086}
1087
1088func funcname(f funcInfo) string {
1089	if !f.valid() {
1090		return ""
1091	}
1092	return f.datap.funcName(f.nameOff)
1093}
1094
1095func funcpkgpath(f funcInfo) string {
1096	name := funcNameForPrint(funcname(f))
1097	i := len(name) - 1
1098	for ; i > 0; i-- {
1099		if name[i] == '/' {
1100			break
1101		}
1102	}
1103	for ; i < len(name); i++ {
1104		if name[i] == '.' {
1105			break
1106		}
1107	}
1108	return name[:i]
1109}
1110
1111func funcfile(f funcInfo, fileno int32) string {
1112	datap := f.datap
1113	if !f.valid() {
1114		return "?"
1115	}
1116	// Make sure the cu index and file offset are valid
1117	if fileoff := datap.cutab[f.cuOffset+uint32(fileno)]; fileoff != ^uint32(0) {
1118		return gostringnocopy(&datap.filetab[fileoff])
1119	}
1120	// pcln section is corrupt.
1121	return "?"
1122}
1123
1124// funcline1 should be an internal detail,
1125// but widely used packages access it using linkname.
1126// Notable members of the hall of shame include:
1127//   - github.com/phuslu/log
1128//
1129// Do not remove or change the type signature.
1130// See go.dev/issue/67401.
1131//
1132//go:linkname funcline1
1133func funcline1(f funcInfo, targetpc uintptr, strict bool) (file string, line int32) {
1134	datap := f.datap
1135	if !f.valid() {
1136		return "?", 0
1137	}
1138	fileno, _ := pcvalue(f, f.pcfile, targetpc, strict)
1139	line, _ = pcvalue(f, f.pcln, targetpc, strict)
1140	if fileno == -1 || line == -1 || int(fileno) >= len(datap.filetab) {
1141		// print("looking for ", hex(targetpc), " in ", funcname(f), " got file=", fileno, " line=", lineno, "\n")
1142		return "?", 0
1143	}
1144	file = funcfile(f, fileno)
1145	return
1146}
1147
1148func funcline(f funcInfo, targetpc uintptr) (file string, line int32) {
1149	return funcline1(f, targetpc, true)
1150}
1151
1152func funcspdelta(f funcInfo, targetpc uintptr) int32 {
1153	x, _ := pcvalue(f, f.pcsp, targetpc, true)
1154	if debugPcln && x&(goarch.PtrSize-1) != 0 {
1155		print("invalid spdelta ", funcname(f), " ", hex(f.entry()), " ", hex(targetpc), " ", hex(f.pcsp), " ", x, "\n")
1156		throw("bad spdelta")
1157	}
1158	return x
1159}
1160
1161// funcMaxSPDelta returns the maximum spdelta at any point in f.
1162func funcMaxSPDelta(f funcInfo) int32 {
1163	datap := f.datap
1164	p := datap.pctab[f.pcsp:]
1165	pc := f.entry()
1166	val := int32(-1)
1167	most := int32(0)
1168	for {
1169		var ok bool
1170		p, ok = step(p, &pc, &val, pc == f.entry())
1171		if !ok {
1172			return most
1173		}
1174		most = max(most, val)
1175	}
1176}
1177
1178func pcdatastart(f funcInfo, table uint32) uint32 {
1179	return *(*uint32)(add(unsafe.Pointer(&f.nfuncdata), unsafe.Sizeof(f.nfuncdata)+uintptr(table)*4))
1180}
1181
1182func pcdatavalue(f funcInfo, table uint32, targetpc uintptr) int32 {
1183	if table >= f.npcdata {
1184		return -1
1185	}
1186	r, _ := pcvalue(f, pcdatastart(f, table), targetpc, true)
1187	return r
1188}
1189
1190func pcdatavalue1(f funcInfo, table uint32, targetpc uintptr, strict bool) int32 {
1191	if table >= f.npcdata {
1192		return -1
1193	}
1194	r, _ := pcvalue(f, pcdatastart(f, table), targetpc, strict)
1195	return r
1196}
1197
1198// Like pcdatavalue, but also return the start PC of this PCData value.
1199//
1200// pcdatavalue2 should be an internal detail,
1201// but widely used packages access it using linkname.
1202// Notable members of the hall of shame include:
1203//   - github.com/cloudwego/frugal
1204//
1205// Do not remove or change the type signature.
1206// See go.dev/issue/67401.
1207//
1208//go:linkname pcdatavalue2
1209func pcdatavalue2(f funcInfo, table uint32, targetpc uintptr) (int32, uintptr) {
1210	if table >= f.npcdata {
1211		return -1, 0
1212	}
1213	return pcvalue(f, pcdatastart(f, table), targetpc, true)
1214}
1215
1216// funcdata returns a pointer to the ith funcdata for f.
1217// funcdata should be kept in sync with cmd/link:writeFuncs.
1218func funcdata(f funcInfo, i uint8) unsafe.Pointer {
1219	if i < 0 || i >= f.nfuncdata {
1220		return nil
1221	}
1222	base := f.datap.gofunc // load gofunc address early so that we calculate during cache misses
1223	p := uintptr(unsafe.Pointer(&f.nfuncdata)) + unsafe.Sizeof(f.nfuncdata) + uintptr(f.npcdata)*4 + uintptr(i)*4
1224	off := *(*uint32)(unsafe.Pointer(p))
1225	// Return off == ^uint32(0) ? 0 : f.datap.gofunc + uintptr(off), but without branches.
1226	// The compiler calculates mask on most architectures using conditional assignment.
1227	var mask uintptr
1228	if off == ^uint32(0) {
1229		mask = 1
1230	}
1231	mask--
1232	raw := base + uintptr(off)
1233	return unsafe.Pointer(raw & mask)
1234}
1235
1236// step advances to the next pc, value pair in the encoded table.
1237//
1238// step should be an internal detail,
1239// but widely used packages access it using linkname.
1240// Notable members of the hall of shame include:
1241//   - github.com/cloudwego/frugal
1242//
1243// Do not remove or change the type signature.
1244// See go.dev/issue/67401.
1245//
1246//go:linkname step
1247func step(p []byte, pc *uintptr, val *int32, first bool) (newp []byte, ok bool) {
1248	// For both uvdelta and pcdelta, the common case (~70%)
1249	// is that they are a single byte. If so, avoid calling readvarint.
1250	uvdelta := uint32(p[0])
1251	if uvdelta == 0 && !first {
1252		return nil, false
1253	}
1254	n := uint32(1)
1255	if uvdelta&0x80 != 0 {
1256		n, uvdelta = readvarint(p)
1257	}
1258	*val += int32(-(uvdelta & 1) ^ (uvdelta >> 1))
1259	p = p[n:]
1260
1261	pcdelta := uint32(p[0])
1262	n = 1
1263	if pcdelta&0x80 != 0 {
1264		n, pcdelta = readvarint(p)
1265	}
1266	p = p[n:]
1267	*pc += uintptr(pcdelta * sys.PCQuantum)
1268	return p, true
1269}
1270
1271// readvarint reads a varint from p.
1272func readvarint(p []byte) (read uint32, val uint32) {
1273	var v, shift, n uint32
1274	for {
1275		b := p[n]
1276		n++
1277		v |= uint32(b&0x7F) << (shift & 31)
1278		if b&0x80 == 0 {
1279			break
1280		}
1281		shift += 7
1282	}
1283	return n, v
1284}
1285
1286type stackmap struct {
1287	n        int32   // number of bitmaps
1288	nbit     int32   // number of bits in each bitmap
1289	bytedata [1]byte // bitmaps, each starting on a byte boundary
1290}
1291
1292// stackmapdata should be an internal detail,
1293// but widely used packages access it using linkname.
1294// Notable members of the hall of shame include:
1295//   - github.com/cloudwego/frugal
1296//
1297// Do not remove or change the type signature.
1298// See go.dev/issue/67401.
1299//
1300//go:linkname stackmapdata
1301//go:nowritebarrier
1302func stackmapdata(stkmap *stackmap, n int32) bitvector {
1303	// Check this invariant only when stackDebug is on at all.
1304	// The invariant is already checked by many of stackmapdata's callers,
1305	// and disabling it by default allows stackmapdata to be inlined.
1306	if stackDebug > 0 && (n < 0 || n >= stkmap.n) {
1307		throw("stackmapdata: index out of range")
1308	}
1309	return bitvector{stkmap.nbit, addb(&stkmap.bytedata[0], uintptr(n*((stkmap.nbit+7)>>3)))}
1310}
1311