// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Cgo call and callback support.
//
// To call into the C function f from Go, the cgo-generated code calls
// runtime.cgocall(_cgo_Cfunc_f, frame), where _cgo_Cfunc_f is a
// gcc-compiled function written by cgo.
//
// runtime.cgocall (below) calls entersyscall so as not to block
// other goroutines or the garbage collector, and then calls
// runtime.asmcgocall(_cgo_Cfunc_f, frame).
//
// runtime.asmcgocall (in asm_$GOARCH.s) switches to the m->g0 stack
// (assumed to be an operating system-allocated stack, so safe to run
// gcc-compiled code on) and calls _cgo_Cfunc_f(frame).
//
// _cgo_Cfunc_f invokes the actual C function f with arguments
// taken from the frame structure, records the results in the frame,
// and returns to runtime.asmcgocall.
//
// After it regains control, runtime.asmcgocall switches back to the
// original g (m->curg)'s stack and returns to runtime.cgocall.
//
// After it regains control, runtime.cgocall calls exitsyscall, which blocks
// until this m can run Go code without violating the $GOMAXPROCS limit,
// and then unlocks g from m.
//
// The above description skipped over the possibility of the gcc-compiled
// function f calling back into Go. If that happens, we continue down
// the rabbit hole during the execution of f.
//
// To make it possible for gcc-compiled C code to call a Go function p.GoF,
// cgo writes a gcc-compiled function named GoF (not p.GoF, since gcc doesn't
// know about packages).  The gcc-compiled C function f calls GoF.
//
// GoF initializes "frame", a structure containing all of its
// arguments and slots for p.GoF's results. It calls
// crosscall2(_cgoexp_GoF, frame, framesize, ctxt) using the gcc ABI.
//
// crosscall2 (in cgo/asm_$GOARCH.s) is a four-argument adapter from
// the gcc function call ABI to the gc function call ABI. At this
// point we're in the Go runtime, but we're still running on m.g0's
// stack and outside the $GOMAXPROCS limit. crosscall2 calls
// runtime.cgocallback(_cgoexp_GoF, frame, ctxt) using the gc ABI.
// (crosscall2's framesize argument is no longer used, but there's one
// case where SWIG calls crosscall2 directly and expects to pass this
// argument. See _cgo_panic.)
//
// runtime.cgocallback (in asm_$GOARCH.s) switches from m.g0's stack
// to the original g (m.curg)'s stack, on which it calls
// runtime.cgocallbackg(_cgoexp_GoF, frame, ctxt). As part of the
// stack switch, runtime.cgocallback saves the current SP as
// m.g0.sched.sp, so that any use of m.g0's stack during the execution
// of the callback will be done below the existing stack frames.
// Before overwriting m.g0.sched.sp, it pushes the old value on the
// m.g0 stack, so that it can be restored later.
//
// runtime.cgocallbackg (below) is now running on a real goroutine
// stack (not an m.g0 stack).  First it calls runtime.exitsyscall, which will
// block until the $GOMAXPROCS limit allows running this goroutine.
// Once exitsyscall has returned, it is safe to do things like call the memory
// allocator or invoke the Go callback function.  runtime.cgocallbackg
// first defers a function to unwind m.g0.sched.sp, so that if p.GoF
// panics, m.g0.sched.sp will be restored to its old value: the m.g0 stack
// and the m.curg stack will be unwound in lock step.
// Then it calls _cgoexp_GoF(frame).
//
// _cgoexp_GoF, which was generated by cmd/cgo, unpacks the arguments
// from frame, calls p.GoF, writes the results back to frame, and
// returns. Now we start unwinding this whole process.
//
// runtime.cgocallbackg pops but does not execute the deferred
// function to unwind m.g0.sched.sp, calls runtime.entersyscall, and
// returns to runtime.cgocallback.
//
// After it regains control, runtime.cgocallback switches back to
// m.g0's stack (the pointer is still in m.g0.sched.sp), restores the old
// m.g0.sched.sp value from the stack, and returns to crosscall2.
//
// crosscall2 restores the callee-save registers for gcc and returns
// to GoF, which unpacks any result values and returns to f.

package runtime

import (
	"internal/abi"
	"internal/goarch"
	"internal/goexperiment"
	"internal/runtime/sys"
	"unsafe"
)

// Addresses collected in a cgo backtrace when crashing.
// Length must match arg.Max in x_cgo_callers in runtime/cgo/gcc_traceback.c.
type cgoCallers [32]uintptr

// argset matches runtime/cgo/linux_syscall.c:argset_t
type argset struct {
	args   unsafe.Pointer
	retval uintptr
}

// wrapper for syscall package to call cgocall for libc (cgo) calls.
//
//go:linkname syscall_cgocaller syscall.cgocaller
//go:nosplit
//go:uintptrescapes
func syscall_cgocaller(fn unsafe.Pointer, args ...uintptr) uintptr {
	as := argset{args: unsafe.Pointer(&args[0])}
	cgocall(fn, unsafe.Pointer(&as))
	return as.retval
}

var ncgocall uint64 // number of cgo calls in total for dead m

// Call from Go to C.
//
// This must be nosplit because it's used for syscalls on some
// platforms. Syscalls may have untyped arguments on the stack, so
// it's not safe to grow or scan the stack.
//
// cgocall should be an internal detail,
// but widely used packages access it using linkname.
// Notable members of the hall of shame include:
//   - github.com/ebitengine/purego
//
// Do not remove or change the type signature.
// See go.dev/issue/67401.
//
//go:linkname cgocall
//go:nosplit
func cgocall(fn, arg unsafe.Pointer) int32 {
	if !iscgo && GOOS != "solaris" && GOOS != "illumos" && GOOS != "windows" {
		throw("cgocall unavailable")
	}

	if fn == nil {
		throw("cgocall nil")
	}

	if raceenabled {
		racereleasemerge(unsafe.Pointer(&racecgosync))
	}

	mp := getg().m
	mp.ncgocall++

	// Reset traceback.
	mp.cgoCallers[0] = 0

	// Announce we are entering a system call
	// so that the scheduler knows to create another
	// M to run goroutines while we are in the
	// foreign code.
	//
	// The call to asmcgocall is guaranteed not to
	// grow the stack and does not allocate memory,
	// so it is safe to call while "in a system call", outside
	// the $GOMAXPROCS accounting.
	//
	// fn may call back into Go code, in which case we'll exit the
	// "system call", run the Go code (which may grow the stack),
	// and then re-enter the "system call" reusing the PC and SP
	// saved by entersyscall here.
	entersyscall()

	// Tell asynchronous preemption that we're entering external
	// code. We do this after entersyscall because this may block
	// and cause an async preemption to fail, but at this point a
	// sync preemption will succeed (though this is not a matter
	// of correctness).
	osPreemptExtEnter(mp)

	mp.incgo = true
	// We use ncgo as a check during execution tracing for whether there is
	// any C on the call stack, which there will be after this point. If
	// there isn't, we can use frame pointer unwinding to collect call
	// stacks efficiently. This will be the case for the first Go-to-C call
	// on a stack, so it's preferable to update it here, after we emit a
	// trace event in entersyscall above.
	mp.ncgo++

	errno := asmcgocall(fn, arg)

	// Update accounting before exitsyscall because exitsyscall may
	// reschedule us on to a different M.
	mp.incgo = false
	mp.ncgo--

	osPreemptExtExit(mp)

	// After exitsyscall we can be rescheduled on a different M,
	// so we need to restore the original M's winsyscall.
	winsyscall := mp.winsyscall

	exitsyscall()

	getg().m.winsyscall = winsyscall

	// Note that raceacquire must be called only after exitsyscall has
	// wired this M to a P.
	if raceenabled {
		raceacquire(unsafe.Pointer(&racecgosync))
	}

	// From the garbage collector's perspective, time can move
	// backwards in the sequence above. If there's a callback into
	// Go code, GC will see this function at the call to
	// asmcgocall. When the Go call later returns to C, the
	// syscall PC/SP is rolled back and the GC sees this function
	// back at the call to entersyscall. Normally, fn and arg
	// would be live at entersyscall and dead at asmcgocall, so if
	// time moved backwards, GC would see these arguments as dead
	// and then live. Prevent these undead arguments from crashing
	// GC by forcing them to stay live across this time warp.
	KeepAlive(fn)
	KeepAlive(arg)
	KeepAlive(mp)

	return errno
}

// Set or reset the system stack bounds for a callback on sp.
//
// Must be nosplit because it is called by needm prior to fully initializing
// the M.
//
//go:nosplit
func callbackUpdateSystemStack(mp *m, sp uintptr, signal bool) {
	g0 := mp.g0

	if !mp.isextra {
		// We allocated the stack for standard Ms. Don't replace the
		// stack bounds with estimated ones when we already initialized
		// with the exact ones.
		return
	}

	inBound := sp > g0.stack.lo && sp <= g0.stack.hi
	if inBound && mp.g0StackAccurate {
		// This M has called into Go before and has the stack bounds
		// initialized. We have the accurate stack bounds, and the SP
		// is in bounds. We expect it continues to run within the same
		// bounds.
		return
	}

	// We don't have an accurate stack bounds (either it never calls
	// into Go before, or we couldn't get the accurate bounds), or the
	// current SP is not within the previous bounds (the stack may have
	// changed between calls). We need to update the stack bounds.
	//
	// N.B. we need to update the stack bounds even if SP appears to
	// already be in bounds, if our bounds are estimated dummy bounds
	// (below). We may be in a different region within the same actual
	// stack bounds, but our estimates were not accurate. Or the actual
	// stack bounds could have shifted but still have partial overlap with
	// our dummy bounds. If we failed to update in that case, we could find
	// ourselves seemingly called near the bottom of the stack bounds, where
	// we quickly run out of space.

	// Set the stack bounds to match the current stack. If we don't
	// actually know how big the stack is, like we don't know how big any
	// scheduling stack is, but we assume there's at least 32 kB. If we
	// can get a more accurate stack bound from pthread, use that, provided
	// it actually contains SP.
	g0.stack.hi = sp + 1024
	g0.stack.lo = sp - 32*1024
	mp.g0StackAccurate = false
	if !signal && _cgo_getstackbound != nil {
		// Don't adjust if called from the signal handler.
		// We are on the signal stack, not the pthread stack.
		// (We could get the stack bounds from sigaltstack, but
		// we're getting out of the signal handler very soon
		// anyway. Not worth it.)
		var bounds [2]uintptr
		asmcgocall(_cgo_getstackbound, unsafe.Pointer(&bounds))
		// getstackbound is an unsupported no-op on Windows.
		//
		// On Unix systems, if the API to get accurate stack bounds is
		// not available, it returns zeros.
		//
		// Don't use these bounds if they don't contain SP. Perhaps we
		// were called by something not using the standard thread
		// stack.
		if bounds[0] != 0 && sp > bounds[0] && sp <= bounds[1] {
			g0.stack.lo = bounds[0]
			g0.stack.hi = bounds[1]
			mp.g0StackAccurate = true
		}
	}
	g0.stackguard0 = g0.stack.lo + stackGuard
	g0.stackguard1 = g0.stackguard0
}

// Call from C back to Go. fn must point to an ABIInternal Go entry-point.
//
//go:nosplit
func cgocallbackg(fn, frame unsafe.Pointer, ctxt uintptr) {
	gp := getg()
	if gp != gp.m.curg {
		println("runtime: bad g in cgocallback")
		exit(2)
	}

	sp := gp.m.g0.sched.sp // system sp saved by cgocallback.
	oldStack := gp.m.g0.stack
	oldAccurate := gp.m.g0StackAccurate
	callbackUpdateSystemStack(gp.m, sp, false)

	// The call from C is on gp.m's g0 stack, so we must ensure
	// that we stay on that M. We have to do this before calling
	// exitsyscall, since it would otherwise be free to move us to
	// a different M. The call to unlockOSThread is in this function
	// after cgocallbackg1, or in the case of panicking, in unwindm.
	lockOSThread()

	checkm := gp.m

	// Save current syscall parameters, so m.winsyscall can be
	// used again if callback decide to make syscall.
	winsyscall := gp.m.winsyscall

	// entersyscall saves the caller's SP to allow the GC to trace the Go
	// stack. However, since we're returning to an earlier stack frame and
	// need to pair with the entersyscall() call made by cgocall, we must
	// save syscall* and let reentersyscall restore them.
	//
	// Note: savedsp and savedbp MUST be held in locals as an unsafe.Pointer.
	// When we call into Go, the stack is free to be moved. If these locals
	// aren't visible in the stack maps, they won't get updated properly,
	// and will end up being stale when restored by reentersyscall.
	savedsp := unsafe.Pointer(gp.syscallsp)
	savedpc := gp.syscallpc
	savedbp := unsafe.Pointer(gp.syscallbp)
	exitsyscall() // coming out of cgo call
	gp.m.incgo = false
	if gp.m.isextra {
		gp.m.isExtraInC = false
	}

	osPreemptExtExit(gp.m)

	if gp.nocgocallback {
		panic("runtime: function marked with #cgo nocallback called back into Go")
	}

	cgocallbackg1(fn, frame, ctxt)

	// At this point we're about to call unlockOSThread.
	// The following code must not change to a different m.
	// This is enforced by checking incgo in the schedule function.
	gp.m.incgo = true
	unlockOSThread()

	if gp.m.isextra && gp.m.ncgo == 0 {
		// There are no active cgocalls above this frame (ncgo == 0),
		// thus there can't be more Go frames above this frame.
		gp.m.isExtraInC = true
	}

	if gp.m != checkm {
		throw("m changed unexpectedly in cgocallbackg")
	}

	osPreemptExtEnter(gp.m)

	// going back to cgo call
	reentersyscall(savedpc, uintptr(savedsp), uintptr(savedbp))

	gp.m.winsyscall = winsyscall

	// Restore the old g0 stack bounds
	gp.m.g0.stack = oldStack
	gp.m.g0.stackguard0 = oldStack.lo + stackGuard
	gp.m.g0.stackguard1 = gp.m.g0.stackguard0
	gp.m.g0StackAccurate = oldAccurate
}

func cgocallbackg1(fn, frame unsafe.Pointer, ctxt uintptr) {
	gp := getg()

	if gp.m.needextram || extraMWaiters.Load() > 0 {
		gp.m.needextram = false
		systemstack(newextram)
	}

	if ctxt != 0 {
		s := append(gp.cgoCtxt, ctxt)

		// Now we need to set gp.cgoCtxt = s, but we could get
		// a SIGPROF signal while manipulating the slice, and
		// the SIGPROF handler could pick up gp.cgoCtxt while
		// tracing up the stack.  We need to ensure that the
		// handler always sees a valid slice, so set the
		// values in an order such that it always does.
		p := (*slice)(unsafe.Pointer(&gp.cgoCtxt))
		atomicstorep(unsafe.Pointer(&p.array), unsafe.Pointer(&s[0]))
		p.cap = cap(s)
		p.len = len(s)

		defer func(gp *g) {
			// Decrease the length of the slice by one, safely.
			p := (*slice)(unsafe.Pointer(&gp.cgoCtxt))
			p.len--
		}(gp)
	}

	if gp.m.ncgo == 0 {
		// The C call to Go came from a thread not currently running
		// any Go. In the case of -buildmode=c-archive or c-shared,
		// this call may be coming in before package initialization
		// is complete. Wait until it is.
		<-main_init_done
	}

	// Check whether the profiler needs to be turned on or off; this route to
	// run Go code does not use runtime.execute, so bypasses the check there.
	hz := sched.profilehz
	if gp.m.profilehz != hz {
		setThreadCPUProfiler(hz)
	}

	// Add entry to defer stack in case of panic.
	restore := true
	defer unwindm(&restore)

	var ditAlreadySet bool
	if debug.dataindependenttiming == 1 && gp.m.isextra {
		// We only need to enable DIT for threads that were created by C, as it
		// should already by enabled on threads that were created by Go.
		ditAlreadySet = sys.EnableDIT()
	}

	if raceenabled {
		raceacquire(unsafe.Pointer(&racecgosync))
	}

	// Invoke callback. This function is generated by cmd/cgo and
	// will unpack the argument frame and call the Go function.
	var cb func(frame unsafe.Pointer)
	cbFV := funcval{uintptr(fn)}
	*(*unsafe.Pointer)(unsafe.Pointer(&cb)) = noescape(unsafe.Pointer(&cbFV))
	cb(frame)

	if raceenabled {
		racereleasemerge(unsafe.Pointer(&racecgosync))
	}

	if debug.dataindependenttiming == 1 && !ditAlreadySet {
		// Only unset DIT if it wasn't already enabled when cgocallback was called.
		sys.DisableDIT()
	}

	// Do not unwind m->g0->sched.sp.
	// Our caller, cgocallback, will do that.
	restore = false
}

func unwindm(restore *bool) {
	if *restore {
		// Restore sp saved by cgocallback during
		// unwind of g's stack (see comment at top of file).
		mp := acquirem()
		sched := &mp.g0.sched
		sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + alignUp(sys.MinFrameSize, sys.StackAlign)))

		// Do the accounting that cgocall will not have a chance to do
		// during an unwind.
		//
		// In the case where a Go call originates from C, ncgo is 0
		// and there is no matching cgocall to end.
		if mp.ncgo > 0 {
			mp.incgo = false
			mp.ncgo--
			osPreemptExtExit(mp)
		}

		// Undo the call to lockOSThread in cgocallbackg, only on the
		// panicking path. In normal return case cgocallbackg will call
		// unlockOSThread, ensuring no preemption point after the unlock.
		// Here we don't need to worry about preemption, because we're
		// panicking out of the callback and unwinding the g0 stack,
		// instead of reentering cgo (which requires the same thread).
		unlockOSThread()

		releasem(mp)
	}
}

// called from assembly.
func badcgocallback() {
	throw("misaligned stack in cgocallback")
}

// called from (incomplete) assembly.
func cgounimpl() {
	throw("cgo not implemented")
}

var racecgosync uint64 // represents possible synchronization in C code

// Pointer checking for cgo code.

// We want to detect all cases where a program that does not use
// unsafe makes a cgo call passing a Go pointer to memory that
// contains an unpinned Go pointer. Here a Go pointer is defined as a
// pointer to memory allocated by the Go runtime. Programs that use
// unsafe can evade this restriction easily, so we don't try to catch
// them. The cgo program will rewrite all possibly bad pointer
// arguments to call cgoCheckPointer, where we can catch cases of a Go
// pointer pointing to an unpinned Go pointer.

// Complicating matters, taking the address of a slice or array
// element permits the C program to access all elements of the slice
// or array. In that case we will see a pointer to a single element,
// but we need to check the entire data structure.

// The cgoCheckPointer call takes additional arguments indicating that
// it was called on an address expression. An additional argument of
// true means that it only needs to check a single element. An
// additional argument of a slice or array means that it needs to
// check the entire slice/array, but nothing else. Otherwise, the
// pointer could be anything, and we check the entire heap object,
// which is conservative but safe.

// When and if we implement a moving garbage collector,
// cgoCheckPointer will pin the pointer for the duration of the cgo
// call.  (This is necessary but not sufficient; the cgo program will
// also have to change to pin Go pointers that cannot point to Go
// pointers.)

// cgoCheckPointer checks if the argument contains a Go pointer that
// points to an unpinned Go pointer, and panics if it does.
func cgoCheckPointer(ptr any, arg any) {
	if !goexperiment.CgoCheck2 && debug.cgocheck == 0 {
		return
	}

	ep := efaceOf(&ptr)
	t := ep._type

	top := true
	if arg != nil && (t.Kind() == abi.Pointer || t.Kind() == abi.UnsafePointer) {
		p := ep.data
		if !t.IsDirectIface() {
			p = *(*unsafe.Pointer)(p)
		}
		if p == nil || !cgoIsGoPointer(p) {
			return
		}
		aep := efaceOf(&arg)
		switch aep._type.Kind() {
		case abi.Bool:
			if t.Kind() == abi.UnsafePointer {
				// We don't know the type of the element.
				break
			}
			pt := (*ptrtype)(unsafe.Pointer(t))
			cgoCheckArg(pt.Elem, p, true, false, cgoCheckPointerFail)
			return
		case abi.Slice:
			// Check the slice rather than the pointer.
			ep = aep
			t = ep._type
		case abi.Array:
			// Check the array rather than the pointer.
			// Pass top as false since we have a pointer
			// to the array.
			ep = aep
			t = ep._type
			top = false
		case abi.Pointer:
			// The Go code is indexing into a pointer to an array,
			// and we have been passed the pointer-to-array.
			// Check the array rather than the pointer.
			pt := (*abi.PtrType)(unsafe.Pointer(aep._type))
			t = pt.Elem
			if t.Kind() != abi.Array {
				throw("can't happen")
			}
			ep = aep
			top = false
		default:
			throw("can't happen")
		}
	}

	cgoCheckArg(t, ep.data, !t.IsDirectIface(), top, cgoCheckPointerFail)
}

const cgoCheckPointerFail = "cgo argument has Go pointer to unpinned Go pointer"
const cgoResultFail = "cgo result is unpinned Go pointer or points to unpinned Go pointer"

// cgoCheckArg is the real work of cgoCheckPointer. The argument p
// is either a pointer to the value (of type t), or the value itself,
// depending on indir. The top parameter is whether we are at the top
// level, where Go pointers are allowed. Go pointers to pinned objects are
// allowed as long as they don't reference other unpinned pointers.
func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) {
	if !t.Pointers() || p == nil {
		// If the type has no pointers there is nothing to do.
		return
	}

	switch t.Kind() {
	default:
		throw("can't happen")
	case abi.Array:
		at := (*arraytype)(unsafe.Pointer(t))
		if !indir {
			if at.Len != 1 {
				throw("can't happen")
			}
			cgoCheckArg(at.Elem, p, !at.Elem.IsDirectIface(), top, msg)
			return
		}
		for i := uintptr(0); i < at.Len; i++ {
			cgoCheckArg(at.Elem, p, true, top, msg)
			p = add(p, at.Elem.Size_)
		}
	case abi.Chan, abi.Map:
		// These types contain internal pointers that will
		// always be allocated in the Go heap. It's never OK
		// to pass them to C.
		panic(errorString(msg))
	case abi.Func:
		if indir {
			p = *(*unsafe.Pointer)(p)
		}
		if !cgoIsGoPointer(p) {
			return
		}
		panic(errorString(msg))
	case abi.Interface:
		it := *(**_type)(p)
		if it == nil {
			return
		}
		// A type known at compile time is OK since it's
		// constant. A type not known at compile time will be
		// in the heap and will not be OK.
		if inheap(uintptr(unsafe.Pointer(it))) {
			panic(errorString(msg))
		}
		p = *(*unsafe.Pointer)(add(p, goarch.PtrSize))
		if !cgoIsGoPointer(p) {
			return
		}
		if !top && !isPinned(p) {
			panic(errorString(msg))
		}
		cgoCheckArg(it, p, !it.IsDirectIface(), false, msg)
	case abi.Slice:
		st := (*slicetype)(unsafe.Pointer(t))
		s := (*slice)(p)
		p = s.array
		if p == nil || !cgoIsGoPointer(p) {
			return
		}
		if !top && !isPinned(p) {
			panic(errorString(msg))
		}
		if !st.Elem.Pointers() {
			return
		}
		for i := 0; i < s.cap; i++ {
			cgoCheckArg(st.Elem, p, true, false, msg)
			p = add(p, st.Elem.Size_)
		}
	case abi.String:
		ss := (*stringStruct)(p)
		if !cgoIsGoPointer(ss.str) {
			return
		}
		if !top && !isPinned(ss.str) {
			panic(errorString(msg))
		}
	case abi.Struct:
		st := (*structtype)(unsafe.Pointer(t))
		if !indir {
			if len(st.Fields) != 1 {
				throw("can't happen")
			}
			cgoCheckArg(st.Fields[0].Typ, p, !st.Fields[0].Typ.IsDirectIface(), top, msg)
			return
		}
		for _, f := range st.Fields {
			if !f.Typ.Pointers() {
				continue
			}
			cgoCheckArg(f.Typ, add(p, f.Offset), true, top, msg)
		}
	case abi.Pointer, abi.UnsafePointer:
		if indir {
			p = *(*unsafe.Pointer)(p)
			if p == nil {
				return
			}
		}

		if !cgoIsGoPointer(p) {
			return
		}
		if !top && !isPinned(p) {
			panic(errorString(msg))
		}

		cgoCheckUnknownPointer(p, msg)
	}
}

// cgoCheckUnknownPointer is called for an arbitrary pointer into Go
// memory. It checks whether that Go memory contains any other
// pointer into unpinned Go memory. If it does, we panic.
// The return values are unused but useful to see in panic tracebacks.
func cgoCheckUnknownPointer(p unsafe.Pointer, msg string) (base, i uintptr) {
	if inheap(uintptr(p)) {
		b, span, _ := findObject(uintptr(p), 0, 0)
		base = b
		if base == 0 {
			return
		}
		tp := span.typePointersOfUnchecked(base)
		for {
			var addr uintptr
			if tp, addr = tp.next(base + span.elemsize); addr == 0 {
				break
			}
			pp := *(*unsafe.Pointer)(unsafe.Pointer(addr))
			if cgoIsGoPointer(pp) && !isPinned(pp) {
				panic(errorString(msg))
			}
		}
		return
	}

	for _, datap := range activeModules() {
		if cgoInRange(p, datap.data, datap.edata) || cgoInRange(p, datap.bss, datap.ebss) {
			// We have no way to know the size of the object.
			// We have to assume that it might contain a pointer.
			panic(errorString(msg))
		}
		// In the text or noptr sections, we know that the
		// pointer does not point to a Go pointer.
	}

	return
}

// cgoIsGoPointer reports whether the pointer is a Go pointer--a
// pointer to Go memory. We only care about Go memory that might
// contain pointers.
//
//go:nosplit
//go:nowritebarrierrec
func cgoIsGoPointer(p unsafe.Pointer) bool {
	if p == nil {
		return false
	}

	if inHeapOrStack(uintptr(p)) {
		return true
	}

	for _, datap := range activeModules() {
		if cgoInRange(p, datap.data, datap.edata) || cgoInRange(p, datap.bss, datap.ebss) {
			return true
		}
	}

	return false
}

// cgoInRange reports whether p is between start and end.
//
//go:nosplit
//go:nowritebarrierrec
func cgoInRange(p unsafe.Pointer, start, end uintptr) bool {
	return start <= uintptr(p) && uintptr(p) < end
}

// cgoCheckResult is called to check the result parameter of an
// exported Go function. It panics if the result is or contains any
// other pointer into unpinned Go memory.
func cgoCheckResult(val any) {
	if !goexperiment.CgoCheck2 && debug.cgocheck == 0 {
		return
	}

	ep := efaceOf(&val)
	t := ep._type
	cgoCheckArg(t, ep.data, !t.IsDirectIface(), false, cgoResultFail)
}
